]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
We shoud always return the Accept-Ranges header, with a GET or HEAD request, even...
authorWido den Hollander <wido@widodh.nl>
Fri, 23 Jul 2010 13:39:49 +0000 (15:39 +0200)
committerYehuda Sadeh <yehuda@hq.newdream.net>
Tue, 27 Jul 2010 17:28:46 +0000 (10:28 -0700)
This is to let the client know we accept requests for partial content.

On HEAD requests we should also return the Content-Length header.

And we should also return the Last-Modified header with GET and HEAD requests, this way browsers and proxy's can cache content.

src/rgw/rgw_access.h
src/rgw/rgw_fs.cc
src/rgw/rgw_fs.h
src/rgw/rgw_op.cc
src/rgw/rgw_op.h
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h
src/rgw/rgw_rest.cc
src/rgw/rgw_rest.h
src/rgw/rgw_user.cc

index ad8a895affadd907586be75261380106fc6fab00..01a15f17665269ffcfbc454b15deca75ce74f33f 100644 (file)
@@ -122,6 +122,7 @@ public:
             map<string, bufferlist> *attrs,
             const time_t *mod_ptr,
             const time_t *unmod_ptr,
+            time_t *lastmod,
             const char *if_match,
             const char *if_nomatch,
             size_t *total_size,
index c71d657652c9008e9941f7c953b8526870cc2c27..b4c5de5bbf4acdaeebdd653cf13d6a4c8af45090 100644 (file)
@@ -274,9 +274,10 @@ int RGWFS::copy_obj(std::string& id, std::string& dest_bucket, std::string& dest
   void *handle;
   off_t ofs = 0, end = -1;
   size_t total_len;
+  time_t lastmod;
 
   map<string, bufferlist> attrset;
-  ret = prepare_get_obj(src_bucket, src_obj, 0, &end, &attrset, mod_ptr, unmod_ptr,
+  ret = prepare_get_obj(src_bucket, src_obj, 0, &end, &attrset, mod_ptr, unmod_ptr, &lastmod,
                         if_match, if_nomatch, &total_len, &handle, err);
   if (ret < 0)
     return ret;
@@ -421,6 +422,7 @@ int RGWFS::prepare_get_obj(std::string& bucket, std::string& obj,
             map<string, bufferlist> *attrs,
             const time_t *mod_ptr,
             const time_t *unmod_ptr,
+            time_t *lastmod,
             const char *if_match,
             const char *if_nomatch,
             size_t *total_size,
index d35ab13e2be943af3ab82b3487d761051eb83f42..5010bb21ed9d869911dfac0dae4766f460f29ffd 100644 (file)
@@ -45,6 +45,7 @@ public:
            map<std::string, bufferlist> *attrs,
             const time_t *mod_ptr,
             const time_t *unmod_ptr,
+            time_t *lastmod,
             const char *if_match,
             const char *if_nomatch,
             size_t *size,
index 54a2c94fb4bd6c2769cdb9bc12a043999fab3a42..c8e4fbe42ded3c89e96fc6ef933f3e79a411acfe 100644 (file)
@@ -142,7 +142,7 @@ void RGWGetObj::execute()
   init_common();
 
   ret = rgwstore->prepare_get_obj(s->bucket_str, s->object_str, ofs, &end, &attrs, mod_ptr,
-                                  unmod_ptr, if_match, if_nomatch, &total_len, &handle, &err);
+                                  unmod_ptr, &lastmod, if_match, if_nomatch, &total_len, &handle, &err);
   if (ret < 0)
     goto done;
 
index 054d6eaf3faafaf42c06a698b58cf0485b4425be..2b74569908b7c17daefec49dd4d95dcddd23f4a8 100644 (file)
@@ -54,6 +54,7 @@ protected:
   size_t total_len;
   off_t end;
   time_t mod_time;
+  time_t lastmod;
   time_t unmod_time;
   time_t *mod_ptr;
   time_t *unmod_ptr;
index 257e3118d4b8c098e5d80ba7de7f2bf3870354ae..cda70ab0c2d991a4240ad89015b55fa21fe27f63 100644 (file)
@@ -344,6 +344,7 @@ int RGWRados::copy_obj(std::string& id, std::string& dest_bucket, std::string& d
   char *data;
   off_t ofs = 0, end = -1;
   size_t total_len;
+  time_t lastmod;
   map<string, bufferlist>::iterator iter;
 
   cerr << "copy " << src_bucket << ":" << src_obj << " => " << dest_bucket << ":" << dest_obj << std::endl;
@@ -352,7 +353,7 @@ int RGWRados::copy_obj(std::string& id, std::string& dest_bucket, std::string& d
 
   map<string, bufferlist> attrset;
   ret = prepare_get_obj(src_bucket, src_obj, ofs, &end, &attrset,
-                mod_ptr, unmod_ptr, if_match, if_nomatch, &total_len, &handle, err);
+                mod_ptr, unmod_ptr, &lastmod, if_match, if_nomatch, &total_len, &handle, err);
 
   if (ret < 0)
     return ret;
@@ -511,6 +512,7 @@ int RGWRados::prepare_get_obj(std::string& bucket, std::string& oid,
             map<string, bufferlist> *attrs,
             const time_t *mod_ptr,
             const time_t *unmod_ptr,
+            time_t *lastmod,
             const char *if_match,
             const char *if_nomatch,
             size_t *total_size,
@@ -595,6 +597,7 @@ int RGWRados::prepare_get_obj(std::string& bucket, std::string& oid,
     *end = size - 1;
 
   *total_size = (ofs <= *end ? *end + 1 - ofs : 0);
+  *lastmod = mtime;
 
   return 0;
 
index f8bd34b42c72e5894f05e39101962de59dddc71d..22d331ca4eb7e8c03ccb23150c0a5b63e02d2472 100644 (file)
@@ -73,6 +73,7 @@ public:
             map<string, bufferlist> *attrs,
             const time_t *mod_ptr,
             const time_t *unmod_ptr,
+            time_t *lastmod,
             const char *if_match,
             const char *if_nomatch,
             size_t *total_size,
index 78e782a447b2c3b5f27a80c82c16aa66c3807a20..8bf59f781dbae275ec5c35865be25e8dab4c970b 100644 (file)
@@ -85,6 +85,7 @@ void close_section(struct req_state *s, const char *name)
 static void dump_content_length(struct req_state *s, int len)
 {
   CGI_PRINTF(s->fcgx->out, "Content-Length: %d\n", len);
+  CGI_PRINTF(s->fcgx->out, "Accept-Ranges: %s\n", "bytes");
 }
 
 static void dump_etag(struct req_state *s, const char *etag)
@@ -92,6 +93,19 @@ static void dump_etag(struct req_state *s, const char *etag)
   CGI_PRINTF(s->fcgx->out,"ETag: \"%s\"\n", etag);
 }
 
+static void dump_last_modified(struct req_state *s, time_t t) {
+
+  char timestr[TIME_BUF_SIZE];
+  struct tm *tmp = localtime(&t);
+  if (tmp == NULL)
+    return;
+
+  if (strftime(timestr, sizeof(timestr), "%a, %d %b %Y %H:%M:%S %Z", tmp) == 0)
+    return;
+
+  CGI_PRINTF(s->fcgx->out, "Last-Modified: %s\n", timestr);
+}
+
 void dump_value(struct req_state *s, const char *name, const char *fmt, ...)
 {
 #define LARGE_SIZE 8192
@@ -116,7 +130,6 @@ static void dump_entry(struct req_state *s, const char *val)
 
 void dump_time(struct req_state *s, const char *name, time_t *t)
 {
-#define TIME_BUF_SIZE 128
   char buf[TIME_BUF_SIZE];
   struct tm *tmp = localtime(t);
   if (tmp == NULL)
@@ -187,7 +200,6 @@ void abort_early(struct req_state *s, int err)
 
 void dump_range(struct req_state *s, off_t ofs, off_t end)
 {
-    CGI_PRINTF(s->fcgx->out,"Accept-Ranges: bytes\n", "");
     CGI_PRINTF(s->fcgx->out,"Content-Range: bytes %d-%d/%d\n", (int)ofs, (int)end, (int)end + 1);
 }
 
@@ -209,11 +221,12 @@ int RGWGetObj_REST::send_response(void *handle)
   if (sent_header)
     goto send_data;
 
-  if (get_data && !ret) {
-    if (range_str)
-      dump_range(s, ofs, end);
-    dump_content_length(s, total_len);
-  }
+  if (range_str)
+    dump_range(s, ofs, end);
+
+  dump_content_length(s, total_len);
+  dump_last_modified(s, lastmod);
+
   if (!ret) {
     map<string, bufferlist>::iterator iter = attrs.find(RGW_ATTR_ETAG);
     if (iter != attrs.end()) {
@@ -223,6 +236,7 @@ int RGWGetObj_REST::send_response(void *handle)
         dump_etag(s, etag);
       }
     }
+
     for (iter = attrs.begin(); iter != attrs.end(); ++iter) {
        const char *name = iter->first.c_str();
        if (strncmp(name, RGW_ATTR_META_PREFIX, sizeof(RGW_ATTR_META_PREFIX)-1) == 0) {
index dda33d4db0996524c7a7e22b92ad96da66404e96..65495d343bef2ab49ab05d7bdfe2346467db3c30 100644 (file)
@@ -1,5 +1,6 @@
 #ifndef CEPH_RGW_REST_H
 #define CEPH_RGW_REST_H
+#define TIME_BUF_SIZE 128
 
 #include "rgw_op.h"
 
index 2a1c4404b729f415d8f23db7c5dc86efe518f1a4..9749ebd43cfd42eda62111f24f75b8c15e4c3d84 100644 (file)
@@ -28,9 +28,10 @@ int rgw_get_user_info(string user_id, RGWUserInfo& info)
   void *handle = NULL;
   off_t ofs = 0, end = -1;
   size_t total_len;
+  time_t lastmod;
   bufferlist::iterator iter;
 
-  ret = rgwstore->prepare_get_obj(ui_bucket, user_id, ofs, &end, NULL, NULL, NULL, NULL, NULL, &total_len, &handle, &err);
+  ret = rgwstore->prepare_get_obj(ui_bucket, user_id, ofs, &end, NULL, NULL, NULL, &lastmod, NULL, NULL, &total_len, &handle, &err);
   if (ret < 0)
     return ret;
   do {
@@ -121,7 +122,7 @@ int rgw_get_uid_by_email(string& email, string& user_id)
   size_t total_len;
 
   ret = rgwstore->prepare_get_obj(ui_email_bucket, email, ofs, &end, NULL, NULL,
-                                  NULL, NULL, NULL, &total_len, &handle, &err);
+                                  NULL, NULL, NULL, NULL, &total_len, &handle, &err);
   if (ret < 0)
     return ret;
   do {