Browse Source

cache control

David Rose 23 years ago
parent
commit
9e8ba9e7e3

+ 43 - 0
panda/src/downloader/documentSpec.I

@@ -25,6 +25,7 @@
 INLINE DocumentSpec::
 DocumentSpec() {
   _request_mode = RM_any;
+  _cache_control = CC_allow_cache;
   _flags = 0;
 }
 
@@ -38,6 +39,7 @@ DocumentSpec(const string &url) :
   _url(url)
 {
   _request_mode = RM_any;
+  _cache_control = CC_allow_cache;
   _flags = 0;
 }
 
@@ -51,6 +53,7 @@ DocumentSpec(const URLSpec &url) :
   _url(url)
 {
   _request_mode = RM_any;
+  _cache_control = CC_allow_cache;
   _flags = 0;
 }
 
@@ -65,6 +68,7 @@ DocumentSpec(const DocumentSpec &copy) :
   _tag(copy._tag),
   _date(copy._date),
   _request_mode(copy._request_mode),
+  _cache_control(copy._cache_control),
   _flags(copy._flags)
 {
 }
@@ -80,6 +84,7 @@ operator = (const DocumentSpec &copy) {
   _tag = copy._tag;
   _date = copy._date;
   _request_mode = copy._request_mode;
+  _cache_control = copy._cache_control;
   _flags = copy._flags;
 }
 
@@ -290,6 +295,44 @@ get_request_mode() const {
   return _request_mode;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: DocumentSpec::set_cache_control
+//       Access: Published
+//  Description: Specifies what kind of cached value is acceptable for
+//               this document.  Warning: some HTTP proxies may not
+//               respect this setting and may return a cached result
+//               anyway.
+//
+//                 CC_allow_cache: the normal HTTP behavior; the
+//                 server may return a cached value if it believes it
+//                 is valid.
+//
+//                 CC_revalidate: a proxy is forced to contact the
+//                 origin server and verify that is cached value is in
+//                 fact still valid before it returns it.
+//
+//                 CC_no_cache: a proxy must not return its cached
+//                 value at all, but is forced to go all the way back
+//                 to the origin server for the official document.
+//
+//               The default mode is CC_allow_cache.
+////////////////////////////////////////////////////////////////////
+INLINE void DocumentSpec::
+set_cache_control(DocumentSpec::CacheControl cache_control) {
+  _cache_control = cache_control;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DocumentSpec::get_cache_control
+//       Access: Published
+//  Description: Returns the request mode of this DocumentSpec.  See
+//               set_cache_control().
+////////////////////////////////////////////////////////////////////
+INLINE DocumentSpec::CacheControl DocumentSpec::
+get_cache_control() const {
+  return _cache_control;
+}
+
 INLINE istream &
 operator >> (istream &in, DocumentSpec &doc) {
   if (!doc.input(in)) {

+ 10 - 0
panda/src/downloader/documentSpec.h

@@ -70,6 +70,15 @@ PUBLISHED:
   INLINE void set_request_mode(RequestMode request_mode);
   INLINE RequestMode get_request_mode() const;
 
+  enum CacheControl {
+    CC_allow_cache,
+    CC_revalidate,
+    CC_no_cache,
+  };
+
+  INLINE void set_cache_control(CacheControl cache_control);
+  INLINE CacheControl get_cache_control() const;
+
   bool input(istream &in);
   void output(ostream &out) const;
   void write(ostream &out, int indent_level = 0) const;
@@ -79,6 +88,7 @@ private:
   HTTPEntityTag _tag;
   HTTPDate _date;
   RequestMode _request_mode;
+  CacheControl _cache_control;
 
   enum Flags {
     F_has_tag    = 0x0001,

+ 29 - 1
panda/src/downloader/httpChannel.cxx

@@ -813,6 +813,8 @@ run_proxy_reading_header() {
   }
 
   _redirect = get_header_value("Location");
+  // We can take the proxy's word for it that this is the actual URL
+  // for the redirect.
 
   _server_response_has_no_body = 
     (get_status_code() / 100 == 1 ||
@@ -1164,6 +1166,13 @@ run_reading_header() {
   }
   _redirect = get_header_value("Location");
 
+  // The server might have given us just a filename for the redirect.
+  // In that case, it's relative to the same server.
+  if (!_redirect.has_authority()) {
+    _redirect.set_scheme(_document_spec.get_url().get_scheme());
+    _redirect.set_authority(_document_spec.get_url().get_authority());
+  }
+
   _state = S_read_header;
 
   if (_server_response_has_no_body && will_close_connection()) {
@@ -1230,7 +1239,7 @@ run_reading_header() {
           new_url.set_username(_request.get_url().get_username());
         }
         reset_url(_request.get_url(), new_url);
-        _document_spec.set_url(new_url);
+        _request.set_url(new_url);
         make_header();
         make_request_text();
 
@@ -2379,6 +2388,25 @@ make_header() {
     break;
   }
 
+  switch (_request.get_cache_control()) {
+  case DocumentSpec::CC_allow_cache:
+    // Normal, caching behavior.
+    break;
+
+  case DocumentSpec::CC_revalidate:
+    // Request the server to revalidate its cache before returning it.
+    stream
+      << "Cache-Control: max-age=0\r\n";
+    break;
+
+  case DocumentSpec::CC_no_cache:
+    // Request the server to get a fresh copy regardless of its cache.
+    stream
+      << "Cache-Control: no-cache\r\n"
+      << "Pragma: no-cache\r\n";
+    break;
+  }
+
   if (!_body.empty()) {
     stream
       << "Content-Type: application/x-www-form-urlencoded\r\n"