Commits

Boris Nagaev committed daaac9f

EtagStore can be used for Last-Modified header as well

  • Participants
  • Parent commits 4de6f4a

Comments (0)

Files changed (5)

examples/swfstore.cpp.in

     wApp->log("info") << "Gathered: type=" << type << ", value=" << value;
 } // gather
 
-EtagStoreResource etag_resource;
+EtagStoreResource etag_resource("wcetag", "ETag", "If-None-Match");
+EtagStoreResource last_modified_resource("wclastm", "Last-Modified",
+        "If-Modified-Since");
 
 class SWFStoreApp : public WApplication {
 public:
         SWFStore* swf = new SWFStore(root());
         LocalStore* localstore = new LocalStore(root());
         EtagStore* etagstore = new EtagStore(&etag_resource, root());
+        EtagStore* laststore = new EtagStore(&last_modified_resource, root());
         WPushButton* clear_storage = new WPushButton("Clear", root());
         WPushButton* one = new WPushButton("Set k=1", root());
         WPushButton* two = new WPushButton("Set k=2", root());
         gather->set_swfstore(swf);
         gather->set_localstore(localstore);
         gather->add_store(etagstore, Gather::ETAG);
+        gather->add_store(laststore, Gather::LAST_MODIFIED);
     }
 };
 
         addResource(&swfstore_, "/swfstore.swf");
         addResource(&storage_whitelist_, "/storage-whitelist.xml");
         addResource(&etag_resource, "/etag-test.gif");
+        addResource(&last_modified_resource, "/last-modified.gif");
         addEntryPoint(Wt::Application, createSWFStoreApp);
     }
 

src/EtagStore.cpp

 namespace Wc {
 
 EtagStoreResource::EtagStoreResource(const std::string& cookie_name,
+                                     const std::string& send_header,
+                                     const std::string& receive_header,
                                      WObject* parent):
-    WResource(parent), cookie_name_(cookie_name) {
+    WResource(parent), cookie_name_(cookie_name),
+    send_header_(send_header), receive_header_(receive_header) {
     setDispositionType(WResource::Inline);
 }
 
     int cookie_length = (cookie_end == -1) ? -1 : (cookie_end - cookie_begin);
     std::string cookie_value = cookies.substr(cookie_begin, cookie_length);
     //
-    std::string etag_value = request.headerValue("If-None-Match");
+    std::string etag_value = request.headerValue(receive_header());
     boost::mutex::scoped_lock lock(cookie_to_etag_mutex_);
     Map::iterator it = cookie_to_etag_.find(cookie_value);
     if (it == cookie_to_etag_.end()) {
     }
     etag.from_client = etag_value;
     if (!etag.to_client.empty()) {
-        response.addHeader("ETag", etag.to_client);
+        response.addHeader(send_header(), etag.to_client);
         etag.to_client.clear();
     } else {
         etag.handler(etag.from_client);
     }
     if (!etag.from_client.empty()) {
-        response.addHeader("ETag", etag.from_client);
+        response.addHeader(send_header(), etag.from_client);
     }
 }
 

src/EtagStore.hpp

 */
 class EtagStoreResource : public WResource {
 public:
-    /** Constructor */
+    /** Constructor.
+    \param cookie_name Name of cookie used to distinguish clients
+    \param send_header Header send to client
+        (ETag or Last-Modified)
+    \param receive_header Header received from client
+        (If-None-Match or If-Modified-Since)
+    \param parent Parent Wt object
+    */
     EtagStoreResource(const std::string& cookie_name = "wces",
+                      const std::string& send_header = "ETag",
+                      const std::string& receive_header = "If-None-Match",
                       WObject* parent = 0);
 
     /** Handles a request */
         return cookie_name_;
     }
 
+    /** Header send to client */
+    const std::string& send_header() const {
+        return send_header_;
+    }
+
+    /** Header received from client */
+    const std::string& receive_header() const {
+        return receive_header_;
+    }
+
 private:
     struct Etag {
         typedef boost::function<void(const boost::any&)> OneAnyFunc;
     Map cookie_to_etag_;
     boost::mutex cookie_to_etag_mutex_;
     std::string cookie_name_;
+    std::string send_header_;
+    std::string receive_header_;
 
     void handle_etag(const Http::Request& request, Http::Response& response);
 
 // FIXME random numbers?? need statictical data
 int Gather::significance(DataType type) {
     if (type == COOKIE || type == SWF || type == LOCAL_STORAGE ||
-            type == ETAG) {
+            type == ETAG || type == LAST_MODIFIED) {
         return 10000;
     } else if (type == IP) {
         return 45;
         return "local_storage";
     } else if (type == ETAG) {
         return "etag";
+    } else if (type == LAST_MODIFIED) {
+        return "last_modified";
     } else if (type == IP) {
         return "ip";
     } else if (type == PLUGINS) {
         SWF = 20, /**< SWF value (significant virtuals evidence) */
         LOCAL_STORAGE = 25, /**< localStorage (significant virtuals evidence) */
         ETAG = 26, /**< ETag cookie (significant virtuals evidence) */
+        LAST_MODIFIED = 27, /**< Last-Modified (significant evidence) */
         IP = 30, /**< IP address (medium virtuals evidence) */
         PLUGINS = 40, /**< Plugins sorted list (medium virtuals evidence) */
         MIME_TYPES = 50, /**< Mime types sorted list (medium evidence) */