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

📄 http.c

📁 -
💻 C
📖 第 1 页 / 共 3 页
字号:
	    continue;	switch (e->id) {	case HDR_PROXY_AUTHORIZATION:	    /* If we're not doing proxy auth, then it must be passed on */	    if (!request->flags.used_proxy_auth)		httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));	    break;	case HDR_AUTHORIZATION:	    /* If we're not doing www auth, then it must be passed on */	    if (!request->flags.accelerated || !request->flags.used_proxy_auth)		httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));	    else		request->flags.auth = 0;	/* We have used the authentication */	    break;	case HDR_HOST:	    /* Don't use client's Host: header for redirected requests */	    if (!request->flags.redirected || !Config.onoff.redir_rewrites_host)		httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));	    break;	case HDR_IF_MODIFIED_SINCE:	    /* append unless we added our own;	     * note: at most one client's ims header can pass through */	    if (!httpHeaderHas(hdr_out, HDR_IF_MODIFIED_SINCE))		httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));	    break;	case HDR_MAX_FORWARDS:	    if (orig_request->method == METHOD_TRACE) {		/* sacrificing efficiency over clarity, etc. */		const int hops = httpHeaderGetInt(hdr_in, HDR_MAX_FORWARDS);		if (hops > 0)		    httpHeaderPutInt(hdr_out, HDR_MAX_FORWARDS, hops - 1);	    }	    break;	case HDR_RANGE:	case HDR_IF_RANGE:	case HDR_REQUEST_RANGE:	    if (!we_do_ranges)		httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));	    break;	case HDR_PROXY_CONNECTION:	case HDR_CONNECTION:	case HDR_VIA:	case HDR_X_FORWARDED_FOR:	case HDR_CACHE_CONTROL:	    /* append these after the loop if needed */	    break;	default:	    /* pass on all other header fields */	    httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));	}    }    /* append fake user agent if configured and      * the real one is not supplied by the client */    if (Config.fake_ua && !httpHeaderHas(hdr_out, HDR_USER_AGENT))	httpHeaderPutStr(hdr_out, HDR_USER_AGENT, Config.fake_ua);    /* append Via */    {	String strVia = httpHeaderGetList(hdr_in, HDR_VIA);	snprintf(bbuf, BBUF_SZ, "%3.1f %s", orig_request->http_ver, ThisCache);	strListAdd(&strVia, bbuf, ',');	httpHeaderPutStr(hdr_out, HDR_VIA, strBuf(strVia));	stringClean(&strVia);    }    /* append X-Forwarded-For */    {	String strFwd = httpHeaderGetList(hdr_in, HDR_X_FORWARDED_FOR);	strListAdd(&strFwd, (cfd < 0 ? "unknown" : fd_table[cfd].ipaddr), ',');	httpHeaderPutStr(hdr_out, HDR_X_FORWARDED_FOR, strBuf(strFwd));	stringClean(&strFwd);    }    /* append Host if not there already */    if (!httpHeaderHas(hdr_out, HDR_HOST)) {	/* use port# only if not default */	if (orig_request->port == urlDefaultPort(orig_request->protocol)) {	    httpHeaderPutStr(hdr_out, HDR_HOST, orig_request->host);	} else {	    httpHeaderPutStrf(hdr_out, HDR_HOST, "%s:%d",		orig_request->host, (int) orig_request->port);	}    }    /* append Authorization if known in URL, not in header and going direct */    if (!httpHeaderHas(hdr_out, HDR_AUTHORIZATION)) {	if (!request->flags.proxying && *request->login) {	    httpHeaderPutStrf(hdr_out, HDR_AUTHORIZATION, "Basic %s",		base64_encode(request->login));	}    }    /* append Proxy-Authorization if configured for peer, and proxying */    if (!httpHeaderHas(hdr_out, HDR_PROXY_AUTHORIZATION)) {	if (request->flags.proxying && request->peer_login) {	    httpHeaderPutStrf(hdr_out, HDR_PROXY_AUTHORIZATION, "Basic %s",		base64_encode(request->peer_login));	}    }    /* append Cache-Control, add max-age if not there already */    {	HttpHdrCc *cc = httpHeaderGetCc(hdr_in);	if (!cc)	    cc = httpHdrCcCreate();	if (!EBIT_TEST(cc->mask, CC_MAX_AGE)) {	    const char *url = entry ? storeUrl(entry) : urlCanonical(orig_request);	    httpHdrCcSetMaxAge(cc, getMaxAge(url));	    if (strLen(request->urlpath))		assert(strstr(url, strBuf(request->urlpath)));	}	if (flags.only_if_cached)	    EBIT_SET(cc->mask, CC_ONLY_IF_CACHED);	httpHeaderPutCc(hdr_out, cc);	httpHdrCcDestroy(cc);    }    /* maybe append Connection: keep-alive */    if (flags.keepalive) {	if (flags.proxying) {	    httpHeaderPutStr(hdr_out, HDR_PROXY_CONNECTION, "keep-alive");	} else {	    httpHeaderPutStr(hdr_out, HDR_CONNECTION, "keep-alive");	}    }    stringClean(&strConnection);}/* build request prefix and append it to a given MemBuf;  * return the length of the prefix */size_thttpBuildRequestPrefix(request_t * request,    request_t * orig_request,    StoreEntry * entry,    MemBuf * mb,    int cfd,    http_state_flags flags){    const int offset = mb->size;    memBufPrintf(mb, "%s %s HTTP/1.0\r\n",	RequestMethodStr[request->method],	strLen(request->urlpath) ? strBuf(request->urlpath) : "/");    /* build and pack headers */    {	HttpHeader hdr;	Packer p;	httpBuildRequestHeader(request, orig_request, entry, &hdr, cfd, flags);	packerToMemInit(&p, mb);	httpHeaderPackInto(&hdr, &p);	httpHeaderClean(&hdr);	packerClean(&p);    }    /* append header terminator */    memBufAppend(mb, crlf, 2);    return mb->size - offset;}/* This will be called when connect completes. Write request. */static voidhttpSendRequest(HttpStateData * httpState){    MemBuf mb;    request_t *req = httpState->request;    StoreEntry *entry = httpState->entry;    int cfd;    peer *p = httpState->peer;    CWCB *sendHeaderDone;    debug(11, 5) ("httpSendRequest: FD %d: httpState %p.\n", httpState->fd, httpState);    if (pumpMethod(req->method))	sendHeaderDone = httpSendRequestEntry;    else	sendHeaderDone = httpSendComplete;    if (!opt_forwarded_for)	cfd = -1;    else if (entry->mem_obj == NULL)	cfd = -1;    else	cfd = entry->mem_obj->fd;    assert(-1 == cfd || FD_SOCKET == fd_table[cfd].type);    if (p != NULL)	httpState->flags.proxying = 1;    /*     * Is keep-alive okay for all request methods?     */    if (p == NULL)	httpState->flags.keepalive = 1;    else if (p->stats.n_keepalives_sent < 10)	httpState->flags.keepalive = 1;    else if ((double) p->stats.n_keepalives_recv / (double) p->stats.n_keepalives_sent > 0.50)	httpState->flags.keepalive = 1;    if (httpState->peer)	if (neighborType(httpState->peer, httpState->request) == PEER_SIBLING)	    httpState->flags.only_if_cached = 1;    memBufDefInit(&mb);    httpBuildRequestPrefix(req,	httpState->orig_request,	entry,	&mb,	cfd,	httpState->flags);    debug(11, 6) ("httpSendRequest: FD %d:\n%s\n", httpState->fd, mb.buf);    comm_write_mbuf(httpState->fd, mb, sendHeaderDone, httpState);}voidhttpStart(FwdState * fwd){    int fd = fwd->server_fd;    HttpStateData *httpState = memAllocate(MEM_HTTP_STATE_DATA);    request_t *proxy_req;    request_t *orig_req = fwd->request;    debug(11, 3) ("httpStart: \"%s %s\"\n",	RequestMethodStr[orig_req->method],	storeUrl(fwd->entry));    cbdataAdd(httpState, memFree, MEM_HTTP_STATE_DATA);    storeLockObject(fwd->entry);    httpState->fwd = fwd;    httpState->entry = fwd->entry;    httpState->fd = fd;    if (fwd->servers)	httpState->peer = fwd->servers->peer;	/* might be NULL */    if (httpState->peer) {	proxy_req = requestCreate(orig_req->method,	    PROTO_NONE, storeUrl(httpState->entry));	xstrncpy(proxy_req->host, httpState->peer->host, SQUIDHOSTNAMELEN);	proxy_req->port = httpState->peer->http_port;	proxy_req->flags = orig_req->flags;	proxy_req->peer_login = httpState->peer->login;	httpState->request = requestLink(proxy_req);	httpState->orig_request = requestLink(orig_req);	proxy_req->flags.proxying = 1;	/*	 * This NEIGHBOR_PROXY_ONLY check probably shouldn't be here.	 * We might end up getting the object from somewhere else if,	 * for example, the request to this neighbor fails.	 */	if (httpState->peer->options.proxy_only)	    storeReleaseRequest(httpState->entry);#if DELAY_POOLS	assert(delayIsNoDelay(fd) == 0);	if (httpState->peer->options.no_delay)	    delaySetNoDelay(fd);#endif    } else {	httpState->request = requestLink(orig_req);	httpState->orig_request = requestLink(orig_req);    }    /*     * register the handler to free HTTP state data when the FD closes     */    comm_add_close_handler(fd, httpStateFree, httpState);    Counter.server.all.requests++;    Counter.server.http.requests++;    httpSendRequest(httpState);    /*     * We used to set the read timeout here, but not any more.     * Now its set in httpSendComplete() after the full request,     * including request body, has been written to the server.     */}static voidhttpSendRequestEntry(int fd, char *bufnotused, size_t size, int errflag, void *data){    HttpStateData *httpState = data;    StoreEntry *entry = httpState->entry;    ErrorState *err;    debug(11, 5) ("httpSendRequestEntry: FD %d: size %d: errflag %d.\n",	fd, size, errflag);    if (size > 0) {	fd_bytes(fd, size, FD_WRITE);	kb_incr(&Counter.server.all.kbytes_out, size);	kb_incr(&Counter.server.http.kbytes_out, size);    }    if (errflag == COMM_ERR_CLOSING)	return;    if (errflag) {	err = errorCon(ERR_WRITE_ERROR, HTTP_INTERNAL_SERVER_ERROR);	err->xerrno = errno;	err->request = requestLink(httpState->orig_request);	errorAppendEntry(entry, err);	comm_close(fd);	return;    }    if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {	comm_close(fd);	return;    }    pumpStart(fd, httpState->fwd, httpSendRequestEntryDone, httpState);}static voidhttpSendRequestEntryDone(int fd, char *bufnotused, size_t size, int errflag, void *data){    HttpStateData *httpState = data;    StoreEntry *entry = httpState->entry;    ErrorState *err;    aclCheck_t ch;    debug(11, 5) ("httpSendRequestEntryDone: FD %d: size %d: errflag %d.\n",	fd, size, errflag);    if (size > 0) {	fd_bytes(fd, size, FD_WRITE);	kb_incr(&Counter.server.all.kbytes_out, size);	kb_incr(&Counter.server.http.kbytes_out, size);    }    if (errflag == COMM_ERR_CLOSING)	return;    if (errflag) {	err = errorCon(ERR_WRITE_ERROR, HTTP_INTERNAL_SERVER_ERROR);	err->xerrno = errno;	err->request = requestLink(httpState->orig_request);	errorAppendEntry(entry, err);	comm_close(fd);	return;    }    memset(&ch, '\0', sizeof(ch));    ch.request = httpState->request;    if (!Config.accessList.brokenPosts) {	debug(11, 5) ("httpSendRequestEntryDone: No brokenPosts list\n");	httpSendComplete(fd, NULL, 0, 0, data);    } else if (!aclCheckFast(Config.accessList.brokenPosts, &ch)) {	debug(11, 5) ("httpSendRequestEntryDone: didn't match brokenPosts\n");	httpSendComplete(fd, NULL, 0, 0, data);    } else {	debug(11, 2) ("httpSendRequestEntryDone: matched brokenPosts\n");	comm_write(fd, "\r\n", 2, httpSendComplete, data, NULL);    }}

⌨️ 快捷键说明

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