This commit is contained in:
41
README.md
41
README.md
@@ -120,6 +120,47 @@ curl -X PUT \
|
||||
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
|
||||
|
||||
```
|
||||
|
@@ -14,6 +14,7 @@
|
||||
#include "compress.hpp"
|
||||
#include "string_utils.hpp" // Include the new utility header
|
||||
#include "put_handler.hpp"
|
||||
#include "update_handler.hpp" // Include the new update handler header
|
||||
#include "utils.hpp"
|
||||
#include "welcome_page.hpp"
|
||||
|
||||
@@ -106,6 +107,9 @@ Server::Server(const ServerConfig& config)
|
||||
// Initialize the put handler
|
||||
put_handler_ = std::make_unique<PutHandler>(*this);
|
||||
|
||||
// Initialize the update handler
|
||||
update_handler_ = std::make_unique<UpdateHandler>(*this);
|
||||
|
||||
// Initialize rate limiter
|
||||
auth_rate_limiter_ = std::make_unique<RateLimiter>(
|
||||
config_.auth_rate_limit,
|
||||
@@ -183,6 +187,11 @@ void Server::setup_routes() {
|
||||
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
|
||||
server_.Put("/(.*)", [this](const httplib::Request& req, httplib::Response& res) {
|
||||
res.status = 404;
|
||||
|
@@ -46,6 +46,7 @@ private:
|
||||
httplib::Server server_;
|
||||
bool running_;
|
||||
std::unique_ptr<PutHandler> put_handler_;
|
||||
std::unique_ptr<UpdateHandler> update_handler_;
|
||||
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>
|
||||
</ul>
|
||||
</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>
|
||||
</body>
|
||||
|
Reference in New Issue
Block a user