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

📄 errorpage.c

📁 -
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $Id: errorpage.c,v 1.148.2.2 1999/06/19 16:16:06 wessels Exp $ * * DEBUG: section 4     Error Generation * AUTHOR: Duane Wessels * * 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. * *//* * Abstract:  These routines are used to generate error messages to be *              sent to clients.  The error type is used to select between *              the various message formats. (formats are stored in the *              Config.errorDirectory) */#include "squid.h"/* local types */typedef struct {    int id;    char *page_name;} ErrorDynamicPageInfo;/* local constant and vars */static const char *const proxy_auth_challenge_fmt = "Basic realm=\"%s\"";/* * note: hard coded error messages are not appended with %S automagically * to give you more control on the format */static const struct {    int type;			/* and page_id */    const char *text;} error_hard_text[] = {    {	ERR_SQUID_SIGNATURE,	    "\n<br clear=\"all\">\n"	    "<hr noshade size=1>\n"	    "Generated %T by %h (<a href=\"http://squid.nlanr.net/Squid/\">%s</a>)\n"	    "</BODY></HTML>\n"    }};static Stack ErrorDynamicPages;/* local prototypes */static const int error_hard_text_count = sizeof(error_hard_text) / sizeof(*error_hard_text);static char **error_text = NULL;static int error_page_count = 0;static char *errorTryLoadText(const char *page_name, const char *dir);static char *errorLoadText(const char *page_name);static const char *errorFindHardText(err_type type);static ErrorDynamicPageInfo *errorDynamicPageInfoCreate(int id, const char *page_name);static void errorDynamicPageInfoDestroy(ErrorDynamicPageInfo * info);static MemBuf errorBuildContent(ErrorState * err);static const char *errorConvert(char token, ErrorState * err);static CWCB errorSendComplete;/* * Function:  errorInitialize * * Abstract:  This function finds the error messages formats, and stores *            them in error_text[]; * * Global effects: *            error_text[] - is modified */voiderrorInitialize(void){    err_type i;    const char *text;    error_page_count = ERR_MAX + ErrorDynamicPages.count;    error_text = xcalloc(error_page_count, sizeof(char *));    for (i = ERR_NONE, i++; i < error_page_count; i++) {	safe_free(error_text[i]);	/* hard-coded ? */	if ((text = errorFindHardText(i)))	    error_text[i] = xstrdup(text);	else if (i < ERR_MAX) {	    /* precompiled ? */	    error_text[i] = errorLoadText(err_type_str[i]);	} else {	    /* dynamic */	    ErrorDynamicPageInfo *info = ErrorDynamicPages.items[i - ERR_MAX];	    assert(info && info->id == i && info->page_name);	    error_text[i] = errorLoadText(info->page_name);	}	assert(error_text[i]);    }}voiderrorClean(void){    if (error_text) {	int i;	for (i = ERR_NONE + 1; i < error_page_count; i++)	    safe_free(error_text[i]);	safe_free(error_text);    }    while (ErrorDynamicPages.count)	errorDynamicPageInfoDestroy(stackPop(&ErrorDynamicPages));    error_page_count = 0;}static const char *errorFindHardText(err_type type){    int i;    for (i = 0; i < error_hard_text_count; i++)	if (error_hard_text[i].type == type)	    return error_hard_text[i].text;    return NULL;}static char *errorLoadText(const char *page_name){    /* test configured location */    char *text = errorTryLoadText(page_name, Config.errorDirectory);    /* test default location if failed */    if (!text && strcmp(Config.errorDirectory, DEFAULT_SQUID_ERROR_DIR))	text = errorTryLoadText(page_name, DEFAULT_SQUID_ERROR_DIR);    /* giving up if failed */    if (!text)	fatal("failed to find or read error text file.");    return text;}static char *errorTryLoadText(const char *page_name, const char *dir){    int fd;    char path[MAXPATHLEN];    struct stat sb;    char *text;    snprintf(path, sizeof(path), "%s/%s", dir, page_name);    fd = file_open(path, O_RDONLY, NULL, NULL, NULL);    if (fd < 0 || fstat(fd, &sb) < 0) {	debug(4, 0) ("errorTryLoadText: '%s': %s\n", path, xstrerror());	if (fd >= 0)	    file_close(fd);	return NULL;    }    text = xcalloc(sb.st_size + 2 + 1, 1);	/* 2 == space for %S */    if (read(fd, text, sb.st_size) != sb.st_size) {	debug(4, 0) ("errorTryLoadText: failed to fully read: '%s': %s\n",	    path, xstrerror());	xfree(text);	text = NULL;    }    file_close(fd);    if (strstr(text, "%s") == NULL)	strcat(text, "%S");	/* add signature */    return text;}static ErrorDynamicPageInfo *errorDynamicPageInfoCreate(int id, const char *page_name){    ErrorDynamicPageInfo *info = xcalloc(1, sizeof(ErrorDynamicPageInfo));    info->id = id;    info->page_name = xstrdup(page_name);    return info;}static voiderrorDynamicPageInfoDestroy(ErrorDynamicPageInfo * info){    assert(info);    xfree(info->page_name);    xfree(info);}interrorReservePageId(const char *page_name){    ErrorDynamicPageInfo *info =    errorDynamicPageInfoCreate(ERR_MAX + ErrorDynamicPages.count, page_name);    stackPush(&ErrorDynamicPages, info);    return info->id;}static const char *errorPageName(int pageId){    if (pageId >= ERR_NONE && pageId < ERR_MAX)		/* common case */	return err_type_str[pageId];    if (pageId >= ERR_MAX && pageId - ERR_MAX < ErrorDynamicPages.count)	return ((ErrorDynamicPageInfo *) ErrorDynamicPages.	    items[pageId - ERR_MAX])->page_name;    return "ERR_UNKNOWN";	/* should not happen */}/* * Function:  errorCon * * Abstract:  This function creates a ErrorState object. */ErrorState *errorCon(err_type type, http_status status){    ErrorState *err = memAllocate(MEM_ERRORSTATE);    err->page_id = type;	/* has to be reset manually if needed */    err->type = type;    err->http_status = status;    return err;}/* * Function:  errorAppendEntry * * 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 stores the text in the specified store *            entry.  This function should only be called by ``server *            side routines'' which need to communicate errors to the *            client side.  It should also be called from client_side.c *            because we now support persistent connections, and *            cannot assume that we can immediately write to the socket *            for an error. */voiderrorAppendEntry(StoreEntry * entry, ErrorState * err){    HttpReply *rep;    MemObject *mem = entry->mem_obj;    assert(mem != NULL);    assert(mem->inmem_hi == 0);    if (entry->store_status != STORE_PENDING) {	/*	 * If the entry is not STORE_PENDING, then no clients	 * care about it, and we don't need to generate an	 * error message	 */	assert(EBIT_TEST(entry->flags, ENTRY_ABORTED));	assert(mem->nclients == 0);	errorStateFree(err);	return;    }    storeLockObject(entry);    storeBuffer(entry);    rep = errorBuildReply(err);    /* Add authentication header */    switch (err->http_status) {    case HTTP_PROXY_AUTHENTICATION_REQUIRED:	/* Proxy authorisation needed */	httpHeaderPutStrf(&rep->header, HDR_PROXY_AUTHENTICATE,	    proxy_auth_challenge_fmt, Config.proxyAuthRealm);	break;    case HTTP_UNAUTHORIZED:	/* WWW Authorisation needed */	httpHeaderPutStrf(&rep->header, HDR_WWW_AUTHENTICATE,	    proxy_auth_challenge_fmt, Config.proxyAuthRealm);	break;    default:	/* Keep GCC happy */	break;    }    httpReplySwapOut(rep, entry);    httpReplyDestroy(rep);    mem->reply->sline.status = err->http_status;    mem->reply->content_length = -1;    EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT);    storeBufferFlush(entry);    storeComplete(entry);

⌨️ 快捷键说明

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