[sheepdog] [PATCH v3 2/3] sheep/http: implement HEAD for object opeation
Liu Yuan
namei.unix at gmail.com
Thu Dec 26 07:38:54 CET 2013
Signed-off-by: Liu Yuan <namei.unix at gmail.com>
---
sheep/http/http.c | 2 +-
sheep/http/http.h | 2 ++
sheep/http/kv.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++-----
sheep/http/swift.c | 16 +++++++++++++++-
4 files changed, 64 insertions(+), 7 deletions(-)
diff --git a/sheep/http/http.c b/sheep/http/http.c
index 0081707..4a2ae35 100644
--- a/sheep/http/http.c
+++ b/sheep/http/http.c
@@ -193,7 +193,7 @@ void http_response_header(struct http_request *req, enum http_status status)
req->status = status;
http_request_writef(req, "Status: %s\r\n", strstatus(status));
- if (req->opcode == HTTP_GET && req->data_length > 0)
+ if (req->opcode == HTTP_GET || req->opcode == HTTP_HEAD)
http_request_writef(req, "Content-Length: %lu\r\n",
req->data_length);
http_request_writes(req, "Content-type: text/plain;\r\n\r\n");
diff --git a/sheep/http/http.h b/sheep/http/http.h
index 40ff307..52f5b36 100644
--- a/sheep/http/http.h
+++ b/sheep/http/http.h
@@ -139,6 +139,8 @@ int kv_create_object(struct http_request *req, const char *account,
const char *bucket, const char *object);
int kv_read_object(struct http_request *req, const char *account,
const char *bucket, const char *object);
+int kv_read_object_meta(struct http_request *req, const char *account,
+ const char *bucket, const char *object);
int kv_delete_object(const char *account, const char *bucket, const char *);
int kv_iterate_object(const char *account, const char *bucket,
void (*cb)(const char *object, void *opaque),
diff --git a/sheep/http/kv.c b/sheep/http/kv.c
index a58310f..d04230d 100644
--- a/sheep/http/kv.c
+++ b/sheep/http/kv.c
@@ -35,7 +35,6 @@ struct kv_onode {
/* a hash value for etag */
uint8_t sha1[round_up(SHA1_DIGEST_SIZE, 8)];
uint64_t size;
- uint64_t ctime;
uint64_t mtime;
uint32_t data_vid;
uint32_t nr_extent;
@@ -690,10 +689,19 @@ out:
return ret;
}
+static uint64_t get_seconds(void)
+{
+ struct timeval tv;
+ uint64_t seconds;
+
+ gettimeofday(&tv, NULL);
+ seconds = (uint64_t)tv.tv_sec;
+ return seconds;
+}
+
static int onode_populate_data(struct kv_onode *onode, struct http_request *req)
{
ssize_t size;
- struct timeval tv;
int ret;
if (req->data_length <= KV_ONODE_INLINE_SIZE) {
@@ -711,9 +719,7 @@ static int onode_populate_data(struct kv_onode *onode, struct http_request *req)
goto out;
}
- gettimeofday(&tv, NULL);
- onode->ctime = (uint64_t) tv.tv_sec << 32 | tv.tv_usec * 1000;
- onode->mtime = onode->ctime;
+ onode->mtime = get_seconds();
onode->size = req->data_length;
out:
return ret;
@@ -1093,3 +1099,38 @@ int kv_iterate_object(const char *account, const char *bucket,
return ret;
}
+
+static char *http_time(uint64_t time)
+{
+ static __thread char time_str[128];
+
+ strftime(time_str, sizeof(time_str), "%a, %d %b %Y %H:%M:%S GMT",
+ gmtime((time_t *)&time));
+ return time_str;
+}
+
+int kv_read_object_meta(struct http_request *req, const char *account,
+ const char *bucket, const char *name)
+{
+ struct kv_onode *onode = NULL;
+ char vdi_name[SD_MAX_VDI_LEN];
+ uint32_t bucket_vid;
+ int ret;
+
+ snprintf(vdi_name, SD_MAX_VDI_LEN, "%s/%s", account, bucket);
+ ret = sd_lookup_vdi(vdi_name, &bucket_vid);
+ if (ret != SD_RES_SUCCESS)
+ return ret;
+
+ onode = xzalloc(sizeof(*onode));
+ ret = onode_lookup(onode, bucket_vid, name);
+ if (ret != SD_RES_SUCCESS)
+ goto out;
+
+ req->data_length = onode->size;
+ http_request_writef(req, "Last-Modified: %s\n",
+ http_time(onode->mtime));
+out:
+ free(onode);
+ return ret;
+}
diff --git a/sheep/http/swift.c b/sheep/http/swift.c
index c3985be..a2b2e89 100644
--- a/sheep/http/swift.c
+++ b/sheep/http/swift.c
@@ -171,7 +171,21 @@ static void swift_delete_container(struct http_request *req,
static void swift_head_object(struct http_request *req, const char *account,
const char *container, const char *object)
{
- http_response_header(req, NOT_IMPLEMENTED);
+ int ret;
+
+ ret = kv_read_object_meta(req, account, container, object);
+ switch (ret) {
+ case SD_RES_SUCCESS:
+ http_response_header(req, OK);
+ break;
+ case SD_RES_NO_VDI:
+ case SD_RES_NO_OBJ:
+ http_response_header(req, NOT_FOUND);
+ break;
+ default:
+ http_response_header(req, INTERNAL_SERVER_ERROR);
+ break;
+ }
}
static void swift_get_object(struct http_request *req, const char *account,
--
1.8.1.2
More information about the sheepdog
mailing list