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

📄 forward.c

📁 -
💻 C
📖 第 1 页 / 共 2 页
字号:
     * Assert that server_fd is set.  This is to guarantee that fwdState     * is attached to something and will be deallocated when server_fd     * is closed.     */    assert(fwdState->server_fd > -1);    if (fwdState->servers && (p = fwdState->servers->peer)) {	p->stats.fetches++;	httpStart(fwdState);    } else {	switch (request->protocol) {	case PROTO_HTTP:	    httpStart(fwdState);	    break;	case PROTO_GOPHER:	    gopherStart(fwdState);	    break;	case PROTO_FTP:	    ftpStart(fwdState);	    break;	case PROTO_WAIS:	    waisStart(fwdState);	    break;	case PROTO_CACHEOBJ:	case PROTO_INTERNAL:	case PROTO_URN:	    fatal_dump("Should never get here");	    break;	case PROTO_WHOIS:	    whoisStart(fwdState);	    break;	default:	    debug(17, 1) ("fwdDispatch: Cannot retrieve '%s'\n",		storeUrl(entry));	    fwdFail(fwdState, errorCon(ERR_UNSUP_REQ, HTTP_BAD_REQUEST));	    comm_close(fwdState->server_fd);	    break;	}    }}static intfwdReforward(FwdState * fwdState){    StoreEntry *e = fwdState->entry;    FwdServer *fs = fwdState->servers;    http_status s;    assert(e->store_status == STORE_PENDING);    assert(e->mem_obj);    debug(17, 3) ("fwdReforward: %s?\n", storeUrl(e));    if (!EBIT_TEST(e->flags, ENTRY_FWD_HDR_WAIT)) {	debug(17, 3) ("fwdReforward: No, ENTRY_FWD_HDR_WAIT isn't set\n");	return 0;    }    if (fwdState->n_tries > 9)	return 0;    if (pumpMethod(fwdState->request->method))	if (0 == pumpRestart(fwdState->request))	    return 0;    assert(fs);    fwdState->servers = fs->next;    fwdServerFree(fs);    if (fwdState->servers == NULL) {	debug(17, 3) ("fwdReforward: No forward-servers left\n");	return 0;    }    s = e->mem_obj->reply->sline.status;    debug(17, 3) ("fwdReforward: status %d\n", (int) s);    return fwdReforwardableStatus(s);}/* PUBLIC FUNCTIONS */voidfwdServersFree(FwdServer ** FS){    FwdServer *fs;    while ((fs = *FS)) {	*FS = fs->next;	fwdServerFree(fs);    }}voidfwdStart(int fd, StoreEntry * e, request_t * r, struct in_addr client_addr,    struct in_addr my_addr){    FwdState *fwdState;    aclCheck_t ch;    int answer;    ErrorState *err;    /*     * client_addr == no_addr indicates this is an "internal" request     * from peer_digest.c, asn.c, netdb.c, etc and should always     * be allowed.  yuck, I know.     */    if (client_addr.s_addr != no_addr.s_addr) {	/*      	 * Check if this host is allowed to fetch MISSES from us (miss_access)	 */	memset(&ch, '\0', sizeof(aclCheck_t));	ch.src_addr = client_addr;	ch.my_addr = my_addr;	ch.request = r;	answer = aclCheckFast(Config.accessList.miss, &ch);	if (answer == 0) {	    err = errorCon(ERR_FORWARDING_DENIED, HTTP_FORBIDDEN);	    err->request = requestLink(r);	    err->src_addr = client_addr;	    errorAppendEntry(e, err);	    return;	}    }    debug(17, 3) ("fwdStart: '%s'\n", storeUrl(e));    e->mem_obj->request = requestLink(r);    e->mem_obj->fd = fd;    if (shutting_down) {	/* more yuck */	err = errorCon(ERR_SHUTTING_DOWN, HTTP_SERVICE_UNAVAILABLE);	err->request = requestLink(r);	errorAppendEntry(e, err);	return;    }    switch (r->protocol) {	/*	 * Note, don't create fwdState for these requests	 */    case PROTO_INTERNAL:	internalStart(r, e);	return;    case PROTO_CACHEOBJ:	cachemgrStart(fd, r, e);	return;    case PROTO_URN:	urnStart(r, e);	return;    default:	break;    }    fwdState = memAllocate(MEM_FWD_STATE);    cbdataAdd(fwdState, memFree, MEM_FWD_STATE);    fwdState->entry = e;    fwdState->client_fd = fd;    fwdState->server_fd = -1;    fwdState->request = requestLink(r);    fwdState->start = squid_curtime;    storeLockObject(e);    EBIT_SET(e->flags, ENTRY_FWD_HDR_WAIT);    storeRegisterAbort(e, fwdAbort, fwdState);    peerSelect(r, e, fwdStartComplete, fwdState);}intfwdCheckDeferRead(int fd, void *data){    StoreEntry *e = data;    MemObject *mem = e->mem_obj;    if (mem == NULL)	return 0;#if DELAY_POOLS    if (fd < 0)	(void) 0;    else if (delayIsNoDelay(fd))	(void) 0;    else if (delayMostBytesWanted(mem, 1) == 0)	return 1;#endif    if (EBIT_TEST(e->flags, ENTRY_FWD_HDR_WAIT))	return 0;    if (mem->inmem_hi - storeLowestMemReaderOffset(e) < READ_AHEAD_GAP)	return 0;    return 1;}voidfwdFail(FwdState * fwdState, ErrorState * errorState){    assert(EBIT_TEST(fwdState->entry->flags, ENTRY_FWD_HDR_WAIT));    debug(17, 3) ("fwdFail: %s \"%s\"\n\t%s\n",	err_type_str[errorState->type],	httpStatusString(errorState->http_status),	storeUrl(fwdState->entry));    if (fwdState->err)	errorStateFree(fwdState->err);    fwdState->err = errorState;}/* * Called when someone else calls StoreAbort() on this entry */voidfwdAbort(void *data){    FwdState *fwdState = data;    debug(17, 2) ("fwdAbort: %s\n", storeUrl(fwdState->entry));    fwdStateFree(fwdState);}/* * Frees fwdState without closing FD or generating an abort */voidfwdUnregister(int fd, FwdState * fwdState){    debug(17, 3) ("fwdUnregister: %s\n", storeUrl(fwdState->entry));    assert(fd = fwdState->server_fd);    assert(fd > -1);    comm_remove_close_handler(fd, fwdServerClosed, fwdState);    fwdState->server_fd = -1;}/* * server-side modules call fwdComplete() when they are done * downloading an object.  Then, we either 1) re-forward the * request somewhere else if needed, or 2) call storeComplete() * to finish it off */voidfwdComplete(FwdState * fwdState){    StoreEntry *e = fwdState->entry;    assert(e->store_status == STORE_PENDING);    debug(17, 3) ("fwdComplete: %s\n\tstatus %d\n", storeUrl(e),	e->mem_obj->reply->sline.status);    fwdLogReplyStatus(fwdState->n_tries, e->mem_obj->reply->sline.status);    if (fwdReforward(fwdState)) {	debug(17, 3) ("fwdComplete: re-forwarding %d %s\n",	    e->mem_obj->reply->sline.status,	    storeUrl(e));	if (fwdState->server_fd > -1)	    fwdUnregister(fwdState->server_fd, fwdState);	storeEntryReset(e);	fwdStartComplete(fwdState->servers, fwdState);    } else {	debug(17, 3) ("fwdComplete: not re-forwarding status %d\n",	    e->mem_obj->reply->sline.status);	EBIT_CLR(e->flags, ENTRY_FWD_HDR_WAIT);	storeComplete(e);	/*	 * If fwdState isn't associated with a server FD, it	 * won't get freed unless we do it here.	 */	if (fwdState->server_fd < 0)	    fwdStateFree(fwdState);    }}voidfwdInit(void){    cachemgrRegister("forward",	"Request Forwarding Statistics",	fwdStats, 0, 1);}static voidfwdLogReplyStatus(int tries, http_status status){    if (status > HTTP_INVALID_HEADER)	return;    assert(tries);    tries--;    if (tries > MAX_FWD_STATS_IDX)	tries = MAX_FWD_STATS_IDX;    FwdReplyCodes[tries][status]++;}static voidfwdStats(StoreEntry * s){    int i;    int j;    storeAppendPrintf(s, "Status");    for (j = 0; j <= MAX_FWD_STATS_IDX; j++) {	storeAppendPrintf(s, "\ttry#%d", j + 1);    }    storeAppendPrintf(s, "\n");    for (i = 0; i <= (int) HTTP_INVALID_HEADER; i++) {	if (FwdReplyCodes[0][i] == 0)	    continue;	storeAppendPrintf(s, "%3d", i);	for (j = 0; j <= MAX_FWD_STATS_IDX; j++) {	    storeAppendPrintf(s, "\t%d", FwdReplyCodes[j][i]);	}	storeAppendPrintf(s, "\n");    }}intfwdReforwardableStatus(http_status s){    switch (s) {    case HTTP_FORBIDDEN:    case HTTP_INTERNAL_SERVER_ERROR:    case HTTP_NOT_IMPLEMENTED:    case HTTP_BAD_GATEWAY:    case HTTP_SERVICE_UNAVAILABLE:    case HTTP_GATEWAY_TIMEOUT:	return 1;    default:	return 0;    }    /* NOTREACHED */}

⌨️ 快捷键说明

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