/*
- * $Id: client_side.cc,v 1.231 1998/03/20 05:07:39 wessels Exp $
+ * $Id: client_side.cc,v 1.232 1998/03/20 18:02:08 rousskov Exp $
*
* DEBUG: section 33 Client-side Routines
* AUTHOR: Duane Wessels
static void clientParseRequestHeaders(clientHttpRequest *);
static void clientProcessRequest(clientHttpRequest *);
static void clientProcessExpired(void *data);
+static void clientProcessOnlyIfCachedMiss(clientHttpRequest * http);
static HttpReply *clientConstructProxyAuthReply(clientHttpRequest * http);
static int clientCachable(clientHttpRequest * http);
static int clientHierarchical(clientHttpRequest * http);
rep = errorBuildReply(err);
errorStateFree(err);
/* add Authenticate header */
- httpHeaderSetStr(&rep->hdr, HDR_PROXY_AUTHENTICATE, proxy_auth_challenge);
+ httpHeaderPutStr(&rep->header, HDR_PROXY_AUTHENTICATE, proxy_auth_challenge);
return rep;
}
if (entry->lastmod < 0)
return 1;
/* Find size of the object */
- object_length = httpReplyContentLen(mem->reply);
+ object_length = mem->reply->content_length;
if (object_length < 0)
object_length = contentLen(entry);
if (entry->lastmod > request->ims) {
debug(33, 9) ("httpRequestFree: al.url='%s'\n", http->al.url);
if (mem) {
http->al.http.code = mem->reply->sline.status;
- http->al.http.content_type = httpReplyContentType(mem->reply);
+ http->al.http.content_type = strBuf(mem->reply->content_type);
}
http->al.cache.caddr = conn->log_addr;
http->al.cache.size = http->out.size;
debug(33, 3) ("clientBuildReplyHeader: OUTPUT:\n%s\n", hdr_out);
memFree(MEM_4K_BUF, xbuf);
memFree(MEM_4K_BUF, ybuf);
+ /* temporary kludge to test headers, remove it @?@ @?@ */
+ {
+ extern void httpHeaderTestParser(const char *hstr);
+ httpHeaderTestParser(hdr_out);
+ }
+ /* end of kludge */
return len;
}
} else if ((done = clientCheckTransferDone(http)) != 0 || size == 0) {
debug(33, 5) ("clientWriteComplete: FD %d transfer is DONE\n", fd);
/* We're finished case */
- if (httpReplyContentLen(http->entry->mem_obj->reply) < 0 || !done ||
+ if (http->entry->mem_obj->reply->content_length < 0 || !done ||
EBIT_TEST(entry->flag, ENTRY_BAD_LENGTH)) {
/*
* Client connection closed due to unknown or invalid
comm_close(fd);
}
+/*
+ * client issued a request with an only-if-cached cache-control directive
+ * we did not find a cached object that can be returned without
+ * contacting other servers
+ * respond with a 504 (Gateway Timeout) as suggested in [RFC 2068]
+ */
+static void
+clientProcessOnlyIfCachedMiss(clientHttpRequest * http)
+{
+ char *url = http->uri;
+ request_t *r = http->request;
+ ErrorState *err = NULL;
+ debug(33, 4) ("clientProcessOnlyIfCachedMiss: '%s %s'\n",
+ RequestMethodStr[r->method], url);
+ debug(33, 10) ("clientProcessMiss: request_hdr:\n%s\n", r->headers);
+ http->al.http.code = HTTP_GATEWAY_TIMEOUT;
+ err = errorCon(ERR_ONLY_IF_CACHED_MISS, HTTP_GATEWAY_TIMEOUT);
+ err->request = requestLink(r);
+ err->src_addr = http->conn->peer.sin_addr;
+ http->entry = clientCreateStoreEntry(http, r->method, 0);
+ errorAppendEntry(http->entry, err);
+}
+
static log_type
clientProcessRequest2(clientHttpRequest * http)
{
storeClientListAdd(entry, http);
}
http->out.offset = 0;
+ /* "pure" hit? (will not contact other servers) */
switch (http->log_type) {
case LOG_TCP_HIT:
case LOG_TCP_NEGATIVE_HIT:
memAllocate(MEM_4K_BUF),
clientCacheHit,
http);
+ return;
+ default:
break;
+ }
+ /* ok, it is a miss or a "dirty" hit (will contact other servers) */
+ /* are we allowed to contact other servers? */
+ if (r->cache_control && EBIT_TEST(r->cache_control->mask, CC_ONLY_IF_CACHED)) {
+ /* nope, bailing out */
+ clientProcessOnlyIfCachedMiss(http);
+ return;
+ }
+ switch (http->log_type) {
case LOG_TCP_IMS_MISS:
if (entry->store_status == STORE_ABORTED)
debug(33, 0) ("clientProcessRequest 2: entry->swap_status == STORE_ABORTED\n");
*(*headers_p + header_sz) = '\0';
debug(33, 5) ("parseHttpRequest: Request Header is\n%s\n", *headers_p);
+ /* temporary kludge to test headers, remove it @?@ @?@ */
+ {
+ extern void httpHeaderTestParser(const char *hstr);
+ httpHeaderTestParser(*headers_p);
+ }
+ /* end of kludge */
/* Assign http->uri */
if ((t = strchr(url, '\n'))) /* remove NL */
return 1;
if (http->entry->mem_obj == NULL)
return 1;
- expectlen = httpReplyContentLen(http->entry->mem_obj->reply);
+ expectlen = http->entry->mem_obj->reply->content_length;
curlen = http->entry->mem_obj->inmem_hi;
minlen = Config.quickAbort.min;
if (minlen < 0)
MemObject *mem;
http_reply *reply;
int sendlen;
- int clen;
if (entry == NULL)
return 0;
/*
* then we must wait for the object to become STORE_OK or
* STORE_ABORTED.
*/
- clen = httpReplyContentLen(reply);
if (sending == SENDING_HDRSONLY)
sendlen = reply->hdr_sz;
- else if (clen < 0)
+ else if (reply->content_length < 0)
return 0;
else
- sendlen = clen + reply->hdr_sz;
+ sendlen = reply->content_length + reply->hdr_sz;
/*
* Now that we have the expected length, did we send it all?
*/