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

📄 client_side.c

📁 -
💻 C
📖 第 1 页 / 共 5 页
字号:
	debug(33, 3) ("clientHandleIMSReply: Incomplete headers for '%s'\n", url);	if (size >= CLIENT_SOCK_SZ) {	    /* will not get any bigger than that */	    debug(33, 3) ("clientHandleIMSReply: Reply is too large '%s', using old entry\n", url);	    /* use old entry, this repeats the code abovez */	    http->log_type = LOG_TCP_REFRESH_FAIL_HIT;	    storeUnregister(entry, http);	    storeUnlockObject(entry);	    entry = http->entry = http->old_entry;	    entry->refcount++;	    /* continue */	} else {	    storeClientCopy(entry,		http->out.offset + size,		http->out.offset,		CLIENT_SOCK_SZ,		buf,		clientHandleIMSReply,		http);	    return;	}    } else if (clientGetsOldEntry(entry, http->old_entry, http->request)) {	/* We initiated the IMS request, the client is not expecting	 * 304, so put the good one back.  First, make sure the old entry	 * headers have been loaded from disk. */	oldentry = http->old_entry;	http->log_type = LOG_TCP_REFRESH_HIT;	if (oldentry->mem_obj->request == NULL) {	    oldentry->mem_obj->request = requestLink(mem->request);	    unlink_request = 1;	}	/* Don't memcpy() the whole reply structure here.  For example,	 * www.thegist.com (Netscape/1.13) returns a content-length for	 * 304's which seems to be the length of the 304 HEADERS!!! and	 * not the body they refer to.  */	httpReplyUpdateOnNotModified(oldentry->mem_obj->reply, mem->reply);	storeTimestampsSet(oldentry);	storeUnregister(entry, http);	storeUnlockObject(entry);	entry = http->entry = oldentry;	entry->timestamp = squid_curtime;	if (unlink_request) {	    requestUnlink(entry->mem_obj->request);	    entry->mem_obj->request = NULL;	}    } else {	/* the client can handle this reply, whatever it is */	http->log_type = LOG_TCP_REFRESH_MISS;	if (HTTP_NOT_MODIFIED == mem->reply->sline.status) {	    http->old_entry->timestamp = squid_curtime;	    http->old_entry->refcount++;	    http->log_type = LOG_TCP_REFRESH_HIT;	}	storeUnregister(http->old_entry, http);	storeUnlockObject(http->old_entry);	recopy = 0;    }    http->old_entry = NULL;	/* done with old_entry */    assert(!EBIT_TEST(entry->flags, ENTRY_ABORTED));    if (recopy) {	storeClientCopy(entry,	    http->out.offset,	    http->out.offset,	    CLIENT_SOCK_SZ,	    buf,	    clientSendMoreData,	    http);    } else {	clientSendMoreData(data, buf, size);    }}intmodifiedSince(StoreEntry * entry, request_t * request){    int object_length;    MemObject *mem = entry->mem_obj;    time_t mod_time = entry->lastmod;    debug(33, 3) ("modifiedSince: '%s'\n", storeUrl(entry));    if (mod_time < 0)	mod_time = entry->timestamp;    debug(33, 3) ("modifiedSince: mod_time = %d\n", (int) mod_time);    if (mod_time < 0)	return 1;    /* Find size of the object */    object_length = mem->reply->content_length;    if (object_length < 0)	object_length = contentLen(entry);    if (mod_time > request->ims) {	debug(33, 3) ("--> YES: entry newer than client\n");	return 1;    } else if (mod_time < request->ims) {	debug(33, 3) ("-->  NO: entry older than client\n");	return 0;    } else if (request->imslen < 0) {	debug(33, 3) ("-->  NO: same LMT, no client length\n");	return 0;    } else if (request->imslen == object_length) {	debug(33, 3) ("-->  NO: same LMT, same length\n");	return 0;    } else {	debug(33, 3) ("--> YES: same LMT, different length\n");	return 1;    }}voidclientPurgeRequest(clientHttpRequest * http){    StoreEntry *entry;    ErrorState *err = NULL;    HttpReply *r;    debug(33, 3) ("Config.onoff.enable_purge = %d\n", Config.onoff.enable_purge);    if (!Config.onoff.enable_purge) {	http->log_type = LOG_TCP_DENIED;	err = errorCon(ERR_ACCESS_DENIED, HTTP_FORBIDDEN);	err->request = requestLink(http->request);	err->src_addr = http->conn->peer.sin_addr;	http->entry = clientCreateStoreEntry(http, http->request->method, null_request_flags);	errorAppendEntry(http->entry, err);	return;    }    http->log_type = LOG_TCP_MISS;    if ((entry = storeGetPublic(http->uri, METHOD_GET)) == NULL) {	http->http_code = HTTP_NOT_FOUND;    } else {	storeRelease(entry);	http->http_code = HTTP_OK;    }    debug(33, 4) ("clientPurgeRequest: Not modified '%s'\n",	storeUrl(entry));    /*     * Make a new entry to hold the reply to be written     * to the client.     */    http->entry = clientCreateStoreEntry(http, http->request->method, null_request_flags);    httpReplyReset(r = http->entry->mem_obj->reply);    httpReplySetHeaders(r, 1.0, http->http_code, NULL, NULL, 0, 0, -1);    httpReplySwapOut(r, http->entry);    storeComplete(http->entry);}intcheckNegativeHit(StoreEntry * e){    if (!EBIT_TEST(e->flags, ENTRY_NEGCACHED))	return 0;    if (e->expires <= squid_curtime)	return 0;    if (e->store_status != STORE_OK)	return 0;    return 1;}voidclientUpdateCounters(clientHttpRequest * http){    int svc_time = tvSubMsec(http->start, current_time);    ping_data *i;    HierarchyLogEntry *H;    Counter.client_http.requests++;    if (isTcpHit(http->log_type))	Counter.client_http.hits++;    if (http->request->err_type != ERR_NONE)	Counter.client_http.errors++;    statHistCount(&Counter.client_http.all_svc_time, svc_time);    /*     * The idea here is not to be complete, but to get service times     * for only well-defined types.  For example, we don't include     * LOG_TCP_REFRESH_FAIL_HIT because its not really a cache hit     * (we *tried* to validate it, but failed).     */    switch (http->log_type) {    case LOG_TCP_REFRESH_HIT:	statHistCount(&Counter.client_http.nh_svc_time, svc_time);	break;    case LOG_TCP_IMS_HIT:	statHistCount(&Counter.client_http.nm_svc_time, svc_time);	break;    case LOG_TCP_HIT:    case LOG_TCP_MEM_HIT:    case LOG_TCP_OFFLINE_HIT:	statHistCount(&Counter.client_http.hit_svc_time, svc_time);	break;    case LOG_TCP_MISS:    case LOG_TCP_CLIENT_REFRESH_MISS:	statHistCount(&Counter.client_http.miss_svc_time, svc_time);	break;    default:	/* make compiler warnings go away */	break;    }    H = &http->request->hier;    switch (H->alg) {    case PEER_SA_DIGEST:	Counter.cd.times_used++;	break;    case PEER_SA_ICP:	Counter.icp.times_used++;	i = &H->ping;	if (0 != i->stop.tv_sec && 0 != i->start.tv_sec)	    statHistCount(&Counter.icp.query_svc_time,		tvSubUsec(i->start, i->stop));	if (i->timeout)	    Counter.icp.query_timeouts++;	break;    case PEER_SA_NETDB:	Counter.netdb.times_used++;	break;    default:	break;    }}static voidhttpRequestFree(void *data){    clientHttpRequest *http = data;    clientHttpRequest **H;    ConnStateData *conn = http->conn;    StoreEntry *e;    request_t *request = http->request;    MemObject *mem = NULL;    debug(33, 3) ("httpRequestFree: %s\n", storeUrl(http->entry));    if (!clientCheckTransferDone(http)) {	if ((e = http->entry)) {	    http->entry = NULL;	    storeUnregister(e, http);	    storeUnlockObject(e);	}	if (http->entry && http->entry->ping_status == PING_WAITING)	    storeReleaseRequest(http->entry);    }    assert(http->log_type < LOG_TYPE_MAX);    if (http->entry)	mem = http->entry->mem_obj;    if (http->out.size || http->log_type) {	http->al.icp.opcode = ICP_INVALID;	http->al.url = http->log_uri;	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 = strBuf(mem->reply->content_type);	}	http->al.cache.caddr = conn->log_addr;	http->al.cache.size = http->out.size;	http->al.cache.code = http->log_type;	http->al.cache.msec = tvSubMsec(http->start, current_time);	if (request->user_ident[0])	    http->al.cache.ident = request->user_ident;	else	    http->al.cache.ident = conn->ident;	if (request) {	    Packer p;	    MemBuf mb;	    memBufDefInit(&mb);	    packerToMemInit(&p, &mb);	    httpHeaderPackInto(&request->header, &p);	    http->al.http.method = request->method;	    http->al.http.version = request->http_ver;	    http->al.headers.request = xstrdup(mb.buf);	    http->al.hier = request->hier;	    packerClean(&p);	    memBufClean(&mb);	}	accessLogLog(&http->al);	clientUpdateCounters(http);	clientdbUpdate(conn->peer.sin_addr, http->log_type, PROTO_HTTP, http->out.size);    }    if (http->acl_checklist)	aclChecklistFree(http->acl_checklist);    if (request)	checkFailureRatio(request->err_type, http->al.hier.code);    safe_free(http->uri);    safe_free(http->log_uri);    safe_free(http->al.headers.request);    safe_free(http->al.headers.reply);    safe_free(http->redirect.location);    stringClean(&http->range_iter.boundary);    if ((e = http->entry)) {	http->entry = NULL;	storeUnregister(e, http);	storeUnlockObject(e);    }    /* old_entry might still be set if we didn't yet get the reply     * code in clientHandleIMSReply() */    if ((e = http->old_entry)) {	http->old_entry = NULL;	storeUnregister(e, http);	storeUnlockObject(e);    }    requestUnlink(http->request);    assert(http != http->next);    assert(http->conn->chr != NULL);    H = &http->conn->chr;    while (*H) {	if (*H == http)	    break;	H = &(*H)->next;    }    assert(*H != NULL);    *H = http->next;    http->next = NULL;    dlinkDelete(&http->active, &ClientActiveRequests);    cbdataFree(http);}/* This is a handler normally called by comm_close() */static voidconnStateFree(int fd, void *data){    ConnStateData *connState = data;    clientHttpRequest *http;    debug(33, 3) ("connStateFree: FD %d\n", fd);    assert(connState != NULL);    while ((http = connState->chr) != NULL) {	assert(http->conn == connState);	assert(connState->chr != connState->chr->next);	httpRequestFree(http);    }    safe_free(connState->in.buf);    /* XXX account connState->in.buf */    pconnHistCount(0, connState->nrequests);    cbdataFree(connState);#ifdef _SQUID_LINUX_    /* prevent those nasty RST packets */    {	char buf[SQUID_TCP_SO_RCVBUF];	while (read(fd, buf, SQUID_TCP_SO_RCVBUF) > 0);    }#endif}static voidclientInterpretRequestHeaders(clientHttpRequest * http){    request_t *request = http->request;    const HttpHeader *req_hdr = &request->header;    int no_cache = 0;#if USE_USERAGENT_LOG    const char *str;#endif    request->imslen = -1;    request->ims = httpHeaderGetTime(req_hdr, HDR_IF_MODIFIED_SINCE);    if (request->ims > 0)	request->flags.ims = 1;    if (httpHeaderHas(req_hdr, HDR_PRAGMA)) {	String s = httpHeaderGetList(req_hdr, HDR_PRAGMA);	if (strListIsMember(&s, "no-cache", ','))	    no_cache++;	stringClean(&s);    }    if (request->cache_control)	if (EBIT_TEST(request->cache_control->mask, CC_NO_CACHE))	    no_cache++;    if (no_cache) {#if HTTP_VIOLATIONS	if (Config.onoff.reload_into_ims)	    request->flags.nocache_hack = 1;	else if (refresh_nocache_hack)	    request->flags.nocache_hack = 1;	else#endif	    request->flags.nocache = 1;    }    /* ignore range header in non-GETs */    if (request->method == METHOD_GET) {	request->range = httpHeaderGetRange(req_hdr);	if (request->range)	    request->flags.range = 1;    }    if (httpHeaderHas(req_hdr, HDR_AUTHORIZATION))	request->flags.auth = 1;    if (request->login[0] != '\0')	request->flags.auth = 1;    if (httpHeaderHas(req_hdr, HDR_VIA)) {	String s = httpHeaderGetList(req_hdr, HDR_VIA);	/*	 * ThisCache cannot be a member of Via header, "1.0 ThisCache" can.	 * Note ThisCache2 has a space prepended to the hostname so we don't	 * accidentally match super-domains.	 */	if (strListIsSubstr(&s, ThisCache2, ',')) {	    debugObj(33, 1, "WARNING: Forwarding loop detected for:\n",		request, (ObjPackMethod) & httpRequestPack);	    request->flags.loopdetect = 1;	}#if FORW_VIA_DB	fvdbCountVia(strBuf(s));#endif	stringClean(&s);    }#if USE_USERAGENT_LOG    if ((str = httpHeaderGetStr(req_hdr, HDR_USER_AGENT)))	logUserAgent(fqdnFromAddr(http->conn->peer.sin_addr), str);#endif#if FORW_VIA_DB    if (httpHeaderHas(req_hdr, HDR_X_FORWARDED_FOR)) {	String s = httpHeaderGetList(req_hdr, HDR_X_FORWARDED_FOR);	fvdbCountForw(strBuf(s));	stringClean(&s);    }

⌨️ 快捷键说明

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