diff -c -r -x *.o -x *.orig -X exclude_files squid-1.0.alpha4/src/debug.c squid-1.0.alpha4.henrik/src/debug.c
*** squid-1.0.alpha4/src/debug.c	Wed Mar 27 21:20:44 1996
--- squid-1.0.alpha4.henrik/src/debug.c	Sun Mar 31 20:43:13 1996
***************
*** 15,21 ****
  static int debugLevels[MAX_DEBUG_SECTIONS];
  
  #if defined(__STRICT_ANSI__)
! void _db_print(int section,...)
  {
      va_list args;
  #else
--- 15,21 ----
  static int debugLevels[MAX_DEBUG_SECTIONS];
  
  #if defined(__STRICT_ANSI__)
! void _db_print(int section, int level, char *format...)
  {
      va_list args;
  #else
***************
*** 24,32 ****
  {
      va_list args;
      int section;
- #endif
      int level;
      char *format = NULL;
      static char f[BUFSIZ];
      static char tmpbuf[BUFSIZ];
      char *s = NULL;
--- 24,32 ----
  {
      va_list args;
      int section;
      int level;
      char *format = NULL;
+ #endif
      static char f[BUFSIZ];
      static char tmpbuf[BUFSIZ];
      char *s = NULL;
***************
*** 35,47 ****
  	return;
  
  #if defined(__STRICT_ANSI__)
!     va_start(args, section);
  #else
      va_start(args);
      section = va_arg(args, int);
- #endif
      level = va_arg(args, int);
      format = va_arg(args, char *);
  
      if (level > debugLevels[section]) {
  	va_end(args);
--- 35,47 ----
  	return;
  
  #if defined(__STRICT_ANSI__)
!     va_start(args, format);
  #else
      va_start(args);
      section = va_arg(args, int);
      level = va_arg(args, int);
      format = va_arg(args, char *);
+ #endif
  
      if (level > debugLevels[section]) {
  	va_end(args);
diff -c -r -x *.o -x *.orig -X exclude_files squid-1.0.alpha4/src/http.c squid-1.0.alpha4.henrik/src/http.c
*** squid-1.0.alpha4/src/http.c	Sat Mar 30 01:09:04 1996
--- squid-1.0.alpha4.henrik/src/http.c	Mon Apr  1 03:23:52 1996
***************
*** 160,179 ****
  	strncat(data->reply_hdr, buf, 8191 - strlen(data->reply_hdr));
  	if ((t = strstr(data->reply_hdr, "\r\n\r\n"))) {
  	    data->reply_hdr_state++;
! 	    t += 2;
  	    *t = '\0';
  	} else if ((t = strstr(data->reply_hdr, "\n\n"))) {
  	    data->reply_hdr_state++;
! 	    t++;
  	    *t = '\0';
  	}
      }
      if (data->reply_hdr_state == 1) {
  	data->reply_hdr_state++;
  	debug(11, 9, "GOT HTTP REPLY HDR:\n---------\n%s\n----------\n",
  	    data->reply_hdr);
! 	t = strtok(data->reply_hdr, "\r\n");
  	while (t) {
  	    if (!strncasecmp(t, "HTTP", 4)) {
  		if ((t = strchr(t, ' '))) {
  		    t++;
--- 160,182 ----
  	strncat(data->reply_hdr, buf, 8191 - strlen(data->reply_hdr));
  	if ((t = strstr(data->reply_hdr, "\r\n\r\n"))) {
  	    data->reply_hdr_state++;
! 	    t += 4;
  	    *t = '\0';
  	} else if ((t = strstr(data->reply_hdr, "\n\n"))) {
  	    data->reply_hdr_state++;
! 	    t += 2;
  	    *t = '\0';
  	}
      }
      if (data->reply_hdr_state == 1) {
+ 	char *headers=xstrdup(data->reply_hdr);
  	data->reply_hdr_state++;
  	debug(11, 9, "GOT HTTP REPLY HDR:\n---------\n%s\n----------\n",
  	    data->reply_hdr);
! 	t = strtok(headers, "\n");
  	while (t) {
+ 	    while(t[strlen(t)]=='\r')
+ 	      t[strlen(t)]=0;
  	    if (!strncasecmp(t, "HTTP", 4)) {
  		if ((t = strchr(t, ' '))) {
  		    t++;
***************
*** 190,201 ****
  		    data->content_length = atoi(t);
  		}
  	    }
! 	    t = strtok(NULL, "\r\n");
  	}
  	if (data->http_code)
! 	    debug(11, 0, "httpReadReply: HTTP CODE: %d\n", data->http_code);
  	if (data->content_length)
! 	    debug(11, 0, "httpReadReply: Content Length: %d\n", data->content_length);
  	/* If we know this is cachable we can unchange the key */
  	switch (data->http_code) {
  	case 200:		/* OK */
--- 193,204 ----
  		    data->content_length = atoi(t);
  		}
  	    }
! 	    t = strtok(NULL, "\n");
  	}
  	if (data->http_code)
! 	    debug(11, 1, "httpReadReply: HTTP CODE: %d\n", data->http_code);
  	if (data->content_length)
! 	    debug(11, 1, "httpReadReply: Content Length: %d\n", data->content_length);
  	/* If we know this is cachable we can unchange the key */
  	switch (data->http_code) {
  	case 200:		/* OK */
***************
*** 213,218 ****
--- 216,223 ----
  	    break;
  	}
      }
+     /* Calculate expiry time */
+     entry->expires = cached_curtime + ttlSet(entry);
  }
  
  
***************
*** 279,288 ****
  	if (errno == ECONNRESET) {
  	    /* Connection reset by peer */
  	    /* consider it as a EOF */
- 	    if (!(entry->flag & DELETE_BEHIND))
- 		entry->expires = cached_curtime + ttlSet(entry);
  	    sprintf(tmp_error_buf, "\n<p>Warning: The Remote Server sent RESET at the end of transmission.\n");
  	    storeAppend(entry, tmp_error_buf, strlen(tmp_error_buf));
  	    storeComplete(entry);
  	    httpCloseAndFree(fd, data);
  	} else if (errno == EAGAIN || errno == EWOULDBLOCK) {
--- 284,295 ----
  	if (errno == ECONNRESET) {
  	    /* Connection reset by peer */
  	    /* consider it as a EOF */
  	    sprintf(tmp_error_buf, "\n<p>Warning: The Remote Server sent RESET at the end of transmission.\n");
  	    storeAppend(entry, tmp_error_buf, strlen(tmp_error_buf));
+ 	    /* The object is not cacheable */
+ 	    /* I am not sure if this is the right way to do it / Henrik */
+ 	    BIT_RESET(entry->flag, CACHABLE);
+ 	    BIT_SET(entry->flag, RELEASE_REQUEST);
  	    storeComplete(entry);
  	    httpCloseAndFree(fd, data);
  	} else if (errno == EAGAIN || errno == EWOULDBLOCK) {
***************
*** 298,305 ****
  	}
      } else if (len == 0) {
  	/* Connection closed; retrieval done. */
- 	if (!(entry->flag & DELETE_BEHIND))
- 	    entry->expires = cached_curtime + ttlSet(entry);
  	storeComplete(entry);
  	httpCloseAndFree(fd, data);
      } else if (((entry->mem_obj->e_current_len + len) > getHttpMax()) &&
--- 305,310 ----
diff -c -r -x *.o -x *.orig -X exclude_files squid-1.0.alpha4/src/icp.c squid-1.0.alpha4.henrik/src/icp.c
*** squid-1.0.alpha4/src/icp.c	Sat Mar 30 01:21:53 1996
--- squid-1.0.alpha4.henrik/src/icp.c	Mon Apr  1 05:23:02 1996
***************
*** 112,127 ****
  	sprintf(tmp_error_buf, "icpCloseAndFree: Called with NULL icpState from %s line %d", __FILE__, line);
  	fatal_dump(tmp_error_buf);
      }
!     debug(12, 0, "icpCloseAndFree: entry=%p\n", icpState->entry);
      if (icpState->entry)
  	size = icpState->entry->mem_obj->e_current_len;
!     debug(12, 0, "icpCloseAndFree: size=%d\n", size);
      CacheInfo->log_append(CacheInfo,
  	icpState->url,
  	inet_ntoa(icpState->peer.sin_addr),
  	size,
  	log_tags[icpState->log_type],
! 	icpState->type);
      safe_free(icpState->url);
      safe_free(icpState->type);
      safe_free(icpState->mime_hdr);
--- 112,127 ----
  	sprintf(tmp_error_buf, "icpCloseAndFree: Called with NULL icpState from %s line %d", __FILE__, line);
  	fatal_dump(tmp_error_buf);
      }
!     debug(12, 1, "icpCloseAndFree: entry=%p\n", icpState->entry);
      if (icpState->entry)
  	size = icpState->entry->mem_obj->e_current_len;
!     debug(12, 1, "icpCloseAndFree: size=%d\n", size);
      CacheInfo->log_append(CacheInfo,
  	icpState->url,
  	inet_ntoa(icpState->peer.sin_addr),
  	size,
  	log_tags[icpState->log_type],
! 	icpState->type?icpState->type:"UNKNOWN");
      safe_free(icpState->url);
      safe_free(icpState->type);
      safe_free(icpState->mime_hdr);
***************
*** 325,331 ****
  
      /* Clean up client side statemachine */
      entry = state->entry;
!     debug(12, 0, "icpSendERRORComplete: entry=%p\n", entry);
      icpFreeBufOrPage(state);
      icpCloseAndFree(fd, state, __LINE__);
  
--- 325,331 ----
  
      /* Clean up client side statemachine */
      entry = state->entry;
!     debug(12, 1, "icpSendERRORComplete: entry=%p\n", entry);
      icpFreeBufOrPage(state);
      icpCloseAndFree(fd, state, __LINE__);
  
***************
*** 353,359 ****
      debug(12, 4, "icpSendERROR: code %d: port %d: msg: '%s'\n",
  	errorCode, port, msg);
  
!     debug(12, 0, "icpSendERROR: state=%p  state->entry=%p\n", state, state->entry);
  
      if (port == COMM_ERROR) {
  	/* This file descriptor isn't bound to a socket anymore.
--- 353,359 ----
      debug(12, 4, "icpSendERROR: code %d: port %d: msg: '%s'\n",
  	errorCode, port, msg);
  
!     debug(12, 1, "icpSendERROR: state=%p  state->entry=%p\n", state, state->entry);
  
      if (port == COMM_ERROR) {
  	/* This file descriptor isn't bound to a socket anymore.
***************
*** 460,466 ****
  	state->entry = NULL;	/* Don't use a subsequently freed storeEntry */
  #endif
  	state->log_type = entry->mem_obj->abort_code;
! 	debug(12, 0, "icpHandleStore: abort_code=%d\n", entry->mem_obj->abort_code);
  	state->ptr_to_4k_page = NULL;	/* Nothing to deallocate */
  	state->buf = NULL;	/* Nothing to deallocate */
  	icpSendERROR(fd,
--- 460,466 ----
  	state->entry = NULL;	/* Don't use a subsequently freed storeEntry */
  #endif
  	state->log_type = entry->mem_obj->abort_code;
! 	debug(12, 1, "icpHandleStore: abort_code=%d\n", entry->mem_obj->abort_code);
  	state->ptr_to_4k_page = NULL;	/* Nothing to deallocate */
  	state->buf = NULL;	/* Nothing to deallocate */
  	icpSendERROR(fd,
***************
*** 573,586 ****
  
  	    /* Send object to requestor */
  	    entry->refcount++;	/* HIT CASE */
  	    icpSendMoreData(fd, usm);
  	    return;
  	}
  	/* We do NOT hold a lock on the existing "entry" because we're
  	 * about to eject it */
! 	tmp_in_addr.s_addr = htonl(usm->header.shostid);
! 	if (!lock)
  	    debug(12, 0, "icp_hit_or_miss: swap file open failed\n");
  	usm->log_type = LOG_TCP_EXPIRED;
  	CacheInfo->proto_miss(CacheInfo, CacheInfo->proto_id(url));
  	icpProcessMISS(fd, usm);
--- 573,587 ----
  
  	    /* Send object to requestor */
  	    entry->refcount++;	/* HIT CASE */
+ 
  	    icpSendMoreData(fd, usm);
  	    return;
  	}
  	/* We do NOT hold a lock on the existing "entry" because we're
  	 * about to eject it */
! 	if(lock<0)
  	    debug(12, 0, "icp_hit_or_miss: swap file open failed\n");
+ 	tmp_in_addr.s_addr = htonl(usm->header.shostid);
  	usm->log_type = LOG_TCP_EXPIRED;
  	CacheInfo->proto_miss(CacheInfo, CacheInfo->proto_id(url));
  	icpProcessMISS(fd, usm);
***************
*** 1194,1201 ****
  	*t = '\0';
      if ((t = strchr(url, '#')))	/* remove HTML anchors */
  	*t = '\0';
- 
-     /* We now filter If-Modified-Since in httpSendRequest() */
  
      /* see if we running in httpd_accel_mode, if so got to convert it to URL */
      if (httpd_accel_mode && url[0] == '/') {
--- 1195,1200 ----
diff -c -r -x *.o -x *.orig -X exclude_files squid-1.0.alpha4/src/mime.c squid-1.0.alpha4.henrik/src/mime.c
*** squid-1.0.alpha4/src/mime.c	Fri Mar 29 22:19:23 1996
--- squid-1.0.alpha4.henrik/src/mime.c	Mon Apr  1 05:44:19 1996
***************
*** 4,17 ****
  #include "squid.h"
  #include "mime_table.h"
  
  int mime_refresh_request(mime)
       char *mime;
  {
!     if (strstr(mime, "no-cache"))
  	return 1;
  
!     if (strstr(mime, "If-Modified-Since"))
! 	return 1;
  
      return 0;
  }
--- 4,44 ----
  #include "squid.h"
  #include "mime_table.h"
  
+ char *mime_get_header(char *mime, char *name)
+ {
+     static char header[1024];
+     char *p;
+     char got=0;
+ 
+     for(p=mime;*p;p+=strcspn(p,"\n\r")) {
+     	if(strcmp(p,"\r\n\r\n")==0 || strcmp(p,"\n\n")==0)
+ 	  return NULL;
+     	while(isspace(*p)) p++;
+     	if(strncasecmp(p,name,strlen(name))==0 &&
+ 	  (isspace(p[strlen(name)]) || p[strlen(name)]==':')) {
+ 	    strncpy(header,p,sizeof(header));
+ 	    header[sizeof(header)-1]=0;
+ 	    header[strcspn(header,"\n\r")]=0;
+ 	    p=header;
+ 	    p+=strlen(name);
+ 	    if(*p==':') p++,got=1;
+ 	    while(isspace(*p)) p++,got=1;
+ 	    if (got) return p;
+ 	}
+     }
+     return NULL;
+ }
+ 
  int mime_refresh_request(mime)
       char *mime;
  {
!     char *pr;
!     pr=mime_get_header(mime,"pragma");
!     if (pr && strstr(pr,"no-cache"))
  	return 1;
  
!     if (mime_get_header("If-Modified-Since"))
!         return 1;
  
      return 0;
  }
diff -c -r -x *.o -x *.orig -X exclude_files squid-1.0.alpha4/src/mime.h squid-1.0.alpha4.henrik/src/mime.h
*** squid-1.0.alpha4/src/mime.h	Wed Mar 27 02:46:14 1996
--- squid-1.0.alpha4.henrik/src/mime.h	Sun Mar 31 23:29:12 1996
***************
*** 12,17 ****
--- 12,18 ----
      char *icon;
  } ext_table_entry;
  
+ extern char *mime_get_header _PARAMS((char *mime, char *header));
  extern void mime_process _PARAMS((char *mime));
  extern int mime_refresh_request _PARAMS((char *mime));
  extern ext_table_entry *mime_ext_to_type _PARAMS((char *extension));
diff -c -r -x *.o -x *.orig -X exclude_files squid-1.0.alpha4/src/stat.c squid-1.0.alpha4.henrik/src/stat.c
*** squid-1.0.alpha4/src/stat.c	Fri Mar 29 22:19:25 1996
--- squid-1.0.alpha4.henrik/src/stat.c	Sun Mar 31 21:15:10 1996
***************
*** 173,179 ****
  	    elapsed_time(entry, (int) entry->timestamp, space),
  	    flags_describe(entry),
  	    elapsed_time(entry, (int) entry->lastref, space2),
! 	    ttl_describe(entry, (int) entry->expires),
  	    npend,
  	    (int) entry->refcount,
  	    mem_describe(entry),
--- 173,179 ----
  	    elapsed_time(entry, (int) entry->timestamp, space),
  	    flags_describe(entry),
  	    elapsed_time(entry, (int) entry->lastref, space2),
! 	    ttl_describe(entry),
  	    npend,
  	    (int) entry->refcount,
  	    mem_describe(entry),
***************
*** 1107,1115 ****
  }
  
  
! char *ttl_describe(entry, expires)
       StoreEntry *entry;
-      int expires;
  {
      int hh, mm, ss;
      static char TTL[60];
--- 1107,1114 ----
  }
  
  
! char *ttl_describe(entry)
       StoreEntry *entry;
  {
      int hh, mm, ss;
      static char TTL[60];
***************
*** 1117,1123 ****
  
      TTL[0] = '\0';
      strcpy(TTL, "UNKNOWN");	/* sometimes the TTL isn't set below */
!     ttl = expires - cached_curtime;
      if (ttl < 0)
  	strcpy(TTL, "EXPIRED");
      else {
--- 1116,1122 ----
  
      TTL[0] = '\0';
      strcpy(TTL, "UNKNOWN");	/* sometimes the TTL isn't set below */
!     ttl = entry->expires - cached_curtime;
      if (ttl < 0)
  	strcpy(TTL, "EXPIRED");
      else {
diff -c -r -x *.o -x *.orig -X exclude_files squid-1.0.alpha4/src/store.c squid-1.0.alpha4.henrik/src/store.c
*** squid-1.0.alpha4/src/store.c	Fri Mar 29 22:20:12 1996
--- squid-1.0.alpha4.henrik/src/store.c	Mon Apr  1 03:25:52 1996
***************
*** 749,754 ****
--- 749,763 ----
  
  }
  
+ /* Mark object as expired
+  */
+ void storeExpire(e)
+     StoreEntry *e;
+ {
+     debug(20, 3, "storeExpire: Object %s\n", e->key);
+     e->expires = cached_curtime;
+ }
+ 
  /* switch object to deleting behind mode 
   * call by retrieval module when object gets too big.
   */
***************
*** 766,772 ****
      BIT_SET(e->flag, DELETE_BEHIND);
      BIT_SET(e->flag, RELEASE_REQUEST);
      BIT_RESET(e->flag, CACHABLE);
!     e->expires = cached_curtime;
  }
  
  /* Append incoming data from a primary server to an entry. */
--- 775,781 ----
      BIT_SET(e->flag, DELETE_BEHIND);
      BIT_SET(e->flag, RELEASE_REQUEST);
      BIT_RESET(e->flag, CACHABLE);
!     storeExpire(e);
  }
  
  /* Append incoming data from a primary server to an entry. */
***************
*** 1296,1301 ****
--- 1305,1315 ----
  {
      debug(20, 5, "storeComplete: <URL:%s>\n", e->url);
  
+     if(e->flag & KEY_CHANGE) {
+         /* Never cache private objects */
+     	BIT_SET(e->flag,RELEASE_REQUEST);
+ 	BIT_RESET(e->flag,CACHABLE);
+     }
      e->object_len = e->mem_obj->e_current_len;
      InvokeHandlers(e);
      e->lastref = cached_curtime;
***************
*** 1879,1884 ****
--- 1893,1899 ----
      /* If, for any reason we can't discard this object because of an
       * outstanding request, mark it for pending release */
      if (storeEntryLocked(e)) {
+     	storeExpire(e);
  	BIT_SET(e->flag, RELEASE_REQUEST);
  	return -1;
      }
***************
*** 1952,1958 ****
  	return;
      }
      if (table == (HashID) 0)
! 	fatal_dump("storeUnChangeKey: Hash table 'table' is zero!\n");
  
      if ((table_entry = hash_lookup(table, e->key)))
  	result = (StoreEntry *) table_entry;
--- 1967,1973 ----
  	return;
      }
      if (table == (HashID) 0)
! 	fatal_dump("storeChangeKey: Hash table 'table' is zero!\n");
  
      if ((table_entry = hash_lookup(table, e->key)))
  	result = (StoreEntry *) table_entry;
***************
*** 2023,2029 ****
      storeHashInsert(e);
      BIT_RESET(E1->flag, KEY_CHANGE);
      BIT_SET(E1->flag, KEY_URL);
!     debug(25, 0, "storeUnChangeKey: Changed back to '%s'\n", key);
  }
  
  /* return if the current key is the original one. */
--- 2038,2044 ----
      storeHashInsert(e);
      BIT_RESET(E1->flag, KEY_CHANGE);
      BIT_SET(E1->flag, KEY_URL);
!     debug(25, 1, "storeUnChangeKey: Changed back to '%s'\n", key);
  }
  
  /* return if the current key is the original one. */
***************
*** 2199,2207 ****
      return *size;
  }
  
- 
- 
- 
  /*
   * Go through the first 300 bytes of MIME header of a cached object, returning
   * fields that match.
--- 2214,2219 ----
***************
*** 2250,2256 ****
  int storeEntryValidToSend(e)
       StoreEntry *e;
  {
!     if ((cached_curtime < e->expires) || (e->status == STORE_PENDING))
  	return 1;
      return 0;
  }
--- 2262,2268 ----
  int storeEntryValidToSend(e)
       StoreEntry *e;
  {
!     if ((cached_curtime < e->expires) || (!e->expires && e->status==STORE_PENDING))
  	return 1;
      return 0;
  }
diff -c -r -x *.o -x *.orig -X exclude_files squid-1.0.alpha4/src/ttl.c squid-1.0.alpha4.henrik/src/ttl.c
*** squid-1.0.alpha4/src/ttl.c	Fri Mar 29 22:19:27 1996
--- squid-1.0.alpha4.henrik/src/ttl.c	Mon Apr  1 00:08:45 1996
***************
*** 87,103 ****
  
      debug(22, 5, "ttlSet: Choosing TTL for %s\n", entry->url);
  
-     /*
-      * Check for Unauthorized HTTP requests.
-      * This needs to be improved.  I don't think we can/should rely on
-      * a server sending the string 'Unauthorized'.  Would be nice if
-      * we could write 'if (http_code == 401)' in http.c.       -DW
-      */
-     if (storeGrep(entry, "401", 15))	/* Unauthorized */
- 	return 0;
-     if (storeGrep(entry, "407", 15))	/* NS: Proxy Authentication Required */
- 	return 0;
- 
      /* these are case-insensitive compares */
      buf[0] = '\0';
      if (storeMatchMime(entry, "last-modified: ", buf, 300)) {
--- 87,92 ----
***************
*** 159,165 ****
  	if (regexec(&(t->compiled_pattern), entry->url, 0, 0, 0) == 0) {
  	    match = t;
  	    debug(22, 5, "ttlSet: Matched '%s %d %d%%'\n",
! 		match->pattern, match->abs_ttl, match->pct_age);
  	    flags |= TTL_MATCHED;
  	}
      }
--- 148,155 ----
  	if (regexec(&(t->compiled_pattern), entry->url, 0, 0, 0) == 0) {
  	    match = t;
  	    debug(22, 5, "ttlSet: Matched '%s %d %d%%'\n",
! 		match->pattern, match->abs_ttl>0 ? match->abs_ttl:default_ttl,
! 		match->pct_age);
  	    flags |= TTL_MATCHED;
  	}
      }
