⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 http.c

📁 -
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * $Id: http.c,v 1.346.2.7 1999/04/27 22:14:09 wessels Exp $ * * DEBUG: section 11    Hypertext Transfer Protocol (HTTP) * AUTHOR: Harvest Derived * * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/ * ---------------------------------------------------------- * *  Squid is the result of efforts by numerous individuals from the *  Internet community.  Development is led by Duane Wessels of the *  National Laboratory for Applied Network Research and funded by the *  National Science Foundation.  Squid is Copyrighted (C) 1998 by *  Duane Wessels and the University of California San Diego.  Please *  see the COPYRIGHT file for full details.  Squid incorporates *  software developed and/or copyrighted by other sources.  Please see *  the CREDITS file for full details. * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. *   *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. *   *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * *//* * Anonymizing patch by lutz@as-node.jena.thur.de * have a look into http-anon.c to get more informations. */#include "squid.h"static const char *const crlf = "\r\n";static CWCB httpSendComplete;static CWCB httpSendRequestEntry;static CWCB httpSendRequestEntryDone;static PF httpReadReply;static void httpSendRequest(HttpStateData *);static PF httpStateFree;static PF httpTimeout;static void httpCacheNegatively(StoreEntry *);static void httpMakePrivate(StoreEntry *);static void httpMakePublic(StoreEntry *);static int httpCachableReply(HttpStateData *);static void httpMaybeRemovePublic(StoreEntry *, http_status);static voidhttpStateFree(int fd, void *data){    HttpStateData *httpState = data;#if DELAY_POOLS    delayClearNoDelay(fd);#endif    if (httpState == NULL)	return;    storeUnlockObject(httpState->entry);    if (httpState->reply_hdr) {	memFree(httpState->reply_hdr, MEM_8K_BUF);	httpState->reply_hdr = NULL;    }    requestUnlink(httpState->request);    requestUnlink(httpState->orig_request);    httpState->request = NULL;    httpState->orig_request = NULL;    cbdataFree(httpState);}inthttpCachable(method_t method){    /* GET and HEAD are cachable. Others are not. */    if (method != METHOD_GET && method != METHOD_HEAD)	return 0;    /* else cachable */    return 1;}static voidhttpTimeout(int fd, void *data){    HttpStateData *httpState = data;    StoreEntry *entry = httpState->entry;    debug(11, 4) ("httpTimeout: FD %d: '%s'\n", fd, storeUrl(entry));    if (entry->store_status == STORE_PENDING) {	if (entry->mem_obj->inmem_hi == 0) {	    fwdFail(httpState->fwd,		errorCon(ERR_READ_TIMEOUT, HTTP_GATEWAY_TIMEOUT));	}    }    comm_close(fd);}/* This object can be cached for a long time */static voidhttpMakePublic(StoreEntry * entry){    if (EBIT_TEST(entry->flags, ENTRY_CACHABLE))	storeSetPublicKey(entry);}/* This object should never be cached at all */static voidhttpMakePrivate(StoreEntry * entry){    storeExpireNow(entry);    storeReleaseRequest(entry);	/* delete object when not used */    /* storeReleaseRequest clears ENTRY_CACHABLE flag */}/* This object may be negatively cached */static voidhttpCacheNegatively(StoreEntry * entry){    storeNegativeCache(entry);    if (EBIT_TEST(entry->flags, ENTRY_CACHABLE))	storeSetPublicKey(entry);}static voidhttpMaybeRemovePublic(StoreEntry * e, http_status status){    int remove = 0;    StoreEntry *pe;    if (!EBIT_TEST(e->flags, KEY_PRIVATE))	return;    switch (status) {    case HTTP_OK:    case HTTP_NON_AUTHORITATIVE_INFORMATION:    case HTTP_MULTIPLE_CHOICES:    case HTTP_MOVED_PERMANENTLY:    case HTTP_MOVED_TEMPORARILY:    case HTTP_FORBIDDEN:    case HTTP_NOT_FOUND:    case HTTP_METHOD_NOT_ALLOWED:    case HTTP_GONE:	remove = 1;	break;#if WORK_IN_PROGRESS    case HTTP_UNAUTHORIZED:	remove = 1;	break;#endif    default:	remove = 0;	break;    }    if (!remove)	return;    assert(e->mem_obj);    if ((pe = storeGetPublic(e->mem_obj->url, e->mem_obj->method)) != NULL) {	assert(e != pe);	storeRelease(pe);    }    if (e->mem_obj->method == METHOD_GET) {	/* A fresh GET should eject old HEAD objects */	if ((pe = storeGetPublic(e->mem_obj->url, METHOD_HEAD)) != NULL) {	    assert(e != pe);	    storeRelease(pe);	}    }}static inthttpCachableReply(HttpStateData * httpState){    HttpReply *rep = httpState->entry->mem_obj->reply;    HttpHeader *hdr = &rep->header;    const int cc_mask = (rep->cache_control) ? rep->cache_control->mask : 0;    const char *v;    if (EBIT_TEST(cc_mask, CC_PRIVATE))	return 0;    if (EBIT_TEST(cc_mask, CC_NO_CACHE))	return 0;    if (EBIT_TEST(cc_mask, CC_NO_STORE))	return 0;    if (httpState->request->flags.auth) {	/*	 * Responses to requests with authorization may be cached	 * only if a Cache-Control: public reply header is present.	 * RFC 2068, sec 14.9.4	 */	if (!EBIT_TEST(cc_mask, CC_PUBLIC))	    return 0;    }    /*     * We don't properly deal with Vary features yet, so we can't     * cache these     */    if (httpHeaderHas(hdr, HDR_VARY))	return 0;    /* Pragma: no-cache in _replies_ is not documented in HTTP,     * but servers like "Active Imaging Webcast/2.0" sure do use it */    if (httpHeaderHas(hdr, HDR_PRAGMA)) {	String s = httpHeaderGetList(hdr, HDR_PRAGMA);	const int no_cache = strListIsMember(&s, "no-cache", ',');	stringClean(&s);	if (no_cache)	    return 0;    }    /*     * The "multipart/x-mixed-replace" content type is used for     * continuous push replies.  These are generally dynamic and     * probably should not be cachable     */    if ((v = httpHeaderGetStr(hdr, HDR_CONTENT_TYPE)))	if (!strncasecmp(v, "multipart/x-mixed-replace", 25))	    return 0;    switch (httpState->entry->mem_obj->reply->sline.status) {	/* Responses that are cacheable */    case HTTP_OK:    case HTTP_NON_AUTHORITATIVE_INFORMATION:    case HTTP_MULTIPLE_CHOICES:    case HTTP_MOVED_PERMANENTLY:    case HTTP_GONE:	/*	 * Don't cache objects that need to be refreshed on next request,	 * unless we know how to refresh it.	 */	if (!refreshIsCachable(httpState->entry))	    return 0;	/* don't cache objects from peers w/o LMT, Date, or Expires */	/* check that is it enough to check headers @?@ */	if (rep->date > -1)	    return 1;	else if (rep->last_modified > -1)	    return 1;	else if (!httpState->peer)	    return 1;	/* @?@ (here and 302): invalid expires header compiles to squid_curtime */	else if (rep->expires > -1)	    return 1;	else	    return 0;	/* NOTREACHED */	break;	/* Responses that only are cacheable if the server says so */    case HTTP_MOVED_TEMPORARILY:	if (rep->expires > -1)	    return 1;	else	    return 0;	/* NOTREACHED */	break;	/* Errors can be negatively cached */    case HTTP_NO_CONTENT:    case HTTP_USE_PROXY:    case HTTP_BAD_REQUEST:    case HTTP_FORBIDDEN:    case HTTP_NOT_FOUND:    case HTTP_METHOD_NOT_ALLOWED:    case HTTP_REQUEST_URI_TOO_LARGE:    case HTTP_INTERNAL_SERVER_ERROR:    case HTTP_NOT_IMPLEMENTED:    case HTTP_BAD_GATEWAY:    case HTTP_SERVICE_UNAVAILABLE:    case HTTP_GATEWAY_TIMEOUT:	return -1;	/* NOTREACHED */	break;	/* Some responses can never be cached */    case HTTP_PARTIAL_CONTENT:	/* Not yet supported */    case HTTP_SEE_OTHER:    case HTTP_NOT_MODIFIED:    case HTTP_UNAUTHORIZED:    case HTTP_PROXY_AUTHENTICATION_REQUIRED:    case HTTP_INVALID_HEADER:	/* Squid header parsing error */    default:			/* Unknown status code */	return 0;	/* NOTREACHED */	break;    }    /* NOTREACHED */}/* rewrite this later using new interfaces @?@ */voidhttpProcessReplyHeader(HttpStateData * httpState, const char *buf, int size){    char *t = NULL;    StoreEntry *entry = httpState->entry;    int room;    int hdr_len;    HttpReply *reply = entry->mem_obj->reply;    debug(11, 3) ("httpProcessReplyHeader: key '%s'\n",	storeKeyText(entry->key));    if (httpState->reply_hdr == NULL)	httpState->reply_hdr = memAllocate(MEM_8K_BUF);    if (httpState->reply_hdr_state == 0) {	hdr_len = strlen(httpState->reply_hdr);	room = 8191 - hdr_len;	strncat(httpState->reply_hdr, buf, room < size ? room : size);	hdr_len += room < size ? room : size;	if (hdr_len > 4 && strncmp(httpState->reply_hdr, "HTTP/", 5)) {	    debug(11, 3) ("httpProcessReplyHeader: Non-HTTP-compliant header: '%s'\n", httpState->reply_hdr);	    httpState->reply_hdr_state += 2;	    reply->sline.status = HTTP_INVALID_HEADER;	    return;	}	t = httpState->reply_hdr + hdr_len;	/* headers can be incomplete only if object still arriving */	if (!httpState->eof) {	    size_t k = headersEnd(httpState->reply_hdr, 8192);	    if (0 == k)		return;		/* headers not complete */	    t = httpState->reply_hdr + k;	}	*t = '\0';	httpState->reply_hdr_state++;    }    if (httpState->reply_hdr_state == 1) {	const Ctx ctx = ctx_enter(entry->mem_obj->url);	httpState->reply_hdr_state++;	debug(11, 9) ("GOT HTTP REPLY HDR:\n---------\n%s\n----------\n",	    httpState->reply_hdr);	/* Parse headers into reply structure */	/* what happens if we fail to parse here? */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -