This commit is contained in:
41
README.md
41
README.md
@@ -120,6 +120,47 @@ curl -X PUT \
|
|||||||
http://localhost:8080/upload
|
http://localhost:8080/upload
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### PUT /update
|
||||||
|
|
||||||
|
Update the metadata for an existing object. The request must be authenticated with a valid write token. The request body must be JSON and include both a `hash` (the object's hash) and a `metadata` object.
|
||||||
|
|
||||||
|
**Request:**
|
||||||
|
- Method: PUT
|
||||||
|
- URL: /update
|
||||||
|
- Headers:
|
||||||
|
- Authorization: Bearer <WRITE_TOKEN>
|
||||||
|
- Content-Type: application/json
|
||||||
|
- Body:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"hash": "<object_hash>",
|
||||||
|
"metadata": {
|
||||||
|
"key1": "value1",
|
||||||
|
"key2": "value2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
- 200 OK on success:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"result": "success",
|
||||||
|
"hash": "<object_hash>"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- 400 Bad Request if missing fields or invalid JSON
|
||||||
|
- 404 Not Found if the object does not exist
|
||||||
|
- 401/403 if authentication fails
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```sh
|
||||||
|
curl -X PUT http://localhost:8080/update \
|
||||||
|
-H "Authorization: Bearer <WRITE_TOKEN>" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"hash": "abc123", "metadata": {"foo": "bar"}}'
|
||||||
|
```
|
||||||
|
|
||||||
### Get a File
|
### Get a File
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
#include "compress.hpp"
|
#include "compress.hpp"
|
||||||
#include "string_utils.hpp" // Include the new utility header
|
#include "string_utils.hpp" // Include the new utility header
|
||||||
#include "put_handler.hpp"
|
#include "put_handler.hpp"
|
||||||
|
#include "update_handler.hpp" // Include the new update handler header
|
||||||
#include "utils.hpp"
|
#include "utils.hpp"
|
||||||
#include "welcome_page.hpp"
|
#include "welcome_page.hpp"
|
||||||
|
|
||||||
@@ -106,6 +107,9 @@ Server::Server(const ServerConfig& config)
|
|||||||
// Initialize the put handler
|
// Initialize the put handler
|
||||||
put_handler_ = std::make_unique<PutHandler>(*this);
|
put_handler_ = std::make_unique<PutHandler>(*this);
|
||||||
|
|
||||||
|
// Initialize the update handler
|
||||||
|
update_handler_ = std::make_unique<UpdateHandler>(*this);
|
||||||
|
|
||||||
// Initialize rate limiter
|
// Initialize rate limiter
|
||||||
auth_rate_limiter_ = std::make_unique<RateLimiter>(
|
auth_rate_limiter_ = std::make_unique<RateLimiter>(
|
||||||
config_.auth_rate_limit,
|
config_.auth_rate_limit,
|
||||||
@@ -183,6 +187,11 @@ void Server::setup_routes() {
|
|||||||
put_handler_->handle_put_object(req, res);
|
put_handler_->handle_put_object(req, res);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Update object metadata (new endpoint)
|
||||||
|
server_.Put("/update", [this](const httplib::Request& req, httplib::Response& res) {
|
||||||
|
update_handler_->handle_update_object(req, res);
|
||||||
|
});
|
||||||
|
|
||||||
// Handle PUT requests to other paths
|
// Handle PUT requests to other paths
|
||||||
server_.Put("/(.*)", [this](const httplib::Request& req, httplib::Response& res) {
|
server_.Put("/(.*)", [this](const httplib::Request& req, httplib::Response& res) {
|
||||||
res.status = 404;
|
res.status = 404;
|
||||||
|
@@ -46,6 +46,7 @@ private:
|
|||||||
httplib::Server server_;
|
httplib::Server server_;
|
||||||
bool running_;
|
bool running_;
|
||||||
std::unique_ptr<PutHandler> put_handler_;
|
std::unique_ptr<PutHandler> put_handler_;
|
||||||
|
std::unique_ptr<UpdateHandler> update_handler_;
|
||||||
std::unique_ptr<RateLimiter> auth_rate_limiter_;
|
std::unique_ptr<RateLimiter> auth_rate_limiter_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
65
src/update_handler.cpp
Normal file
65
src/update_handler.cpp
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
#include "update_handler.hpp"
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace simple_object_storage {
|
||||||
|
|
||||||
|
UpdateHandler::UpdateHandler(Server& server) : server_(server) {}
|
||||||
|
|
||||||
|
void UpdateHandler::handle_update_object(const httplib::Request& req, httplib::Response& res) {
|
||||||
|
std::map<std::string, std::string> params;
|
||||||
|
// Validate authentication and rate limit (no required query params, just auth)
|
||||||
|
if (!server_.validate_write_request(req, res, {}, params)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse JSON body
|
||||||
|
nlohmann::json body;
|
||||||
|
try {
|
||||||
|
body = nlohmann::json::parse(req.body);
|
||||||
|
} catch (const nlohmann::json::parse_error& e) {
|
||||||
|
res.status = 400;
|
||||||
|
nlohmann::json response = {{"result", "error"}, {"error", "Invalid JSON body"}};
|
||||||
|
res.set_content(response.dump(), "application/json");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for required fields
|
||||||
|
if (!body.contains("hash") || !body.contains("metadata")) {
|
||||||
|
res.status = 400;
|
||||||
|
nlohmann::json response = {{"result", "error"}, {"error", "Missing 'hash' or 'metadata' field in request body"}};
|
||||||
|
res.set_content(response.dump(), "application/json");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string hash = body["hash"].get<std::string>();
|
||||||
|
nlohmann::json new_metadata = body["metadata"];
|
||||||
|
|
||||||
|
// Get the object entry
|
||||||
|
dbEntry entry;
|
||||||
|
if (!server_.db_->get(hash, entry)) {
|
||||||
|
res.status = 404;
|
||||||
|
nlohmann::json response = {{"result", "error"}, {"error", "Object not found for hash: " + hash}};
|
||||||
|
res.set_content(response.dump(), "application/json");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare updated entry (keep hash and labeltags, update metadata)
|
||||||
|
dbEntry updated_entry = entry;
|
||||||
|
updated_entry.metadata = new_metadata;
|
||||||
|
// Ensure labeltags and hash are preserved in metadata
|
||||||
|
updated_entry.metadata["labeltags"] = updated_entry.labeltags;
|
||||||
|
updated_entry.metadata["hash"] = updated_entry.hash;
|
||||||
|
|
||||||
|
if (!server_.db_->update_or_insert(updated_entry)) {
|
||||||
|
res.status = 500;
|
||||||
|
nlohmann::json response = {{"result", "error"}, {"error", "Failed to update metadata for hash: " + hash}};
|
||||||
|
res.set_content(response.dump(), "application/json");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nlohmann::json response = {{"result", "success"}, {"hash", hash}};
|
||||||
|
res.set_content(response.dump(), "application/json");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace simple_object_storage
|
16
src/update_handler.hpp
Normal file
16
src/update_handler.hpp
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "server.hpp"
|
||||||
|
#include <memory>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
namespace simple_object_storage {
|
||||||
|
|
||||||
|
class UpdateHandler {
|
||||||
|
public:
|
||||||
|
explicit UpdateHandler(Server& server);
|
||||||
|
void handle_update_object(const httplib::Request& req, httplib::Response& res);
|
||||||
|
private:
|
||||||
|
Server& server_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace simple_object_storage
|
@@ -184,6 +184,15 @@ std::string welcome_page() {
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="endpoint-group">
|
||||||
|
<h3>PUT /update</h3>
|
||||||
|
<p>Update the metadata for an existing object. Requires authentication. Send a JSON body with <code>hash</code> and <code>metadata</code> fields.</p>
|
||||||
|
<pre>{
|
||||||
|
"hash": "<object_hash>",
|
||||||
|
"metadata": { "key": "value" }
|
||||||
|
}</pre>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
Reference in New Issue
Block a user