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

📄 errorpage.c

📁 -
💻 C
📖 第 1 页 / 共 2 页
字号:
    storeNegativeCache(entry);    storeReleaseRequest(entry);    storeUnlockObject(entry);    errorStateFree(err);}/* * Function:  errorSend * * Arguments: err - This object is destroyed after use in this function. * * Abstract:  This function generates a error page from the info contained *            by 'err' and then sends it to the client. *            The callback function errorSendComplete() is called after *            the page has been written to the client socket (fd). *            errorSendComplete() deallocates 'err'.  We need to add *            'err' to the cbdata because comm_write() requires it *            for all callback data pointers. * *            Note, normally errorSend() should only be called from *            routines in ssl.c and pass.c, where we don't have any *            StoreEntry's.  In client_side.c we must allocate a StoreEntry *            for errors and use errorAppendEntry() to account for *            persistent/pipeline connections. */voiderrorSend(int fd, ErrorState * err){    HttpReply *rep;    debug(4, 3) ("errorSend: FD %d, err=%p\n", fd, err);    assert(fd >= 0);    /*     * ugh, this is how we make sure error codes get back to     * the client side for logging and error tracking.     */    if (err->request)	err->request->err_type = err->type;    /* moved in front of errorBuildBuf @?@ */    err->flags.flag_cbdata = 1;    cbdataAdd(err, memFree, MEM_ERRORSTATE);    rep = errorBuildReply(err);    comm_write_mbuf(fd, httpReplyPack(rep), errorSendComplete, err);    httpReplyDestroy(rep);}/* * Function:  errorSendComplete * * Abstract:  Called by commHandleWrite() after data has been written *            to the client socket. * * Note:      If there is a callback, the callback is responsible for *            closeing the FD, otherwise we do it ourseves. */static voiderrorSendComplete(int fd, char *bufnotused, size_t size, int errflag, void *data){    ErrorState *err = data;    debug(4, 3) ("errorSendComplete: FD %d, size=%d\n", fd, size);    if (errflag != COMM_ERR_CLOSING) {	if (err->callback)	    err->callback(fd, err->callback_data, size);	else	    comm_close(fd);    }    errorStateFree(err);}voiderrorStateFree(ErrorState * err){    requestUnlink(err->request);    safe_free(err->redirect_url);    safe_free(err->url);    safe_free(err->host);    safe_free(err->dnsserver_msg);    safe_free(err->request_hdrs);    if (err->flags.flag_cbdata)	cbdataFree(err);    else	memFree(err, MEM_ERRORSTATE);}#define CVT_BUF_SZ 512/* * B - URL with FTP %2f hack                    x * c - Squid error code                         x * d - seconds elapsed since request received   x * e - errno                                    x * E - strerror()                               x * f - FTP request line                         x * F - FTP reply line                           x * g - FTP server message                       x * h - cache hostname                           x * H - server host name                         x * i - client IP address                        x * I - server IP address                        x * L - HREF link for more info/contact          x * M - Request Method                           x * p - URL port #                               x * P - Protocol                                 x * R - Full HTTP Request                        x * S - squid signature from ERR_SIGNATURE       x * s - caching proxy software with version      x * t - local time                               x * T - UTC                                      x * U - URL without password                     x * u - URL without password, %2f added to path  x * w - cachemgr email address                   x * z - dns server error message                 x */static const char *errorConvert(char token, ErrorState * err){    request_t *r = err->request;    static MemBuf mb = MemBufNULL;    const char *p = NULL;	/* takes priority over mb if set */    memBufReset(&mb);    switch (token) {    case 'B':	p = r ? ftpUrlWith2f(r) : "[no URL]";	break;    case 'e':	memBufPrintf(&mb, "%d", err->xerrno);	break;    case 'E':	if (err->xerrno)	    memBufPrintf(&mb, "(%d) %s", err->xerrno, strerror(err->xerrno));	else	    memBufPrintf(&mb, "[No Error]");	break;    case 'f':	/* FTP REQUEST LINE */	if (err->ftp.request)	    p = err->ftp.request;	else	    p = "nothing";	break;    case 'F':	/* FTP REPLY LINE */	if (err->ftp.request)	    p = err->ftp.reply;	else	    p = "nothing";	break;    case 'g':	/* FTP SERVER MESSAGE */	wordlistCat(err->ftp_server_msg, &mb);	break;    case 'h':	memBufPrintf(&mb, "%s", getMyHostname());	break;    case 'H':	p = r ? r->host : "[unknown host]";	break;    case 'i':	memBufPrintf(&mb, "%s", inet_ntoa(err->src_addr));	break;    case 'I':	if (err->host) {	    memBufPrintf(&mb, "%s", err->host);	} else	    p = "[unknown]";	break;    case 'L':	if (Config.errHtmlText) {	    memBufPrintf(&mb, "%s", Config.errHtmlText);	} else	    p = "[not available]";	break;    case 'M':	p = r ? RequestMethodStr[r->method] : "[unkown method]";	break;    case 'p':	if (r) {	    memBufPrintf(&mb, "%d", (int) r->port);	} else {	    p = "[unknown port]";	}	break;    case 'P':	p = r ? ProtocolStr[r->protocol] : "[unkown protocol]";	break;    case 'R':	if (NULL != r) {	    Packer p;	    memBufPrintf(&mb, "%s %s HTTP/%3.1f\n",		RequestMethodStr[r->method],		strLen(r->urlpath) ? strBuf(r->urlpath) : "/",		(double) r->http_ver);	    packerToMemInit(&p, &mb);	    httpHeaderPackInto(&r->header, &p);	    packerClean(&p);	} else if (err->request_hdrs) {	    p = err->request_hdrs;	} else {	    p = "[no request]";	}	break;    case 's':	p = full_appname_string;	break;    case 'S':	/* signature may contain %-escapes, recursion */	if (err->page_id != ERR_SQUID_SIGNATURE) {	    const int saved_id = err->page_id;	    MemBuf sign_mb;	    err->page_id = ERR_SQUID_SIGNATURE;	    sign_mb = errorBuildContent(err);	    memBufPrintf(&mb, "%s", sign_mb.buf);	    memBufClean(&sign_mb);	    err->page_id = saved_id;	} else {	    /* wow, somebody put %S into ERR_SIGNATURE, stop recursion */	    p = "[%S]";	}	break;    case 't':	memBufPrintf(&mb, "%s", mkhttpdlogtime(&squid_curtime));	break;    case 'T':	memBufPrintf(&mb, "%s", mkrfc1123(squid_curtime));	break;    case 'U':	p = r ? urlCanonicalClean(r) : err->url ? err->url : "[no URL]";	break;    case 'w':	if (Config.adminEmail)	    memBufPrintf(&mb, "%s", Config.adminEmail);	else	    p = "[unknown]";	break;    case 'z':	if (err->dnsserver_msg)	    p = err->dnsserver_msg;	else	    p = "[unknown]";	break;    case '%':	p = "%";	break;    default:	memBufPrintf(&mb, "%%%c", token);	break;    }    if (!p)	p = mb.buf;		/* do not use mb after this assignment! */    assert(p);    debug(4, 3) ("errorConvert: %%%c --> '%s'\n", token, p);    return p;}/* allocates and initializes an error response */HttpReply *errorBuildReply(ErrorState * err){    HttpReply *rep = httpReplyCreate();    MemBuf content = errorBuildContent(err);    /* no LMT for error pages; error pages expire immediately */    httpReplySetHeaders(rep, 1.0, err->http_status, NULL, "text/html", content.size, 0, squid_curtime);    /*     * include some information for downstream caches. Implicit     * replaceable content. This isn't quite sufficient. xerrno is not     * necessarily meaningful to another system, so we really should     * expand it. Additionally, we should identify ourselves. Someone     * might want to know. Someone _will_ want to know OTOH, the first     * X-CACHE-MISS entry should tell us who.     */    httpHeaderPutStrf(&rep->header, HDR_X_SQUID_ERROR, "%s %d",	errorPageName(err->page_id), err->xerrno);    httpBodySet(&rep->body, &content);    /* do not memBufClean() the content, it was absorbed by httpBody */    return rep;}static MemBuferrorBuildContent(ErrorState * err){    MemBuf content;    const char *m;    const char *p;    const char *t;    assert(err != NULL);    assert(err->page_id > ERR_NONE && err->page_id < error_page_count);    memBufDefInit(&content);    m = error_text[err->page_id];    assert(m);    while ((p = strchr(m, '%'))) {	memBufAppend(&content, m, p - m);	/* copy */	t = errorConvert(*++p, err);	/* convert */	memBufPrintf(&content, "%s", t);	/* copy */	m = p + 1;		/* advance */    }    if (*m)	memBufPrintf(&content, "%s", m);	/* copy tail */    assert(content.size == strlen(content.buf));    return content;}

⌨️ 快捷键说明

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