|  | @@ -433,18 +433,33 @@ directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose,
 | 
	
		
			
				|  |  |      if (resource)
 | 
	
		
			
				|  |  |        flav = networkstatus_parse_flavor_name(resource);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    /* DEFAULT_IF_MODIFIED_SINCE_DELAY is 1/20 of the default consensus
 | 
	
		
			
				|  |  | +     * period of 1 hour.
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +#define DEFAULT_IF_MODIFIED_SINCE_DELAY (180)
 | 
	
		
			
				|  |  |      if (flav != -1) {
 | 
	
		
			
				|  |  |        /* IF we have a parsed consensus of this type, we can do an
 | 
	
		
			
				|  |  |         * if-modified-time based on it. */
 | 
	
		
			
				|  |  |        v = networkstatus_get_latest_consensus_by_flavor(flav);
 | 
	
		
			
				|  |  | -      if (v)
 | 
	
		
			
				|  |  | -        if_modified_since = v->valid_after + 180;
 | 
	
		
			
				|  |  | +      if (v) {
 | 
	
		
			
				|  |  | +        /* In networks with particularly short V3AuthVotingIntervals,
 | 
	
		
			
				|  |  | +         * ask for the consensus if it's been modified since half the
 | 
	
		
			
				|  |  | +         * V3AuthVotingInterval of the most recent consensus. */
 | 
	
		
			
				|  |  | +        time_t ims_delay = DEFAULT_IF_MODIFIED_SINCE_DELAY;
 | 
	
		
			
				|  |  | +        if (v->fresh_until > v->valid_after
 | 
	
		
			
				|  |  | +            && ims_delay > (v->fresh_until - v->valid_after)/2) {
 | 
	
		
			
				|  |  | +          ims_delay = (v->fresh_until - v->valid_after)/2;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if_modified_since = v->valid_after + ims_delay;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  |      } else {
 | 
	
		
			
				|  |  |        /* Otherwise it might be a consensus we don't parse, but which we
 | 
	
		
			
				|  |  |         * do cache.  Look at the cached copy, perhaps. */
 | 
	
		
			
				|  |  |        cached_dir_t *cd = dirserv_get_consensus(resource);
 | 
	
		
			
				|  |  | +      /* We have no method of determining the voting interval from an
 | 
	
		
			
				|  |  | +       * unparsed consensus, so we use the default. */
 | 
	
		
			
				|  |  |        if (cd)
 | 
	
		
			
				|  |  | -        if_modified_since = cd->published + 180;
 | 
	
		
			
				|  |  | +        if_modified_since = cd->published + DEFAULT_IF_MODIFIED_SINCE_DELAY;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -2258,6 +2273,7 @@ write_http_status_line(dir_connection_t *conn, int status,
 | 
	
		
			
				|  |  |      log_warn(LD_BUG,"status line too long.");
 | 
	
		
			
				|  |  |      return;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | +  log_debug(LD_DIRSERV,"Wrote status 'HTTP/1.0 %d %s'", status, reason_phrase);
 | 
	
		
			
				|  |  |    connection_write_to_buf(buf, strlen(buf), TO_CONN(conn));
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -2554,8 +2570,11 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
 | 
	
		
			
				|  |  |    if ((header = http_get_header(headers, "If-Modified-Since: "))) {
 | 
	
		
			
				|  |  |      struct tm tm;
 | 
	
		
			
				|  |  |      if (parse_http_time(header, &tm) == 0) {
 | 
	
		
			
				|  |  | -      if (tor_timegm(&tm, &if_modified_since)<0)
 | 
	
		
			
				|  |  | +      if (tor_timegm(&tm, &if_modified_since)<0) {
 | 
	
		
			
				|  |  |          if_modified_since = 0;
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        log_debug(LD_DIRSERV, "If-Modified-Since is '%s'.", escaped(header));
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      /* The correct behavior on a malformed If-Modified-Since header is to
 | 
	
		
			
				|  |  |       * act as if no If-Modified-Since header had been given. */
 |