Branch: Tag:

2004-04-13

2004-04-13 16:02:37 by Henrik Grubbström (Grubba) <grubba@grubba.org>

Added some support for the If-None-Match header.
Moved around some code from the HTTP/0.9 case.

Rev: server/protocols/http.pike:1.426

2:   // Modified by Francesco Chemolli to add throttling capabilities.   // Copyright © 1996 - 2001, Roxen IS.    - constant cvs_version = "$Id: http.pike,v 1.425 2004/04/13 09:54:06 grubba Exp $"; + constant cvs_version = "$Id: http.pike,v 1.426 2004/04/13 16:02:37 grubba Exp $";   // #define REQUEST_DEBUG   #define MAGIC_ERROR   
61:   private static int wanted_data, have_data;   private static object(String.Buffer) data_buffer;    + private static multiset(string) none_match; +    int kept_alive;      #ifdef DEBUG
693:    case "authorization": rawauth = contents; break;    case "referer": referer = ({contents}); break;    case "if-modified-since": since=contents; break; +  case "if-match": break; // Not supported yet. +  case "if-none-match": +  none_match = (multiset)((contents-" ")/","); +  break;       case "proxy-authorization":    array y;
1566:    else if(!file->type) file->type="text/plain";    }    -  if(!file->raw) +  if(!file->raw && (prot != "HTTP/0.9"))    { -  +  // Generate the headers.    heads = ([]); -  +     if (!file->stat) file->stat = misc->stat;    if(objectp(file->file)) {    if(!file->stat)
1612:   // misc->last_modified,   // misc->cacheable);    -  if(since && (!file->error || file->error == 200) && misc->last_modified) + #ifdef RAM_CACHE +  if (!(misc->etag = heads->ETag) && file->len && +  (file->data || file->file) && +  (file->len < conf->datacache->max_file_size)) { +  string data = ""; +  if (file->file) { +  data = file->file->read(file->len); +  if (file->data && (sizeof(data) < file->len)) { +  data += file->data[..file->len - (sizeof(data)+1)]; +  } +  m_delete(file, file); +  } else if (file->data) { +  data = file->data[..file->len - 1]; +  } +  file->data = data; +  heads->ETag = misc->etag = +  Crypto.string_to_hex(Crypto.md5()->update(data)->digest()); +  heads->Vary = "ETag"; +  } + #endif /* RAM_CACHE */ +  +  if (!file->error || file->error == 200) { +  if (none_match && misc->etag && +  (none_match[misc->etag] || none_match["*"])) { +  // We have a if-none-match header that matches our etag. +  if ((<"HEAD", "GET">)[method]) { +  // RFC 2616 14.26: +  // Instead, if the request method was GET or HEAD, the server +  // SHOULD respond with a 304 (Not Modified) response, including +  // the cache- related header fields (particularly ETag) of one +  // of the entities that matched. For all other request methods, +  // the server MUST respond with a status of 412 (Precondition +  // Failed). +  file->error = 304; +  } else { +  file->error = 412; +  } +  file->file = file->data = 0; +  } else if(since && misc->last_modified)    {    /* ({ time, len }) */    array(int) since_info = Roxen.parse_since( since );
1634:    )    {    file->error = 304; -  file->file = file->data = file->type = 0; +  file->file = file->data = 0;    }    } -  +  }    -  if(prot != "HTTP/0.9") +     {    string h, charset="";   
1764:    heads->Connection = "close";    misc->connection = "close";    } - #ifdef RAM_CACHE -  if (!(misc->etag = heads->eTag) && file->len && -  (file->data || file->file) && -  (file->len < conf->datacache->max_file_size)) { -  string data = ""; -  if (file->file) { -  data = file->file->read(file->len); -  if (file->data && (sizeof(data) < file->len)) { -  data += file->data[..file->len - (sizeof(data)+1)]; -  } -  m_delete(file, file); -  } else if (file->data) { -  data = file->data[..file->len - 1]; -  } -  file->data = data; -  heads->eTag = misc->etag = -  Crypto.string_to_hex(Crypto.md5()->update(data)->digest()); -  } - #endif /* RAM_CACHE */ +     if( mixed err = catch( head_string += Roxen.make_http_headers( heads ) ) )    {   #ifdef DEBUG
1837: Inside #if defined(RAM_CACHE)
   // We have to handle the date header.    "hs":head_string,    "key":misc->cachekey, +  "etag":misc->etag,    "callbacks":misc->_cachecallbacks,    "len":file->len,    // fix non-keep-alive when sending from cache