From: wessels <> Date: Mon, 28 Jul 1997 12:40:50 +0000 (+0000) Subject: mostly working customizable error messages. lots of blanks to fill in though X-Git-Tag: SQUID_3_0_PRE1~4849 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9b312a1927a9c6945fe8db7c97712d111e31af1d;p=thirdparty%2Fsquid.git mostly working customizable error messages. lots of blanks to fill in though --- diff --git a/src/Makefile.in b/src/Makefile.in index cc30a938f5..1a0d0b7c83 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,7 +1,7 @@ # # Makefile for the Squid Object Cache server # -# $Id: Makefile.in,v 1.83 1997/07/19 01:33:53 wessels Exp $ +# $Id: Makefile.in,v 1.84 1997/07/28 06:40:50 wessels Exp $ # # Uncomment and customize the following to suit your needs: # @@ -42,6 +42,7 @@ DEFAULT_SWAP_DIR = $(localstatedir)/cache DEFAULT_PINGER = $(libexecdir)/pinger DEFAULT_UNLINKD = $(libexecdir)/unlinkd DEFAULT_ICON_DIR = $(sysconfdir)/icons +DEFAULT_ERROR_DIR = $(sysconfdir)/errors CC = @CC@ MAKEDEPEND = @MAKEDEPEND@ @@ -180,7 +181,8 @@ cf.data: cf.data.pre Makefile s%@DEFAULT_STORE_LOG@%$(DEFAULT_STORE_LOG)%g;\ s%@DEFAULT_PID_FILE@%$(DEFAULT_PID_FILE)%g;\ s%@DEFAULT_SWAP_DIR@%$(DEFAULT_SWAP_DIR)%g;\ - s%@DEFAULT_ICON_DIR@%$(DEFAULT_ICON_DIR)%g" < cf.data.pre >$@ + s%@DEFAULT_ICON_DIR@%$(DEFAULT_ICON_DIR)%g;\ + s%@DEFAULT_ERROR_DIR@%$(DEFAULT_ERROR_DIR)%g" < cf.data.pre >$@ install-mkdirs: -@if test ! -d $(prefix); then \ diff --git a/src/cf.data.pre b/src/cf.data.pre index c4946c25da..8e1e00ab2a 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -1862,6 +1862,14 @@ DOC_START XXX DOC_END +NAME: error_directory +TYPE: pathname_stat +LOC: Config.errorDirectory +DEFAULT: @DEFAULT_ERROR_DIR@ +DOC_START + XXX +DOC_END + NAME: icon_content_type TYPE: string LOC: Config.icons.content_type diff --git a/src/client.cc b/src/client.cc index 7c128b88f5..c06f08e647 100644 --- a/src/client.cc +++ b/src/client.cc @@ -2,8 +2,9 @@ + /* - * $Id: client.cc,v 1.22 1997/07/19 07:20:01 wessels Exp $ + * $Id: client.cc,v 1.23 1997/07/28 06:40:51 wessels Exp $ * * DEBUG: section 0 WWW Client * AUTHOR: Harvest Derived diff --git a/src/client_db.cc b/src/client_db.cc index 1104ae92ee..6a7f462429 100644 --- a/src/client_db.cc +++ b/src/client_db.cc @@ -1,6 +1,6 @@ /* - * $Id: client_db.cc,v 1.15 1997/07/26 04:48:24 wessels Exp $ + * $Id: client_db.cc,v 1.16 1997/07/28 06:40:52 wessels Exp $ * * DEBUG: section 0 Client Database * AUTHOR: Duane Wessels @@ -36,7 +36,7 @@ typedef struct _client_info { struct client_info *next; struct in_addr addr; struct { - int result_hist[ERR_MAX]; + int result_hist[LOG_TYPE_MAX]; int n_requests; } Http, Icp; } ClientInfo; @@ -118,7 +118,7 @@ clientdbDump(StoreEntry * sentry) storeAppendPrintf(sentry, "{Name: %s}\n", fqdnFromAddr(c->addr)); storeAppendPrintf(sentry, "{ ICP Requests %d}\n", c->Icp.n_requests); - for (l = LOG_TAG_NONE; l < ERR_MAX; l++) { + for (l = LOG_TAG_NONE; l < LOG_TYPE_MAX; l++) { if (c->Icp.result_hist[l] == 0) continue; storeAppendPrintf(sentry, @@ -129,7 +129,7 @@ clientdbDump(StoreEntry * sentry) } storeAppendPrintf(sentry, "{ HTTP Requests %d}\n", c->Http.n_requests); - for (l = LOG_TAG_NONE; l < ERR_MAX; l++) { + for (l = LOG_TAG_NONE; l < LOG_TYPE_MAX; l++) { if (c->Http.result_hist[l] == 0) continue; storeAppendPrintf(sentry, diff --git a/src/client_side.cc b/src/client_side.cc index fcd0f2490e..e24f1f84a7 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -1,6 +1,6 @@ /* - * $Id: client_side.cc,v 1.119 1997/07/26 04:48:25 wessels Exp $ + * $Id: client_side.cc,v 1.120 1997/07/28 06:40:52 wessels Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -129,8 +129,8 @@ clientAccessCheckDone(int answer, void *data) clientHttpRequest *http = data; ConnStateData *conn = http->conn; int fd = conn->fd; - char *buf = NULL; char *redirectUrl = NULL; + ErrorState *err = NULL; debug(33, 5) ("clientAccessCheckDone: '%s' answer=%d\n", http->url, answer); http->acl_checklist = NULL; if (answer) { @@ -142,21 +142,17 @@ clientAccessCheckDone(int answer, void *data) } else { debug(33, 5) ("Access Denied: %s\n", http->url); redirectUrl = aclGetDenyInfoUrl(&Config.denyInfoList, AclMatchedName); + err = xcalloc(1, sizeof(ErrorState)); + err->type = ERR_ACCESS_DENIED; + err->request = requestLink(http->request); + err->src_addr = http->conn->peer.sin_addr; if (redirectUrl) { - http->http_code = 302, - buf = access_denied_redirect(http->http_code, - http->request->method, - http->url, - fd_table[fd].ipaddr, - redirectUrl); + err->http_status = HTTP_MOVED_TEMPORARILY; + err->redirect_url = xstrdup(redirectUrl); } else { - http->http_code = 400; - buf = access_denied_msg(http->http_code, - http->request->method, - http->url, - fd_table[fd].ipaddr); + err->http_status = HTTP_UNAUTHORIZED; } - icpSendERROR(fd, LOG_TCP_DENIED, buf, http, http->http_code); + errorSend(fd, err); } } @@ -406,8 +402,7 @@ icpHandleIMSReply(void *data, char *buf, ssize_t size) debug(33, 3) ("icpHandleIMSReply: FD %d '%s'\n", fd, entry->url); /* unregister this handler */ if (entry->store_status == STORE_ABORTED) { - debug(33, 3) ("icpHandleIMSReply: ABORTED/%s '%s'\n", - log_tags[entry->mem_obj->abort_code], entry->url); + debug(33, 3) ("icpHandleIMSReply: ABORTED '%s'\n", entry->url); /* We have an existing entry, but failed to validate it */ if (BIT_SET(entry->flag, ENTRY_REVALIDATE)) { /* We can't send the old one, so send the abort message */ @@ -416,7 +411,7 @@ icpHandleIMSReply(void *data, char *buf, ssize_t size) storeUnlockObject(http->old_entry); } else { /* Its okay to send the old one anyway */ - http->log_type = entry->mem_obj->abort_code; + http->log_type = LOG_TCP_REFRESH_FAIL_HIT; storeUnregister(entry, http); storeUnlockObject(entry); entry = http->entry = http->old_entry; @@ -542,38 +537,29 @@ clientConstructTraceEcho(clientHttpRequest * http) void clientPurgeRequest(clientHttpRequest * http) { - char *buf; int fd = http->conn->fd; - LOCAL_ARRAY(char, msg, 8192); - LOCAL_ARRAY(char, line, 256); + char *msg; StoreEntry *entry; - debug(0, 0) ("Config.onoff.enable_purge = %d\n", Config.onoff.enable_purge); + ErrorState *err = NULL; + debug(33, 3) ("Config.onoff.enable_purge = %d\n", Config.onoff.enable_purge); if (!Config.onoff.enable_purge) { - buf = access_denied_msg(http->http_code = 401, - http->request->method, - http->url, - fd_table[fd].ipaddr); - icpSendERROR(fd, LOG_TCP_DENIED, buf, http, http->http_code); + err = xcalloc(1, sizeof(ErrorState)); + err->type = ERR_ACCESS_DENIED; + err->request = requestLink(http->request); + err->src_addr = http->conn->peer.sin_addr; + err->http_status = HTTP_UNAUTHORIZED; + errorSend(fd, err); return; } http->log_type = LOG_TCP_MISS; if ((entry = storeGet(http->url)) == NULL) { - sprintf(msg, "HTTP/1.0 404 Not Found\r\n"); - http->http_code = 404; + http->http_code = HTTP_NOT_FOUND; } else { storeRelease(entry); - sprintf(msg, "HTTP/1.0 200 OK\r\n"); - http->http_code = 200; + http->http_code = HTTP_OK; } - sprintf(line, "Date: %s\r\n", mkrfc1123(squid_curtime)); - strcat(msg, line); - sprintf(line, "Server: Squid/%s\r\n", SQUID_VERSION); - strcat(msg, line); - strcat(msg, "\r\n"); - comm_write(fd, - msg, - strlen(msg), - icpSendERRORComplete, - http, - NULL); + msg = httpReplyHeader(1.0, http->http_code, NULL, 0, 0, -1); + if (strlen(msg) < 8190) + strcat(msg, "\r\n"); + comm_write(fd, xstrdup(msg), strlen(msg), clientWriteComplete, http, xfree); } diff --git a/src/defines.h b/src/defines.h index 659945d39c..2841cc42a6 100644 --- a/src/defines.h +++ b/src/defines.h @@ -27,7 +27,6 @@ #define COMM_OK (0) #define COMM_ERROR (-1) -#define COMM_NO_HANDLER (-2) #define COMM_NOMESSAGE (-3) #define COMM_TIMEOUT (-4) #define COMM_SHUTDOWN (-5) @@ -55,7 +54,6 @@ #define DISK_OK (0) #define DISK_ERROR (-1) #define DISK_EOF (-2) -#define DISK_FILE_NOT_FOUND (-5) #define DISK_NO_SPACE_LEFT (-6) #define DNS_FLAG_ALIVE 0x01 @@ -72,7 +70,6 @@ #define FQDN_BLOCKING_LOOKUP 0x01 #define FQDN_LOOKUP_IF_MISS 0x02 -#define FQDN_LOCK_ENTRY 0x04 #define FQDN_MAX_NAMES 5 @@ -108,10 +105,6 @@ #define ANONYMIZER_STANDARD 1 #define ANONYMIZER_PARANOID 2 -#define ERR_MIN ERR_READ_TIMEOUT -#define ERR_MAX ERR_PROXY_DENIED - - #define ICP_IDENT_SZ 64 #define IDENT_NONE 0 #define IDENT_PENDING 1 @@ -119,7 +112,6 @@ #define IP_BLOCKING_LOOKUP 0x01 #define IP_LOOKUP_IF_MISS 0x02 -#define IP_LOCK_ENTRY 0x04 #define IPCACHE_AV_FACTOR 1000 @@ -138,15 +130,7 @@ #define ICP_FLAG_HIT_OBJ 0x80000000ul #define ICP_FLAG_SRC_RTT 0x40000000ul -#define ICP_COMMON_SZ (sizeof(icp_common_t)) -#define ICP_HDR_SZ (sizeof(icp_common_t)+sizeof(u_num32)) - -#define ICP_OP_HIGHEST (ICP_OP_END - 1) /* highest valid opcode */ - -#define ICP_ERROR_MSGLEN 256 /* max size for string, incl '\0' */ - /* Version */ -#define ICP_VERSION_1 1 #define ICP_VERSION_2 2 #define ICP_VERSION_3 3 #define ICP_VERSION_CURRENT ICP_VERSION_2 @@ -155,18 +139,12 @@ #define DIRECT_MAYBE 1 #define DIRECT_YES 2 -#define OUTSIDE_FIREWALL 0 -#define INSIDE_FIREWALL 1 -#define NO_FIREWALL 2 - #define REDIRECT_AV_FACTOR 1000 #define REDIRECT_NONE 0 #define REDIRECT_PENDING 1 #define REDIRECT_DONE 2 -#define REFRESH_ICASE 0x01 - #define CONNECT_PORT 443 #define current_stacksize(stack) ((stack)->top - (stack)->base) @@ -178,7 +156,6 @@ #define SM_PAGE_SIZE 4096 #define DISK_PAGE_SIZE 8192 -#define MIN_PENDING 1 #define MIN_CLIENT 1 #define BIT_SET(flag, bit) ((flag) |= (bit)) @@ -206,7 +183,7 @@ #define ENTRY_CACHABLE (1<<7) #define REFRESH_REQUEST (1<<6) #define RELEASE_REQUEST (1<<5) -#define ABORT_MSG_PENDING (1<<4) +#define ENTRY_UNUSED04 (1<<4) #define DELAY_SENDING (1<<3) #define ENTRY_REVALIDATE (1<<2) #define DELETE_BEHIND (1<<1) @@ -236,17 +213,10 @@ #define PEER_COUNT_EVENT_PENDING 1 #define PEER_COUNTING 2 #define ICP_AUTH_SIZE (2) /* size of authenticator field */ -#define ICP_QUERY_SZ (sizeof(icp_query_t)) -#define ICP_HIT_SZ (sizeof(icp_hit_t)) -#define ICP_MISS_SZ (sizeof(icp_miss_t)) -#define ICP_ERROR_SZ (sizeof(icp_error_t)) -#define ICP_SEND_SZ (sizeof(icp_send_t)) -#define ICP_SENDA_SZ (sizeof(icp_senda_t)) -#define ICP_DATAB_SZ (sizeof(icp_datab_t)) -#define ICP_DATA_SZ (sizeof(icp_databe_t)) -#define ICP_MESSAGE_SZ (sizeof(icp_message_t)) -#define ICP_MESSAGE_SZ (sizeof(icp_message_t)) #define ICON_MENU "anthony-dir.gif" #define ICON_DIRUP "anthony-dirup.gif" #define ICON_LINK "anthony-link.gif" + +#define AUTH_MSG_SZ 4096 +#define HTTP_REPLY_BUF_SZ 4096 diff --git a/src/enums.h b/src/enums.h index 12706af61e..5c0681a0ff 100644 --- a/src/enums.h +++ b/src/enums.h @@ -11,34 +11,41 @@ typedef enum { LOG_TCP_IMS_HIT, /* 7 */ LOG_TCP_IMS_MISS, /* 8 */ LOG_TCP_SWAPFAIL_MISS, /* 9 */ - LOG_TCP_DENIED, /* 10 */ LOG_UDP_HIT, /* 11 */ LOG_UDP_HIT_OBJ, /* 12 */ LOG_UDP_MISS, /* 13 */ LOG_UDP_DENIED, /* 14 */ LOG_UDP_INVALID, /* 15 */ LOG_UDP_MISS_NOFETCH, /* 16 */ - ERR_READ_TIMEOUT, /* 17 */ - ERR_LIFETIME_EXP, /* 18 */ - ERR_NO_CLIENTS_BIG_OBJ, /* 19 */ - ERR_READ_ERROR, /* 20 */ - ERR_WRITE_ERROR, /* 21 */ - ERR_CLIENT_ABORT, /* 22 */ - ERR_CONNECT_FAIL, /* 23 */ - ERR_INVALID_REQ, /* 24 */ - ERR_UNSUP_REQ, /* 25 */ - ERR_INVALID_URL, /* 26 */ - ERR_NO_FDS, /* 27 */ - ERR_DNS_FAIL, /* 28 */ - ERR_NOT_IMPLEMENTED, /* 29 */ - ERR_CANNOT_FETCH, /* 30 */ - ERR_NO_RELAY, /* 31 */ - ERR_DISK_IO, /* 32 */ - ERR_ZERO_SIZE_OBJECT, /* 33 */ - ERR_FTP_DISABLED, /* 34 */ - ERR_PROXY_DENIED /* 35 */ + LOG_TYPE_MAX } log_type; +typedef enum { + ERR_NONE, + ERR_READ_TIMEOUT, + ERR_LIFETIME_EXP, + ERR_NO_CLIENTS, + ERR_READ_ERROR, + ERR_WRITE_ERROR, + ERR_CLIENT_ABORT, + ERR_CONNECT_FAIL, + ERR_INVALID_REQ, + ERR_UNSUP_REQ, + ERR_INVALID_URL, + ERR_SOCKET_FAILURE, + ERR_DNS_FAIL, + ERR_NOT_IMPLEMENTED, + ERR_CANNOT_FORWARD, + ERR_NO_RELAY, + ERR_DISK_IO, + ERR_ZERO_SIZE_OBJECT, + ERR_FTP_DISABLED, + ERR_PROXY_DENIED, + ERR_CACHE_MISS_DENIED, + ERR_ACCESS_DENIED, + ERR_MAX +} err_type; + typedef enum { ACL_NONE, ACL_SRC_IP, @@ -236,3 +243,43 @@ typedef enum { PROTO_ICP, PROTO_MAX } protocol_t; + +typedef enum { + HTTP_CONTINUE = 100, + HTTP_SWITCHING_PROTOCOLS = 101, + HTTP_OK = 200, + HTTP_CREATED = 201, + HTTP_ACCEPTED = 202, + HTTP_NON_AUTHORITATIVE_INFORMATION = 203, + HTTP_NO_CONTENT = 204, + HTTP_RESET_CONTENT = 205, + HTTP_PARTIAL_CONTENT = 206, + HTTP_MULTIPLE_CHOICES = 300, + HTTP_MOVED_PERMANENTLY = 301, + HTTP_MOVED_TEMPORARILY = 302, + HTTP_SEE_OTHER = 303, + HTTP_NOT_MODIFIED = 304, + HTTP_USE_PROXY = 305, + HTTP_BAD_REQUEST = 400, + HTTP_UNAUTHORIZED = 401, + HTTP_PAYMENT_REQUIRED = 402, + HTTP_FORBIDDEN = 403, + HTTP_NOT_FOUND = 404, + HTTP_METHOD_NOT_ALLOWED = 405, + HTTP_NOT_ACCEPTABLE = 406, + HTTP_PROXY_AUTHENTICATION_REQUIRED = 407, + HTTP_REQUEST_TIMEOUT = 408, + HTTP_CONFLICT = 409, + HTTP_GONE = 410, + HTTP_LENGTH_REQUIRED = 411, + HTTP_PRECONDITION_FAILED = 412, + HTTP_REQUEST_ENTITY_TOO_LARGE = 413, + HTTP_REQUEST_URI_TOO_LARGE = 414, + HTTP_UNSUPPORTED_MEDIA_TYPE = 415, + HTTP_INTERNAL_SERVER_ERROR = 500, + HTTP_NOT_IMPLEMENTED = 501, + HTTP_BAD_GATEWAY = 502, + HTTP_SERVICE_UNAVAILABLE = 503, + HTTP_GATEWAY_TIMEOUT = 504, + HTTP_HTTP_VERSION_NOT_SUPPORTED = 505 +} http_status; diff --git a/src/errorpage.cc b/src/errorpage.cc index f6a927935a..c002de8da5 100644 --- a/src/errorpage.cc +++ b/src/errorpage.cc @@ -1,6 +1,6 @@ /* - * $Id: errorpage.cc,v 1.60 1997/07/17 05:25:09 wessels Exp $ + * $Id: errorpage.cc,v 1.61 1997/07/28 06:40:54 wessels Exp $ * * DEBUG: section 4 Error Generation * AUTHOR: Duane Wessels @@ -31,359 +31,175 @@ #include "squid.h" -#define SQUID_ERROR_MSG_P1 "\ -\n\ -ERROR: The requested URL could not be retrieved\n\ -\n\ -

ERROR

\n\ -

The requested URL could not be retrieved

\n\ -
\n\ -

\n\ -While trying to retrieve the URL:\n\ -%s\n\ -

\n\ -The following error was encountered:\n\ -

\n\ -" - -#define SQUID_ERROR_MSG_P2 "\ -

The system returned:\n\ -

    %s
\n\ -" - -#define SQUID_ERROR_MSG_P3 "\ -

This means that:\n\ -

\n\
-    %s\n\
-
\n\ -

\n\ -%s\n\ -


\n\ -
\n\ -Generated by %s/%s@%s\n\ -
\n\ -\n" - -typedef struct { - char *tag; - char *shrt; - char *lng; -} error_data; - -static error_data ErrorData[] = +const char *err_string[] = { - {"ERR_READ_TIMEOUT", - "Read Timeout", - "The remote site or network may be down. Please try again."}, - {"ERR_LIFETIME_EXP", - "Transaction Timeout", - "The network or remote site may be down or too slow. Try again later."}, - {"ERR_NO_CLIENTS", - "No Client", - "All Clients went away before tranmission completed and the object would not be cached."}, - {"ERR_READ_ERROR", - "Read Error", - "The remote site or network may be down. Please try again."}, - {"ERR_WRITE_ERROR", - "Write Error", - "The remote site or network may be down. Please try again."}, - {"ERR_CLIENT_ABORT", - "Client Aborted", - "Client(s) dropped connection before transmission completed.\nObject fetching is aborted.",}, - {"ERR_CONNECT_FAIL", - "Connection Failed", - "The remote site or server may be down. Please try again soon."}, - {"ERR_INVALID_REQUEST", - "Invalid HTTP request", - "Please double check it, or ask for assistance."}, - {"ERR_UNSUP_REQUEST", - "Unsupported request", - "This request method is not supported for this protocol."}, - {"ERR_INVALID_URL", - "Invalid URL syntax", - "Please double check it, or ask for assistance."}, - {"ERR_NO_FDS", - "Out of file descriptors", - "The cache is currently very busy. Please try again."}, - {"ERR_DNS_FAIL", - "DNS name lookup failure", - "The named host probably does not exist."}, - {"ERR_NOT_IMPLEMENTED", - "Protocol Not Supported", - "The cache does not know about the requested protocol."}, - {"ERR_CANNOT_FETCH", - "Unable to Retrieve", - "The requested URL can not currently be retrieved."}, - {"ERR_NO_RELAY", - "No WAIS Relay", - "There is no WAIS relay host defined for this cache."}, - {"ERR_DISK_IO", - "Cache Disk I/O Failure", - "The system disk is out of space or failing."}, - {"ERR_ZERO_SIZE_OBJECT", - "No Object Data", - "The remote server closed the connection before sending any data."}, - {"ERR_PROXY_DENIED", - "Access Denied", - "You must authenticate yourself before accessing this cache."} + "ERR_NONE", + "ERR_READ_TIMEOUT", + "ERR_LIFETIME_EXP", + "ERR_NO_CLIENTS", + "ERR_READ_ERROR", + "ERR_WRITE_ERROR", + "ERR_CLIENT_ABORT", + "ERR_CONNECT_FAIL", + "ERR_INVALID_REQ", + "ERR_UNSUP_REQ", + "ERR_INVALID_URL", + "ERR_SOCKET_FAILURE", + "ERR_DNS_FAIL", + "ERR_NOT_IMPLEMENTED", + "ERR_CANNOT_FORWARD", + "ERR_NO_RELAY", + "ERR_DISK_IO", + "ERR_ZERO_SIZE_OBJECT", + "ERR_FTP_DISABLED", + "ERR_PROXY_DENIED", + "ERR_CACHE_MISS_DENIED", + "ERR_ACCESS_DENIED", + "ERR_MAX" }; -/* LOCAL */ -static char *tbuf = NULL; -static char *auth_msg = NULL; +static char *error_text[ERR_MAX]; + +static void errorStateFree _PARAMS((ErrorState * err)); +static char *errorConvert _PARAMS((char token, ErrorState * err)); +static char *errorBuildBuf _PARAMS((ErrorState * err, int *len)); +static CWCB errorSendComplete; void errorInitialize(void) { -#ifndef USE_PROXY_AUTH - tmp_error_buf = xmalloc(MAX_URL * 4); -#else - tmp_error_buf = xmalloc(8192); -#endif /* USE_PROXY_AUTH */ - meta_data.misc += MAX_URL * 4; - tbuf = xmalloc(MAX_URL * 3); - meta_data.misc += MAX_URL * 3; - auth_msg = xmalloc(MAX_URL * 3); - meta_data.misc += MAX_URL * 3; -} - - -char * -squid_error_url(const char *url, int method, int type, const char *address, int code, const char *msg) -{ - int error_index; - - *tmp_error_buf = '\0'; - if (type < ERR_MIN || type > ERR_MAX) - fatal_dump("squid_error_url: type out of range."); - if (!code) - code = 500; - error_index = (int) (type - ERR_MIN); - debug(4, 1) ("%s: %s\n", ErrorData[error_index].tag, url); - sprintf(tmp_error_buf, "HTTP/1.0 %d Cache Detected Error\r\nContent-type: text/html\r\n\r\n", code); - sprintf(tbuf, SQUID_ERROR_MSG_P1, - url, - url, - ErrorData[error_index].shrt); - strcat(tmp_error_buf, tbuf); - if (msg) { - sprintf(tbuf, SQUID_ERROR_MSG_P2, msg); - strcat(tmp_error_buf, tbuf); + err_type i; + int fd; + char path[MAXPATHLEN]; + struct stat sb; + assert(sizeof(err_string) == (ERR_MAX + 1) * 4); + for (i = ERR_NONE + 1; i < ERR_MAX; i++) { + snprintf(path, MAXPATHLEN, "%s/%s", + Config.errorDirectory, err_string[i]); + fd = file_open(path, O_RDONLY, NULL, NULL); + if (fd < 0) { + debug(4, 0) ("errorInitialize: %s: %s\n", path, xstrerror()); + fatal("Failed to open error text file"); + } + if (fstat(fd, &sb) < 0) + fatal_dump("stat() failed on error text file"); + safe_free(error_text[i]); + error_text[i] = xcalloc(sb.st_size, 1); + if (read(fd, error_text[i], sb.st_size) != sb.st_size) + fatal_dump("failed to fully read error text file"); + file_close(fd); } - sprintf(tbuf, SQUID_ERROR_MSG_P3, - ErrorData[error_index].lng, - Config.errHtmlText, - appname, - version_string, - getMyHostname()); - strcat(tmp_error_buf, tbuf); - return tmp_error_buf; } - -#define SQUID_REQUEST_ERROR_MSG "\ -ERROR: Invalid HTTP Request\n\ -

ERROR

\n\ -

Invalid HTTP Request

\n\ -
\n\ -
\n\
-%s\n\
-
\n\ -

\n\ -%s\n\ -


\n\ -
\n\ -Generated by %s/%s@%s\n\ -
\n\ -\n" - -char * -squid_error_request(const char *request, int type, int code) +static void +errorStateFree(ErrorState * err) { - int error_index; - - *tmp_error_buf = '\0'; - if (type < ERR_MIN || type > ERR_MAX) - fatal_dump("squid_error_request: type out of range."); - error_index = (int) (type - ERR_MIN); - debug(4, 1) ("%s: %s\n", ErrorData[error_index].tag, request); - sprintf(tmp_error_buf, "HTTP/1.0 %d Cache Detected Error\r\nContent-type: text/html\r\n\r\n", code); - sprintf(tbuf, SQUID_REQUEST_ERROR_MSG, - request, - Config.errHtmlText, - appname, - version_string, - getMyHostname()); - strcat(tmp_error_buf, tbuf); - return tmp_error_buf; + requestUnlink(err->request); + safe_free(err->redirect_url); + safe_free(err->url); + cbdataFree(err); } -char * -access_denied_msg(int code, int method, const char *url, const char *client) +static char * +errorConvert(char token, ErrorState * err) { - sprintf(tmp_error_buf, - "HTTP/1.0 %d Cache Access Denied\r\n" - "Content-type: text/html\r\n" - "\r\n" - "Cache Access Denied\n" - "

Error

\n" - "

Access Denied

\n" - "

\n" - "Sorry, you are not currently allowed to request:\n" - "

    %s
\n" - "from this cache. Please check with the\n" - "cache administrator\n" - "if you believe this is incorrect.\n" - "

\n" - "%s\n" - "


\n" - "
\n" - "Generated by %s/%s@%s\n" - "
\n" - "\n", - code, - url, - Config.adminEmail, - Config.errHtmlText, - appname, - version_string, - getMyHostname()); - return tmp_error_buf; + char *p = NULL; + switch (token) { + case 'U': + if (err->request) + p = urlCanonicalClean(err->request); + else + p = err->url; + break; + default: + p = "%UNKNOWN%"; + break; + } + if (p == NULL) + p = ""; + return p; } -/* maex@space.net (06.09.1996) - * the message that is sent on deny_info - * add a Location: and for old browsers a HREF to the info page - */ -char * -access_denied_redirect(int code, int method, const char *url, const char *client, const char *redirect) -{ - sprintf(tmp_error_buf, - "HTTP/1.0 %d Cache Access Deny Redirect\r\n" - "Location: %s\r\n" - "Content-type: text/html\r\n" - "\r\n" - "Cache Access Denied\n" - "

Error

\n" - "

Access Denied

\n" - "

\n" - "Sorry, you are not currently allowed to request:\n" - "

    %s
\n" - "from this cache.\n" - "

\n" - "You may take a look at\n" - "

 %s
\n" - "or check with the\n" - "cache administrator\n" - "if you believe this is incorrect.\n" - "

\n" - "%s\n" - "


\n" - "
\n" - "Generated by %s/%s@%s\n" - "
\n" - "\n", - code, - redirect, - url, - redirect, - redirect, - Config.adminEmail, - Config.errHtmlText, - appname, - version_string, - getMyHostname()); - return tmp_error_buf; -} +#define ERROR_BUF_SZ (MAX_URL<<2) -char * -authorization_needed_msg(const request_t * request, const char *realm) +static char * +errorBuildBuf(ErrorState * err, int *len) { - sprintf(auth_msg, "Authorization needed\n\ -

Authorization needed

\n\ -

Sorry, you have to authorize yourself to request:\n\ -

    ftp://%s@%s%s
\n\ -

from this cache. Please check with the\n\ -cache administrator\n\ -if you believe this is incorrect.\n\ -

\n\ -%s\n\ -


\n\ -
\n\ -Generated by %s/%s@%s\n\ -
\n\ -\n", - request->login, - request->host, - request->urlpath, - Config.adminEmail, - Config.errHtmlText, - appname, - version_string, - getMyHostname()); - - mk_mime_hdr(tbuf, + LOCAL_ARRAY(char, buf, ERROR_BUF_SZ); + LOCAL_ARRAY(char, content, ERROR_BUF_SZ); + char *hdr; + int clen; + int tlen; + char *m; + char *p; + char *t; + assert(err != NULL); + assert(err->type > ERR_NONE && err->type < ERR_MAX); + m = error_text[err->type]; + clen = 0; + while ((p = strchr(m, '%'))) { + *p = '\0'; /* terminate */ + xstrncpy(content + clen, m, ERROR_BUF_SZ - clen); /* copy */ + clen += (p - m); /* advance */ + if (clen >= ERROR_BUF_SZ) + break; + p++; + m = p + 1; + t = errorConvert(*p, err); /* convert */ + xstrncpy(content + clen, t, ERROR_BUF_SZ - clen); /* copy */ + clen += strlen(t); /* advance */ + if (clen >= ERROR_BUF_SZ) + break; + } + if (clen < ERROR_BUF_SZ && m != NULL) { + xstrncpy(content + clen, m, ERROR_BUF_SZ - clen); + clen += strlen(m); + } + if (clen >= ERROR_BUF_SZ) { + clen = ERROR_BUF_SZ - 1; + *(content + clen) = '\0'; + } + assert(clen == strlen(content)); + hdr = httpReplyHeader((double) 1.0, + err->http_status, "text/html", - strlen(auth_msg), + clen, squid_curtime, - squid_curtime + Config.negativeTtl); - sprintf(tmp_error_buf, "HTTP/1.0 401 Unauthorized\r\n" - "%s" - "WWW-Authenticate: Basic realm=\"%s\"\r\n" - "\r\n" - "%s", - tbuf, realm, auth_msg); - return tmp_error_buf; + squid_curtime); + tlen = snprintf(buf, ERROR_BUF_SZ, "%s\r\n%s", hdr, content); + if (len) + *len = tlen; + return buf; } - -#define PROXY_AUTH_ERR_MSG "\ -HTTP/1.0 %d Cache Access Denied\r\n\ -Proxy-Authenticate: Basic realm=\"Squid proxy-caching web server\"\r\n\ -Content-type: text/html\r\n\ -\r\n\ -Cache Access Denied\n\ -

Cache Access Denied

\n\ -

\n\ -Sorry, you are not currently allowed to request:\n\ -

    %s
\n\ -from this cache until you have authenticated yourself.\n\ -\n

\ -You need to use Netscape version 2.0 or greater, or Microsoft Internet Explorer 3.0\n\ -or an HTTP/1.1 compliant browser for this to work.\n\ -Please contact the cache administrator\n\ -if you have difficulties authenticating yourself, or\n\ -change\n\ -your default password.\n\ -

\n\ -%s\n\ -


\n\ -
\n\ -Generated by %s/%s@%s\n\ -
\n\ -" - -char * -proxy_denied_msg(int code, int method, const char *url, const char *client) +void +errorSend(int fd, ErrorState * err) { - sprintf(tmp_error_buf, PROXY_AUTH_ERR_MSG, - code, - url, - Config.adminEmail, - getMyHostname(), - Config.errHtmlText, - appname, - version_string, - getMyHostname()); - return tmp_error_buf; + char *buf; + int len; + assert(fd >= 0); + buf = errorBuildBuf(err, &len); + cbdataAdd(err); + cbdataLock(err); + comm_write(fd, xstrdup(buf), len, errorSendComplete, err, xfree); } void -errorpageFreeMemory(void) +errorAppendEntry(StoreEntry * entry, ErrorState * err) +{ + char *buf; + int len; + assert(entry->store_status == STORE_PENDING); + buf = errorBuildBuf(err, &len); + storeAppend(entry, buf, len); +} + +static void +errorSendComplete(int fd, char *buf, int size, int errflag, void *data) { - safe_free(tmp_error_buf); - safe_free(tbuf); - safe_free(auth_msg); + ErrorState *err = data; + if (err->callback) + err->callback(fd, err->callback_data, size); + cbdataUnlock(err); + errorStateFree(err); } diff --git a/src/ftp.cc b/src/ftp.cc index 1ea983d797..e96be84ecd 100644 --- a/src/ftp.cc +++ b/src/ftp.cc @@ -1,6 +1,6 @@ /* - * $Id: ftp.cc,v 1.135 1997/07/19 07:18:00 wessels Exp $ + * $Id: ftp.cc,v 1.136 1997/07/28 06:40:55 wessels Exp $ * * DEBUG: section 9 File Transfer Protocol (FTP) * AUTHOR: Harvest Derived @@ -49,6 +49,7 @@ enum { static const char *const crlf = "\r\n"; static char cbuf[1024]; +static char auth_msg[AUTH_MSG_SZ]; typedef enum { BEGIN, @@ -106,6 +107,8 @@ typedef struct _Ftpdata { size_t size; off_t offset; FREE *freefunc; + char *host; + u_short port; } data; } FtpStateData; @@ -139,6 +142,7 @@ static void ftpRestOrList _PARAMS((FtpStateData * ftpState)); static void ftpReadQuit _PARAMS((FtpStateData * ftpState)); static void ftpDataTransferDone _PARAMS((FtpStateData * ftpState)); static void ftpAppendSuccessHeader _PARAMS((FtpStateData * ftpState)); +static char *ftpAuthRequired _PARAMS((const request_t *, const char *)); static STABH ftpAbort; static FTPSM ftpReadWelcome; @@ -201,6 +205,7 @@ ftpStateFree(int fd, void *data) safe_free(ftpState->ctrl.last_message); safe_free(ftpState->title_url); safe_free(ftpState->filepath); + safe_free(ftpState->data.host); if (ftpState->data.fd > -1) comm_close(ftpState->data.fd); cbdataFree(ftpState); @@ -228,8 +233,16 @@ ftpTimeout(int fd, void *data) { FtpStateData *ftpState = data; StoreEntry *entry = ftpState->entry; + ErrorState *err; debug(9, 4) ("ftpTimeout: FD %d: '%s'\n", fd, entry->url); - storeAbort(entry, ERR_READ_TIMEOUT, NULL, 0); + if (entry->object_len == 0) { + err = xcalloc(1, sizeof(ErrorState)); + err->type = ERR_READ_TIMEOUT; + err->http_status = HTTP_GATEWAY_TIMEOUT; + err->request = requestLink(ftpState->request); + errorAppendEntry(entry, err); + } + storeAbort(entry, 0); if (ftpState->data.fd >= 0) { comm_close(ftpState->data.fd); ftpState->data.fd = -1; @@ -600,9 +613,10 @@ ftpReadData(int fd, void *data) int off; int bin; StoreEntry *entry = ftpState->entry; + ErrorState *err; assert(fd == ftpState->data.fd); if (protoAbortFetch(entry)) { - storeAbort(entry, ERR_CLIENT_ABORT, NULL, 0); + storeAbort(entry, 0); ftpDataTransferDone(ftpState); return; } @@ -647,13 +661,25 @@ ftpReadData(int fd, void *data) if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { commSetSelect(fd, COMM_SELECT_READ, ftpReadData, data, 0); } else { - BIT_RESET(entry->flag, ENTRY_CACHABLE); - storeReleaseRequest(entry); - storeAbort(entry, ERR_READ_ERROR, xstrerror(), 0); + if (entry->object_len == 0) { + err = xcalloc(1, sizeof(ErrorState)); + err->type = ERR_READ_ERROR; + err->errno = errno; + err->http_status = HTTP_INTERNAL_SERVER_ERROR; + err->request = requestLink(ftpState->request); + errorAppendEntry(entry, err); + } + storeAbort(entry, 0); ftpDataTransferDone(ftpState); } } else if (len == 0 && entry->mem_obj->e_current_len == 0) { - storeAbort(entry, ERR_ZERO_SIZE_OBJECT, errno ? xstrerror() : NULL, 0); + err = xcalloc(1, sizeof(ErrorState)); + err->type = ERR_ZERO_SIZE_OBJECT; + err->errno = errno; + err->http_status = HTTP_SERVICE_UNAVAILABLE; + err->request = requestLink(ftpState->request); + errorAppendEntry(entry, err); + storeAbort(entry, 0); ftpDataTransferDone(ftpState); } else if (len == 0) { /* Connection closed; retrieval done. */ @@ -819,6 +845,7 @@ ftpStart(request_t * request, StoreEntry * entry) FtpStateData *ftpState = xcalloc(1, sizeof(FtpStateData)); char *response; int fd; + ErrorState *err; cbdataAdd(ftpState); debug(9, 3) ("FtpStart: '%s'\n", entry->url); storeLockObject(entry); @@ -836,7 +863,7 @@ ftpStart(request_t * request, StoreEntry * entry) sprintf(realm, "ftp %s port %d", ftpState->user, request->port); } - response = authorization_needed_msg(request, realm); + response = ftpAuthRequired(request, realm); storeAppend(entry, response, strlen(response)); httpParseReplyHeaders(response, entry->mem_obj->reply); storeComplete(entry); @@ -856,7 +883,13 @@ ftpStart(request_t * request, StoreEntry * entry) url); if (fd == COMM_ERROR) { debug(9, 4) ("ftpStart: Failed because we're out of sockets.\n"); - storeAbort(entry, ERR_NO_FDS, xstrerror(), 0); + err = xcalloc(1, sizeof(ErrorState)); + err->type = ERR_SOCKET_FAILURE; + err->http_status = HTTP_INTERNAL_SERVER_ERROR; + err->errno = errno; + err->request = requestLink(ftpState->request); + errorAppendEntry(entry, err); + storeAbort(entry, 0); return; } ftpState->ctrl.fd = fd; @@ -875,13 +908,28 @@ ftpConnectDone(int fd, int status, void *data) { FtpStateData *ftpState = data; request_t *request = ftpState->request; + ErrorState *err; debug(9, 3) ("ftpConnectDone, status = %d\n", status); if (status == COMM_ERR_DNS) { debug(9, 4) ("ftpConnectDone: Unknown host: %s\n", request->host); - storeAbort(ftpState->entry, ERR_DNS_FAIL, dns_error_message, 0); + err = xcalloc(1, sizeof(ErrorState)); + err->type = ERR_DNS_FAIL; + err->http_status = HTTP_SERVICE_UNAVAILABLE; + err->dnsserver_msg = xstrdup(dns_error_message); + err->request = requestLink(request); + errorAppendEntry(ftpState->entry, err); + storeAbort(ftpState->entry, 0); comm_close(fd); } else if (status != COMM_OK) { - storeAbort(ftpState->entry, ERR_CONNECT_FAIL, xstrerror(), 0); + err = xcalloc(1, sizeof(ErrorState)); + err->type = ERR_CONNECT_FAIL; + err->http_status = HTTP_SERVICE_UNAVAILABLE; + err->errno = errno; + err->host = xstrdup(request->host); + err->port = request->port; + err->request = requestLink(request); + errorAppendEntry(ftpState->entry, err); + storeAbort(ftpState->entry, 0); comm_close(fd); } else { ftpState->state = BEGIN; @@ -921,12 +969,19 @@ ftpWriteCommandCallback(int fd, char *buf, int size, int errflag, void *data) { FtpStateData *ftpState = data; StoreEntry *entry = ftpState->entry; + ErrorState *err; debug(9, 7) ("ftpWriteCommandCallback: wrote %d bytes\n", size); if (errflag) { debug(50, 1) ("ftpWriteCommandCallback: FD %d: %s\n", fd, xstrerror()); - BIT_RESET(entry->flag, ENTRY_CACHABLE); - storeReleaseRequest(entry); - storeAbort(entry, ERR_WRITE_ERROR, xstrerror(), 0); + if (entry->object_len == 0) { + err = xcalloc(1, sizeof(ErrorState)); + err->type = ERR_WRITE_ERROR; + err->http_status = HTTP_SERVICE_UNAVAILABLE; + err->errno = errno; + err->request = requestLink(ftpState->request); + errorAppendEntry(entry, err); + } + storeAbort(entry, 0); comm_close(fd); } } @@ -977,6 +1032,7 @@ ftpReadControlReply(int fd, void *data) char *oldbuf; wordlist **W; int len; + ErrorState *err; debug(9, 5) ("ftpReadControlReply\n"); assert(ftpState->ctrl.offset < ftpState->ctrl.size); len = read(fd, @@ -995,9 +1051,15 @@ ftpReadControlReply(int fd, void *data) ftpState, 0); } else { - BIT_RESET(entry->flag, ENTRY_CACHABLE); - storeReleaseRequest(entry); - storeAbort(entry, ERR_READ_ERROR, xstrerror(), 0); + if (entry->object_len == 0) { + err = xcalloc(1, sizeof(ErrorState)); + err->type = ERR_READ_ERROR; + err->http_status = HTTP_INTERNAL_SERVER_ERROR; + err->errno = errno; + err->request = requestLink(ftpState->request); + errorAppendEntry(entry, err); + } + storeAbort(entry, 0); comm_close(fd); } return; @@ -1005,9 +1067,15 @@ ftpReadControlReply(int fd, void *data) if (len == 0) { debug(9, 1) ("Read 0 bytes from FTP control socket?\n"); assert(len); - BIT_RESET(entry->flag, ENTRY_CACHABLE); - storeReleaseRequest(entry); - storeAbort(entry, ERR_READ_ERROR, xstrerror(), 0); + if (entry->object_len == 0) { + err = xcalloc(1, sizeof(ErrorState)); + err->type = ERR_READ_ERROR; + err->http_status = HTTP_INTERNAL_SERVER_ERROR; + err->errno = errno; + err->request = requestLink(ftpState->request); + errorAppendEntry(entry, err); + } + storeAbort(entry, 0); comm_close(fd); return; } @@ -1284,6 +1352,8 @@ ftpReadPasv(FtpStateData * ftpState) } port = ((p1 << 8) + p2); debug(9, 5) ("ftpReadPasv: connecting to %s, port %d\n", junk, port); + ftpState->data.port = port; + ftpState->data.host = xstrdup(junk); commConnectStart(fd, junk, port, ftpPasvCallback, ftpState); } @@ -1291,9 +1361,19 @@ static void ftpPasvCallback(int fd, int status, void *data) { FtpStateData *ftpState = data; + request_t *request = ftpState->request; + ErrorState *err; debug(9, 3) ("ftpPasvCallback\n"); - if (status == COMM_ERROR) { - storeAbort(ftpState->entry, ERR_CONNECT_FAIL, xstrerror(), 0); + if (status != COMM_OK) { + err = xcalloc(1, sizeof(ErrorState)); + err->type = ERR_CONNECT_FAIL; + err->http_status = HTTP_SERVICE_UNAVAILABLE; + err->errno = errno; + err->host = xstrdup(ftpState->data.host); + err->port = ftpState->data.port; + err->request = requestLink(request); + errorAppendEntry(ftpState->entry, err); + storeAbort(ftpState->entry, 0); comm_close(fd); return; } @@ -1493,3 +1573,58 @@ ftpAbort(void *data) } comm_close(ftpState->ctrl.fd); } + +const char *ftpAuthText = +"Authorization needed\n" +"

Authorization needed

\n" +"

Sorry, you have to authorize yourself to request:\n" +"

    ftp://%s@%s%256.256s
\n" +"

from this cache. Please check with the\n" +"cache administrator\n" +"if you believe this is incorrect.\n" + +"

\n" +"%s\n" +"


\n" +"
\n" +"Generated by %s/%s@%s\n" +"
\n" +"\n"; + + +static char * +ftpAuthRequired(const request_t * request, const char *realm) +{ + LOCAL_ARRAY(char, content, AUTH_MSG_SZ); + char *hdr; + int s = AUTH_MSG_SZ; + int l = 0; + /* Generate the reply body */ + l += snprintf(content + l, s - l, ftpAuthText, + request->login, + request->host, + request->urlpath, + Config.adminEmail); + l += snprintf(content + l, s - l, "

\n%s\n", + Config.errHtmlText); + l += snprintf(content + l, s - l, + "


\n
\nGenerated by %s/%s@%s\n
\n", + appname, + version_string, + getMyHostname()); + /* Now generate reply headers with correct content length */ + hdr = httpReplyHeader(1.0, HTTP_UNAUTHORIZED, + "text/html", + strlen(content), + squid_curtime, + squid_curtime + Config.negativeTtl); + /* Now stuff them together and add Authenticate header */ + l = 0; + s = AUTH_MSG_SZ; + l += snprintf(auth_msg + l, s - l, "%s", hdr); + l += snprintf(auth_msg + l, s - l, + "WWW-Authenticate: Basic realm=\"%s\"\r\n", + realm); + l += snprintf(auth_msg + l, s - l, "\r\n%s", content); + return auth_msg; +} diff --git a/src/globals.h b/src/globals.h index 2dc6634edc..65fe313161 100644 --- a/src/globals.h +++ b/src/globals.h @@ -9,7 +9,8 @@ extern cacheinfo *ICPCacheInfo; extern char *ConfigFile; /* NULL */ extern char *IcpOpcodeStr[]; extern char *dns_error_message; /* NULL */ -extern char *log_tags[]; +extern const char *log_tags[]; +extern const char *err_string[]; extern char *tmp_error_buf; /* NULL */ extern char *volatile debug_options; /* NULL */ extern char ThisCache[SQUIDHOSTNAMELEN << 1]; diff --git a/src/gopher.cc b/src/gopher.cc index 255f391142..86f50484e9 100644 --- a/src/gopher.cc +++ b/src/gopher.cc @@ -1,6 +1,6 @@ /* - * $Id: gopher.cc,v 1.91 1997/07/16 20:32:06 wessels Exp $ + * $Id: gopher.cc,v 1.92 1997/07/28 06:40:56 wessels Exp $ * * DEBUG: section 10 Gopher * AUTHOR: Harvest Derived @@ -648,7 +648,8 @@ gopherTimeout(int fd, void *data) GopherStateData *gopherState = data; StoreEntry *entry = gopherState->entry; debug(10, 4) ("gopherTimeout: FD %d: '%s'\n", fd, entry->url); - storeAbort(entry, ERR_READ_TIMEOUT, NULL, 0); + assert(!ERR_READ_TIMEOUT); + storeAbort(entry, 0); comm_close(fd); } @@ -665,7 +666,7 @@ gopherReadReply(int fd, void *data) int off; int bin; if (protoAbortFetch(entry)) { - storeAbort(entry, ERR_CLIENT_ABORT, NULL, 0); + storeAbort(entry, 0); comm_close(fd); return; } @@ -717,13 +718,13 @@ gopherReadReply(int fd, void *data) gopherReadReply, data, 0); } else { - BIT_RESET(entry->flag, ENTRY_CACHABLE); - storeReleaseRequest(entry); - storeAbort(entry, ERR_READ_ERROR, xstrerror(), 0); + assert(!ERR_READ_ERROR); + storeAbort(entry, 0); comm_close(fd); } } else if (len == 0 && entry->mem_obj->e_current_len == 0) { - storeAbort(entry, ERR_ZERO_SIZE_OBJECT, errno ? xstrerror() : NULL, 0); + assert(!ERR_ZERO_SIZE_OBJECT); + storeAbort(entry, 0); comm_close(fd); } else if (len == 0) { /* Connection closed; retrieval done. */ @@ -760,7 +761,8 @@ gopherSendComplete(int fd, char *buf, int size, int errflag, void *data) debug(10, 5) ("gopherSendComplete: FD %d size: %d errflag: %d\n", fd, size, errflag); if (errflag) { - storeAbort(entry, ERR_CONNECT_FAIL, xstrerror(), 0); + assert(!ERR_CONNECT_FAIL); + storeAbort(entry, 0); comm_close(fd); if (buf) put_free_4k_page(buf); /* Allocated by gopherSendRequest. */ @@ -841,7 +843,8 @@ gopherStart(StoreEntry * entry) /* Parse url. */ if (gopher_url_parser(url, gopherState->host, &gopherState->port, &gopherState->type_id, gopherState->request)) { - storeAbort(entry, ERR_INVALID_URL, NULL, 0); + assert(!ERR_INVALID_URL); + storeAbort(entry, 0); gopherStateFree(-1, gopherState); return; } @@ -854,7 +857,8 @@ gopherStart(StoreEntry * entry) url); if (fd == COMM_ERROR) { debug(10, 4) ("gopherStart: Failed because we're out of sockets.\n"); - storeAbort(entry, ERR_NO_FDS, xstrerror(), 0); + assert(!ERR_SOCKET_FAILURE); + storeAbort(entry, 0); gopherStateFree(-1, gopherState); return; } @@ -865,7 +869,8 @@ gopherStart(StoreEntry * entry) * Otherwise, we cannot check return code for connect. */ if (!ipcache_gethostbyname(gopherState->host, 0)) { debug(10, 4) ("gopherStart: Called without IP entry in ipcache. OR lookup failed.\n"); - storeAbort(entry, ERR_DNS_FAIL, dns_error_message, 0); + assert(!ERR_DNS_FAIL); + storeAbort(entry, 0); comm_close(fd); return; } @@ -903,10 +908,12 @@ gopherConnectDone(int fd, int status, void *data) GopherStateData *gopherState = data; if (status == COMM_ERR_DNS) { debug(10, 4) ("gopherConnectDone: Unknown host: %s\n", gopherState->host); - storeAbort(gopherState->entry, ERR_DNS_FAIL, dns_error_message, 0); + assert(!ERR_DNS_FAIL); + storeAbort(gopherState->entry, 0); comm_close(fd); } else if (status != COMM_OK) { - storeAbort(gopherState->entry, ERR_CONNECT_FAIL, xstrerror(), 0); + assert(!ERR_CONNECT_FAIL); + storeAbort(gopherState->entry, 0); comm_close(fd); } else { commSetSelect(fd, COMM_SELECT_WRITE, gopherSendRequest, gopherState, 0); diff --git a/src/http.cc b/src/http.cc index 8a2cccae4c..a07bad73b7 100644 --- a/src/http.cc +++ b/src/http.cc @@ -1,5 +1,5 @@ /* - * $Id: http.cc,v 1.179 1997/07/26 04:48:29 wessels Exp $ + * $Id: http.cc,v 1.180 1997/07/28 06:40:57 wessels Exp $ * * DEBUG: section 11 Hypertext Transfer Protocol (HTTP) * AUTHOR: Harvest Derived @@ -208,6 +208,7 @@ static void httpAppendRequestHeader _PARAMS((char *hdr, const char *line, size_t static void httpCacheNegatively _PARAMS((StoreEntry *)); static void httpMakePrivate _PARAMS((StoreEntry *)); static void httpMakePublic _PARAMS((StoreEntry *)); +static char *httpStatusString _PARAMS((int status)); static STABH httpAbort; static void @@ -244,8 +245,16 @@ httpTimeout(int fd, void *data) { HttpStateData *httpState = data; StoreEntry *entry = httpState->entry; + ErrorState *err; debug(11, 4) ("httpTimeout: FD %d: '%s'\n", fd, entry->url); - storeAbort(entry, ERR_READ_TIMEOUT, NULL, 0); + if (entry->object_len == 0) { + err = xcalloc(1, sizeof(ErrorState)); + err->type = ERR_READ_TIMEOUT; + err->http_status = HTTP_GATEWAY_TIMEOUT; + err->request = requestLink(httpState->request); + errorAppendEntry(entry, err); + } + storeAbort(entry, 0); comm_close(fd); } @@ -562,8 +571,9 @@ httpReadReply(int fd, void *data) int bin; int clen; int off; + ErrorState *err; if (protoAbortFetch(entry)) { - storeAbort(entry, ERR_CLIENT_ABORT, NULL, 0); + storeAbort(entry, 0); comm_close(fd); return; } @@ -605,21 +615,30 @@ httpReadReply(int fd, void *data) } if (len < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { - /* reinstall handlers */ - /* XXX This may loop forever */ - commSetSelect(fd, COMM_SELECT_READ, - httpReadReply, httpState, 0); + commSetSelect(fd, COMM_SELECT_READ, httpReadReply, httpState, 0); } else { - BIT_RESET(entry->flag, ENTRY_CACHABLE); - storeReleaseRequest(entry); - storeAbort(entry, ERR_READ_ERROR, xstrerror(), 0); + if (entry->object_len == 0) { + err = xcalloc(1, sizeof(ErrorState)); + err->type = ERR_READ_ERROR; + err->errno = errno; + err->http_status = HTTP_INTERNAL_SERVER_ERROR; + err->request = requestLink(httpState->request); + errorAppendEntry(entry, err); + } + storeAbort(entry, 0); comm_close(fd); } debug(50, 2) ("httpReadReply: FD %d: read failure: %s.\n", fd, xstrerror()); } else if (len == 0 && entry->mem_obj->e_current_len == 0) { httpState->eof = 1; - storeAbort(entry, ERR_ZERO_SIZE_OBJECT, errno ? xstrerror() : NULL, 0); + err = xcalloc(1, sizeof(ErrorState)); + err->type = ERR_ZERO_SIZE_OBJECT; + err->errno = errno; + err->http_status = HTTP_SERVICE_UNAVAILABLE; + err->request = requestLink(httpState->request); + errorAppendEntry(entry, err); + storeAbort(entry, 0); comm_close(fd); } else if (len == 0) { /* Connection closed; retrieval done. */ @@ -646,14 +665,18 @@ static void httpSendComplete(int fd, char *buf, int size, int errflag, void *data) { HttpStateData *httpState = data; - StoreEntry *entry = NULL; - - entry = httpState->entry; + StoreEntry *entry = httpState->entry; + ErrorState *err; debug(11, 5) ("httpSendComplete: FD %d: size %d: errflag %d.\n", fd, size, errflag); - if (errflag) { - storeAbort(entry, ERR_CONNECT_FAIL, xstrerror(), 0); + err = xcalloc(1, sizeof(ErrorState)); + err->type = ERR_WRITE_ERROR; + err->http_status = HTTP_INTERNAL_SERVER_ERROR; + err->errno = errno; + err->request = requestLink(httpState->request); + errorAppendEntry(entry, err); + storeAbort(entry, 0); comm_close(fd); return; } else { @@ -874,6 +897,7 @@ proxyhttpStart(request_t * orig_request, HttpStateData *httpState; request_t *request; int fd; + ErrorState *err; debug(11, 3) ("proxyhttpStart: \"%s %s\"\n", RequestMethodStr[orig_request->method], entry->url); if (e->options & NEIGHBOR_PROXY_ONLY) @@ -891,7 +915,12 @@ proxyhttpStart(request_t * orig_request, entry->url); if (fd == COMM_ERROR) { debug(11, 4) ("proxyhttpStart: Failed because we're out of sockets.\n"); - storeAbort(entry, ERR_NO_FDS, xstrerror(), 0); + err = xcalloc(1, sizeof(ErrorState)); + err->type = ERR_SOCKET_FAILURE; + err->http_status = HTTP_INTERNAL_SERVER_ERROR; + err->errno = errno; + errorAppendEntry(entry, err); + storeAbort(entry, 0); return; } storeLockObject(entry); @@ -926,12 +955,27 @@ httpConnectDone(int fd, int status, void *data) HttpStateData *httpState = data; request_t *request = httpState->request; StoreEntry *entry = httpState->entry; + ErrorState *err; if (status == COMM_ERR_DNS) { debug(11, 4) ("httpConnectDone: Unknown host: %s\n", request->host); - storeAbort(entry, ERR_DNS_FAIL, dns_error_message, 0); + err = xcalloc(1, sizeof(ErrorState)); + err->type = ERR_DNS_FAIL; + err->http_status = HTTP_SERVICE_UNAVAILABLE; + err->dnsserver_msg = xstrdup(dns_error_message); + err->request = requestLink(request); + errorAppendEntry(entry, err); + storeAbort(entry, 0); comm_close(fd); } else if (status != COMM_OK) { - storeAbort(entry, ERR_CONNECT_FAIL, xstrerror(), 0); + err = xcalloc(1, sizeof(ErrorState)); + err->type = ERR_CONNECT_FAIL; + err->http_status = HTTP_SERVICE_UNAVAILABLE; + err->errno = errno; + err->host = xstrdup(request->host); + err->port = request->port; + err->request = requestLink(request); + errorAppendEntry(entry, err); + storeAbort(entry, 0); if (httpState->neighbor) peerCheckConnectStart(httpState->neighbor); comm_close(fd); @@ -946,6 +990,7 @@ httpStart(request_t * request, StoreEntry * entry) { int fd; HttpStateData *httpState; + ErrorState *err; debug(11, 3) ("httpStart: \"%s %s\"\n", RequestMethodStr[request->method], entry->url); /* Create socket. */ @@ -957,7 +1002,13 @@ httpStart(request_t * request, StoreEntry * entry) entry->url); if (fd == COMM_ERROR) { debug(11, 4) ("httpStart: Failed because we're out of sockets.\n"); - storeAbort(entry, ERR_NO_FDS, xstrerror(), 0); + err = xcalloc(1, sizeof(ErrorState)); + err->type = ERR_SOCKET_FAILURE; + err->http_status = HTTP_INTERNAL_SERVER_ERROR; + err->errno = errno; + err->request = requestLink(request); + errorAppendEntry(entry, err); + storeAbort(entry, 0); return; } storeLockObject(entry); @@ -1005,3 +1056,159 @@ httpAbort(void *data) debug(11, 1) ("httpAbort: %s\n", httpState->entry->url); comm_close(httpState->fd); } + +static char * +httpStatusString(int status) +{ + char *p = NULL; + switch (status) { + case 100: + p = "Continue"; + break; + case 101: + p = "Switching Protocols"; + break; + case 200: + p = "OK"; + break; + case 201: + p = "Created"; + break; + case 202: + p = "Accepted"; + break; + case 203: + p = "Non-Authoritative Information"; + break; + case 204: + p = "No Content"; + break; + case 205: + p = "Reset Content"; + break; + case 206: + p = "Partial Content"; + break; + case 300: + p = "Multiple Choices"; + break; + case 301: + p = "Moved Permanently"; + break; + case 302: + p = "Moved Temporarily"; + break; + case 303: + p = "See Other"; + break; + case 304: + p = "Not Modified"; + break; + case 305: + p = "Use Proxy"; + break; + case 400: + p = "Bad Request"; + break; + case 401: + p = "Unauthorized"; + break; + case 402: + p = "Payment Required"; + break; + case 403: + p = "Forbidden"; + break; + case 404: + p = "Not Found"; + break; + case 405: + p = "Method Not Allowed"; + break; + case 406: + p = "Not Acceptable"; + break; + case 407: + p = "Proxy Authentication Required"; + break; + case 408: + p = "Request Time-out"; + break; + case 409: + p = "Conflict"; + break; + case 410: + p = "Gone"; + break; + case 411: + p = "Length Required"; + break; + case 412: + p = "Precondition Failed"; + break; + case 413: + p = "Request Entity Too Large"; + break; + case 414: + p = "Request-URI Too Large"; + break; + case 415: + p = "Unsupported Media Type"; + break; + case 500: + p = "Internal Server Error"; + break; + case 501: + p = "Not Implemented"; + break; + case 502: + p = "Bad Gateway"; + break; + case 503: + p = "Service Unavailable"; + break; + case 504: + p = "Gateway Time-out"; + break; + case 505: + p = "HTTP Version not supported"; + break; + default: + p = "Unknown"; + debug(11, 0) ("Unknown HTTP status code: %d\n", status); + break; + } + return p; +} + +char * +httpReplyHeader(double ver, + http_status status, + char *ctype, + int clen, + time_t lmt, + time_t expires) +{ + LOCAL_ARRAY(char, buf, HTTP_REPLY_BUF_SZ); + LOCAL_ARRAY(char, float_buf, 64); + int l = 0; + int s = HTTP_REPLY_BUF_SZ; + /* argh, ../lib/snprintf.c doesn't support '%f' */ + sprintf(float_buf, "%3.1f", ver); + assert(strlen(float_buf) == 3); + l += snprintf(buf + l, s - l, "HTTP/%s %d %s\r\n", + float_buf, + (int) status, + httpStatusString(status)); + l += snprintf(buf + l, s - l, "Server: Squid/%s\r\n", SQUID_VERSION); + l += snprintf(buf + l, s - l, "Date: %s\r\n", mkrfc1123(squid_curtime)); + if (expires >= 0) + l += snprintf(buf + l, s - l, "Expires: %s\r\n", mkrfc1123(expires)); + if (lmt) + l += snprintf(buf + l, s - l, "Last-Modified: %s\r\n", mkrfc1123(lmt)); + if (clen > 0) + l += snprintf(buf + l, s - l, "Content-Length: %d\r\n", clen); + if (ctype) + l += snprintf(buf + l, s - l, "Content-Type: %s\r\n", ctype); + return buf; +} diff --git a/src/main.cc b/src/main.cc index 9082c0a460..1ee1d33396 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,6 +1,6 @@ /* - * $Id: main.cc,v 1.169 1997/07/26 04:48:32 wessels Exp $ + * $Id: main.cc,v 1.170 1997/07/28 06:40:59 wessels Exp $ * * DEBUG: section 1 Startup and Main Loop * AUTHOR: Harvest Derived @@ -492,6 +492,7 @@ mainInitialize(void) dnsOpenServers(); redirectOpenServers(); useragentOpenLog(); + errorInitialize(); #if MALLOC_DBG malloc_debug(0, malloc_debug_level); @@ -577,7 +578,6 @@ main(int argc, char **argv) memset(&no_addr, '\0', sizeof(struct in_addr)); safe_inet_addr("255.255.255.255", &no_addr); squid_srandom(time(NULL)); - errorInitialize(); squid_starttime = getCurrentTime(); failure_notify = fatal_dump; diff --git a/src/protos.h b/src/protos.h index 7e1af68986..163bf4ac43 100644 --- a/src/protos.h +++ b/src/protos.h @@ -49,11 +49,9 @@ extern void aioUnlink _PARAMS((const char *, AIOCB *, void *)); extern void aioCheckCallbacks _PARAMS((void)); extern int parseConfigFile _PARAMS((const char *file_name)); -extern int setCacheSwapMax _PARAMS((int size)); extern void intlistDestroy _PARAMS((intlist **)); extern void wordlistDestroy _PARAMS((wordlist **)); extern void configFreeMemory _PARAMS((void)); -extern char *cachemgr_getpassword _PARAMS((cachemgr_passwd **, char *)); extern void dump_all _PARAMS((void)); extern void cbdataInit _PARAMS((void)); @@ -68,6 +66,7 @@ extern void clientdbInit _PARAMS((void)); extern void clientdbUpdate _PARAMS((struct in_addr, log_type, protocol_t)); extern int clientdbDeniedPercent _PARAMS((struct in_addr)); extern void clientdbDump _PARAMS((StoreEntry *)); +extern CWCB clientWriteComplete; extern void clientAccessCheck _PARAMS((void *)); extern void clientAccessCheckDone _PARAMS((int, void *)); @@ -101,7 +100,6 @@ extern void comm_add_close_handler _PARAMS((int fd, PF *, void *)); extern void comm_remove_close_handler _PARAMS((int fd, PF *, void *)); extern int comm_udp_send _PARAMS((int fd, const char *host, u_short port, const char *buf, int len)); extern int comm_udp_sendto _PARAMS((int fd, const struct sockaddr_in *, int size, const char *buf, int len)); -extern int fd_of_first_client _PARAMS((StoreEntry *)); extern void comm_set_stall _PARAMS((int, int)); extern void comm_write _PARAMS((int fd, char *buf, @@ -124,7 +122,6 @@ extern void _db_print _PARAMS(()); extern int file_open _PARAMS((const char *path, int mode, FOCB *, void *callback_data)); -extern void file_must_close _PARAMS((int fd)); extern void file_close _PARAMS((int fd)); extern int file_write _PARAMS((int fd, char *buf, @@ -142,18 +139,14 @@ extern int file_walk _PARAMS((int fd, FILE_WALK_HD *, void *, FILE_WALK_LHD *, v extern int disk_init _PARAMS((void)); extern int diskWriteIsComplete _PARAMS((int)); -extern void statDns _PARAMS((StoreEntry *)); extern void dnsShutdownServers _PARAMS((void)); extern void dnsOpenServers _PARAMS((void)); -extern void dnsEnqueue _PARAMS((void *)); -extern void *dnsDequeue _PARAMS((void)); extern dnsserver_t *dnsGetFirstAvailable _PARAMS((void)); extern void dnsStats _PARAMS((StoreEntry *)); extern void dnsFreeMemory _PARAMS((void)); extern char *squid_error_url _PARAMS((const char *, int, int, const char *, int, const char *)); extern char *squid_error_request _PARAMS((const char *, int, int)); -extern void errorInitialize _PARAMS((void)); extern char *access_denied_msg _PARAMS((int, int, const char *, const char *)); extern char *access_denied_redirect _PARAMS((int, int, const char *, const char *, const char *)); #if USE_PROXY_AUTH @@ -179,7 +172,6 @@ extern void fdFreeMemory _PARAMS((void)); extern void fdDumpOpen _PARAMS((void)); extern void fdstat_init _PARAMS((void)); -extern void fdstat_open _PARAMS((int fd, unsigned int type)); extern int fdstat_are_n_free_fd _PARAMS((int)); extern fileMap *file_map_create _PARAMS((int)); @@ -195,8 +187,6 @@ extern int fqdncacheUnregister _PARAMS((struct in_addr, void *)); extern const char *fqdncache_gethostbyaddr _PARAMS((struct in_addr, int flags)); extern void fqdncache_init _PARAMS((void)); extern void fqdnStats _PARAMS((StoreEntry *)); -extern void fqdncacheShutdownServers _PARAMS((void)); -extern void fqdncacheOpenServers _PARAMS((void)); extern void fqdncacheReleaseInvalid _PARAMS((const char *)); extern const char *fqdnFromAddr _PARAMS((struct in_addr)); extern int fqdncacheQueueDrain _PARAMS((void)); @@ -240,6 +230,15 @@ extern size_t httpBuildRequestHeader _PARAMS((request_t * request, char *hdr_out, size_t out_sz, int cfd)); +extern int httpAnonAllowed _PARAMS((const char *line)); +extern int httpAnonDenied _PARAMS((const char *line)); +extern char *httpReplyHeader _PARAMS((double ver, + http_status status, + char *ctype, + int clen, + time_t lmt, + time_t expires)); + extern void icmpOpen _PARAMS((void)); extern void icmpClose _PARAMS((void)); @@ -269,7 +268,7 @@ extern void AppendUdp _PARAMS((icpUdpData *)); extern void icpParseRequestHeaders _PARAMS((clientHttpRequest *)); extern void icpProcessRequest _PARAMS((int, clientHttpRequest *)); extern PF icpUdpReply; -extern CWCB icpSendERRORComplete; +extern ERCB icpErrorComplete; extern STCB icpSendMoreData; @@ -280,7 +279,6 @@ extern EVH ipcache_purgelru; extern const ipcache_addrs *ipcache_gethostbyname _PARAMS((const char *, int flags)); extern void ipcacheInvalidate _PARAMS((const char *)); extern void ipcacheReleaseInvalid _PARAMS((const char *)); -extern void ipcacheOpenServers _PARAMS((void)); extern void ipcacheShutdownServers _PARAMS((void)); extern void ipcache_init _PARAMS((void)); extern void stat_ipcache_get _PARAMS((StoreEntry *)); @@ -303,7 +301,6 @@ extern char mimeGetTransferMode _PARAMS((const char *fn)); extern int mcastSetTtl _PARAMS((int, int)); extern IPH mcastJoinGroups; -extern void mcastJoinVizSock _PARAMS((void)); /* Labels for hierachical log file */ /* put them all here for easier reference when writing a logfile analyzer */ @@ -319,15 +316,11 @@ extern int neighborsUdpPing _PARAMS((request_t *, IRCB * callback, void *data, int *exprep)); -extern void neighborAddDomainPing _PARAMS((const char *, const char *)); -extern void neighborAddDomainType _PARAMS((const char *, const char *, const char *)); extern void neighborAddAcl _PARAMS((const char *, const char *)); extern void neighborsUdpAck _PARAMS((int, const char *, icp_common_t *, const struct sockaddr_in *, StoreEntry *, char *, int)); extern void neighborAdd _PARAMS((const char *, const char *, int, int, int, int, int)); extern void neighbors_open _PARAMS((int)); -extern void neighborsDestroy _PARAMS((void)); extern peer *peerFindByName _PARAMS((const char *)); -extern void neighbors_init _PARAMS((void)); extern peer *getDefaultParent _PARAMS((request_t * request)); extern peer *getRoundRobinParent _PARAMS((request_t * request)); extern int neighborUp _PARAMS((const peer * e)); @@ -352,16 +345,13 @@ extern void objcacheStart _PARAMS((int fd, StoreEntry *)); extern void peerSelect _PARAMS((request_t *, StoreEntry *, PSC *, PSC *, void *data)); -extern int peerSelectDirect _PARAMS((request_t *)); extern peer *peerGetSomeParent _PARAMS((request_t *, hier_code *)); -extern int matchInsideFirewall _PARAMS((const char *)); extern void peerSelectInit _PARAMS((void)); extern void protoDispatch _PARAMS((int, StoreEntry *, request_t *)); extern int protoUnregister _PARAMS((StoreEntry *, request_t *, struct in_addr)); extern void protoStart _PARAMS((int, StoreEntry *, peer *, request_t *)); -extern void protoCancelTimeout _PARAMS((int fd, StoreEntry *)); extern int protoAbortFetch _PARAMS((StoreEntry * entry)); @@ -372,7 +362,6 @@ extern void redirectStats _PARAMS((StoreEntry *)); extern int redirectUnregister _PARAMS((const char *url, void *)); extern void redirectFreeMemory _PARAMS((void)); -extern void refreshFreeMemory _PARAMS((void)); extern void refreshAddToList _PARAMS((const char *, int, time_t, int, time_t)); extern int refreshCheck _PARAMS((const StoreEntry *, const request_t *, time_t delta)); extern time_t getMaxAge _PARAMS((const char *url)); @@ -384,13 +373,11 @@ extern void shut_down _PARAMS((int)); extern void start_announce _PARAMS((void *unused)); -extern void sslStart _PARAMS((int fd, const char *, request_t *, size_t *sz)); +extern void sslStart _PARAMS((int fd, const char *, request_t *, size_t * sz)); extern void waisStart _PARAMS((request_t *, StoreEntry *)); extern void storeDirClean _PARAMS((void *unused)); extern void passStart _PARAMS((int, const char *, request_t *, size_t *)); extern void identStart _PARAMS((int, ConnStateData *, IDCB * callback)); -extern int httpAnonAllowed _PARAMS((const char *line)); -extern int httpAnonDenied _PARAMS((const char *line)); extern void *pop _PARAMS((Stack *)); extern int empty_stack _PARAMS((const Stack *)); @@ -401,15 +388,10 @@ extern void stackFreeMemory _PARAMS((Stack *)); extern void stat_init _PARAMS((cacheinfo **, const char *)); extern void stat_get _PARAMS((const char *req, StoreEntry *)); -extern void log_clear _PARAMS((StoreEntry *)); -extern void log_disable _PARAMS((StoreEntry *)); extern void log_enable _PARAMS((StoreEntry *)); -extern void log_get_start _PARAMS((StoreEntry *)); -extern void log_status_get _PARAMS((StoreEntry *)); extern void info_get _PARAMS((StoreEntry *)); extern void server_list _PARAMS((StoreEntry *)); extern void parameter_get _PARAMS((StoreEntry *)); -extern void squid_get_start _PARAMS((StoreEntry *)); /* To reduce memory fragmentation, we now store the memory version of an * object in fixed size blocks of size PAGE_SIZE and instead of calling @@ -443,17 +425,11 @@ extern StoreEntry *storeCreateEntry _PARAMS((const char *, const char *, int, me extern void storeSetPublicKey _PARAMS((StoreEntry *)); extern StoreEntry *storeGetFirst _PARAMS((void)); extern StoreEntry *storeGetNext _PARAMS((void)); -extern StoreEntry *storeLRU _PARAMS((void)); -extern int storeWalkThrough _PARAMS((int (*proc) _PARAMS((void)), void *data)); -extern EVH storePurgeOld; extern void storeComplete _PARAMS((StoreEntry *)); extern void storeInit _PARAMS((void)); -extern int storeReleaseEntry _PARAMS((StoreEntry *)); extern int storeClientWaiting _PARAMS((const StoreEntry *)); -extern void storeAbort _PARAMS((StoreEntry *, log_type, const char *, int)); +extern void storeAbort _PARAMS((StoreEntry *, int)); extern void storeAppend _PARAMS((StoreEntry *, const char *, int)); -extern int storeGetMemSize _PARAMS((void)); -extern int storeGetSwapSize _PARAMS((void)); extern int storeGetSwapSpace _PARAMS((int)); extern void storeLockObject _PARAMS((StoreEntry *)); extern void storeSwapInStart _PARAMS((StoreEntry *, SIH *, void *data)); @@ -501,16 +477,6 @@ extern void storeAppendPrintf _PARAMS(()); extern char *storeSwapFullPath _PARAMS((int, char *)); extern char *storeSwapSubSubDir _PARAMS((int, char *)); -extern int storeAddSwapDisk _PARAMS((const char *, - int size, - int l1, - int l2, - int read_only)); -extern void storeReconfigureSwapDisk _PARAMS((const char *, - int size, - int l1, - int l2, - int read_only)); extern int storeVerifySwapDirs _PARAMS((void)); extern void storeCreateSwapSubDirs _PARAMS((int)); extern const char *storeSwapPath _PARAMS((int)); @@ -549,7 +515,6 @@ extern void normal_shutdown _PARAMS((void)); extern int percent _PARAMS((int, int)); extern void squid_signal _PARAMS((int sig, void (*func) _PARAMS((int)), int flags)); extern pid_t readPidFile _PARAMS((void)); -extern void _debug_trap _PARAMS((const char *message)); extern struct in_addr inaddrFromHostent _PARAMS((const struct hostent * hp)); extern int intAverage _PARAMS((int, int, int, int)); extern double doubleAverage _PARAMS((double, double, int, int)); @@ -574,9 +539,14 @@ extern int matchDomainName _PARAMS((const char *d, const char *h)); extern int urlCheckRequest _PARAMS((const request_t *)); extern int urlDefaultPort _PARAMS((protocol_t p)); extern char *urlClean _PARAMS((char *)); +extern char *urlCanonicalClean _PARAMS((const request_t *)); extern void useragentOpenLog _PARAMS((void)); extern void useragentRotateLog _PARAMS((void)); extern void logUserAgent _PARAMS((const char *, const char *)); extern peer_t parseNeighborType _PARAMS((const char *s)); + +extern void errorSend _PARAMS((int fd, ErrorState *)); +extern void errorAppendEntry _PARAMS((StoreEntry *, ErrorState *)); +extern void errorInitialize _PARAMS((void)); diff --git a/src/ssl.cc b/src/ssl.cc index 8bc28fea50..46666e4efe 100644 --- a/src/ssl.cc +++ b/src/ssl.cc @@ -1,6 +1,6 @@ /* - * $Id: ssl.cc,v 1.59 1997/07/21 07:21:01 wessels Exp $ + * $Id: ssl.cc,v 1.60 1997/07/28 06:41:03 wessels Exp $ * * DEBUG: section 26 Secure Sockets Layer Proxy * AUTHOR: Duane Wessels @@ -55,7 +55,7 @@ static void sslWriteServer _PARAMS((int fd, void *)); static void sslWriteClient _PARAMS((int fd, void *)); static void sslConnected _PARAMS((int fd, void *)); static void sslProxyConnected _PARAMS((int fd, void *)); -static void sslErrorComplete _PARAMS((int, char *, int, int, void *)); +static ERCB sslErrorComplete; static void sslClose _PARAMS((SslStateData * sslState)); static void sslClientClosed _PARAMS((int fd, void *)); static void sslConnectDone _PARAMS((int fd, int status, void *data)); @@ -306,13 +306,9 @@ sslConnected(int fd, void *data) } static void -sslErrorComplete(int fd, char *buf, int size, int errflag, void *sslState) +sslErrorComplete(int fd, void *sslState, int size) { - safe_free(buf); - if (sslState == NULL) { - debug_trap("sslErrorComplete: NULL sslState\n"); - return; - } + assert(sslState != NULL); sslClose(sslState); } @@ -322,35 +318,29 @@ sslConnectDone(int fd, int status, void *data) { SslStateData *sslState = data; request_t *request = sslState->request; - char *buf = NULL; + ErrorState *err = NULL; if (status == COMM_ERR_DNS) { debug(26, 4) ("sslConnect: Unknown host: %s\n", sslState->host); - buf = squid_error_url(sslState->url, - request->method, - ERR_DNS_FAIL, - fd_table[fd].ipaddr, - 500, - dns_error_message); - comm_write(sslState->client.fd, - xstrdup(buf), - strlen(buf), - sslErrorComplete, - sslState, - xfree); + err = xcalloc(1, sizeof(ErrorState)); + err->type = ERR_DNS_FAIL; + err->http_status = HTTP_NOT_FOUND; + err->request = requestLink(request); + err->dnsserver_msg = xstrdup(dns_error_message); + err->callback = sslErrorComplete; + err->callback_data = sslState; + errorSend(sslState->client.fd, err); return; } else if (status != COMM_OK) { - buf = squid_error_url(sslState->url, - sslState->request->method, - ERR_CONNECT_FAIL, - fd_table[fd].ipaddr, - 500, - xstrerror()); - comm_write(sslState->client.fd, - xstrdup(buf), - strlen(buf), - sslErrorComplete, - sslState, - xfree); + err = xcalloc(1, sizeof(ErrorState)); + err->type = ERR_CONNECT_FAIL; + err->http_status = HTTP_SERVICE_UNAVAILABLE; + err->errno = errno; + err->host = xstrdup(sslState->host); + err->port = sslState->port; + err->request = requestLink(request); + err->callback = sslErrorComplete; + err->callback_data = sslState; + errorSend(sslState->client.fd, err); return; } if (sslState->proxying) @@ -360,12 +350,12 @@ sslConnectDone(int fd, int status, void *data) } void -sslStart(int fd, const char *url, request_t * request, size_t *size_ptr) +sslStart(int fd, const char *url, request_t * request, size_t * size_ptr) { /* Create state structure. */ SslStateData *sslState = NULL; int sock; - char *buf = NULL; + ErrorState *err = NULL; debug(26, 3) ("sslStart: '%s %s'\n", RequestMethodStr[request->method], url); /* Create socket. */ @@ -377,18 +367,12 @@ sslStart(int fd, const char *url, request_t * request, size_t *size_ptr) url); if (sock == COMM_ERROR) { debug(26, 4) ("sslStart: Failed because we're out of sockets.\n"); - buf = squid_error_url(url, - request->method, - ERR_NO_FDS, - fd_table[fd].ipaddr, - 500, - xstrerror()); - comm_write(fd, - xstrdup(buf), - strlen(buf), - NULL, - NULL, - xfree); + err = xcalloc(1, sizeof(ErrorState)); + err->type = ERR_SOCKET_FAILURE; + err->http_status = HTTP_INTERNAL_SERVER_ERROR; + err->errno = errno; + err->request = requestLink(request); + errorSend(fd, err); return; } sslState = xcalloc(1, sizeof(SslStateData)); @@ -469,6 +453,12 @@ static void sslPeerSelectFail(peer * p, void *data) { SslStateData *sslState = data; - squid_error_request(sslState->url, ERR_CANNOT_FETCH, 400); - sslClose(sslState); + ErrorState *err = xcalloc(1, sizeof(ErrorState)); + err->type = ERR_CANNOT_FORWARD; + err->http_status = HTTP_SERVICE_UNAVAILABLE; + err->request = requestLink(sslState->request); + err->callback = sslErrorComplete; + err->callback_data = sslState; + errorSend(sslState->client.fd, err); + } diff --git a/src/stat.cc b/src/stat.cc index d667c96472..413f5f9f31 100644 --- a/src/stat.cc +++ b/src/stat.cc @@ -1,6 +1,6 @@ /* - * $Id: stat.cc,v 1.149 1997/07/16 20:32:17 wessels Exp $ + * $Id: stat.cc,v 1.150 1997/07/28 06:41:03 wessels Exp $ * * DEBUG: section 18 Cache Manager Statistics * AUTHOR: Harvest Derived @@ -287,14 +287,8 @@ describeFlags(const StoreEntry * entry) buf[0] = '\0'; if (BIT_TEST(flags, DELETE_BEHIND)) strcat(buf, "DB,"); -#ifdef OLD_CODE - if (BIT_TEST(flags, CLIENT_ABORT_REQUEST)) - strcat(buf, "CA,"); -#endif if (BIT_TEST(flags, DELAY_SENDING)) strcat(buf, "DS,"); - if (BIT_TEST(flags, ABORT_MSG_PENDING)) - strcat(buf, "AP,"); if (BIT_TEST(flags, RELEASE_REQUEST)) strcat(buf, "RL,"); if (BIT_TEST(flags, REFRESH_REQUEST)) diff --git a/src/store.cc b/src/store.cc index 349d4ba862..aaeabfff4c 100644 --- a/src/store.cc +++ b/src/store.cc @@ -1,6 +1,6 @@ /* - * $Id: store.cc,v 1.277 1997/07/19 01:33:58 wessels Exp $ + * $Id: store.cc,v 1.278 1997/07/28 06:41:05 wessels Exp $ * * DEBUG: section 20 Storeage Manager * AUTHOR: Harvest Derived @@ -362,7 +362,6 @@ destroy_MemObject(MemObject * mem) meta_data.url_strings -= strlen(mem->log_url); safe_free(mem->clients); safe_free(mem->reply); - safe_free(mem->e_abort_msg); safe_free(mem->log_url); requestUnlink(mem->request); mem->request = NULL; @@ -558,7 +557,6 @@ storeReleaseRequest(StoreEntry * e) int storeUnlockObject(StoreEntry * e) { - MemObject *mem = e->mem_obj; e->lock_count--; debug(20, 3) ("storeUnlockObject: key '%s' count=%d\n", e->key, e->lock_count); @@ -571,17 +569,6 @@ storeUnlockObject(StoreEntry * e) assert(storePendingNClients(e) == 0); if (BIT_TEST(e->flag, RELEASE_REQUEST)) { storeRelease(e); - } else if (BIT_TEST(e->flag, ABORT_MSG_PENDING)) { - /* This is where the negative cache gets storeAppended */ - /* Briefly lock to replace content with abort message */ - e->lock_count++; - destroy_MemObjectData(mem); - e->object_len = 0; - mem->data = new_MemObjectData(); - storeAppend(e, mem->e_abort_msg, strlen(mem->e_abort_msg)); - e->object_len = mem->e_current_len = strlen(mem->e_abort_msg); - BIT_RESET(e->flag, ABORT_MSG_PENDING); - e->lock_count--; } else if (storeShouldPurgeMem(e)) { storePurgeMem(e); } @@ -1679,16 +1666,12 @@ storeComplete(StoreEntry * e) * entry for releasing */ void -storeAbort(StoreEntry * e, log_type abort_code, const char *msg, int cbflag) +storeAbort(StoreEntry * e, int cbflag) { MemObject *mem = e->mem_obj; assert(e->store_status == STORE_PENDING); assert(mem != NULL); - safe_free(mem->e_abort_msg); - if (msg) - mem->e_abort_msg = xstrdup(msg); - debug(20, 6) ("storeAbort: %s %s\n", log_tags[abort_code], e->key); - mem->abort_code = abort_code; + debug(20, 6) ("storeAbort: %s\n", e->key); storeNegativeCache(e); storeReleaseRequest(e); e->store_status = STORE_ABORTED; @@ -2524,7 +2507,8 @@ storeWriteCleanLogs(void) static int swapInError(int fd_unused, StoreEntry * entry) { - storeAbort(entry, ERR_DISK_IO, xstrerror(), 1); + debug(20, 0) ("swapInError: %s\n", entry->url); + storeAbort(entry, 1); return 0; } @@ -2799,11 +2783,6 @@ storeMemObjectDump(MemObject * mem) mem->e_swap_buf_len); debug(20, 1) ("MemObject->pending_list_size: %d\n", mem->pending_list_size); - debug(20, 1) ("MemObject->e_abort_msg: %p %s\n", - mem->e_abort_msg, - checkNullString(mem->e_abort_msg)); - debug(20, 1) ("MemObject->abort_code: %d %s\n", - mem->abort_code, log_tags[mem->abort_code]); debug(20, 1) ("MemObject->e_current_len: %d\n", mem->e_current_len); debug(20, 1) ("MemObject->e_lowest_offset: %d\n", diff --git a/src/structs.h b/src/structs.h index b6b64ed5b3..f6256aca8b 100644 --- a/src/structs.h +++ b/src/structs.h @@ -201,11 +201,11 @@ struct _SquidConfig { int query_icmp; int icp_hit_stale; int buffered_logs; - int source_ping; - int common_log; - int log_mime_hdrs; - int ident_lookup; - int single_parent_bypass; + int source_ping; + int common_log; + int log_mime_hdrs; + int ident_lookup; + int single_parent_bypass; int log_fqdn; int announce; int accel_with_proxy; @@ -237,6 +237,7 @@ struct _SquidConfig { char *directory; char *content_type; } icons; + char *errorDirectory; }; struct _SquidConfig2 { @@ -452,7 +453,7 @@ struct _clientHttpRequest { StoreEntry *entry; StoreEntry *old_entry; log_type log_type; - int http_code; + http_status http_code; int accel; struct timeval start; float http_ver; @@ -731,8 +732,6 @@ struct _MemObject { int p_rtt; /* parent's RTT to source */ int e_swap_buf_len; unsigned char pending_list_size; - char *e_abort_msg; - log_type abort_code; int e_current_len; off_t e_lowest_offset; struct _store_client *clients; @@ -833,3 +832,19 @@ struct _CommWriteStateData { void *handler_data; FREE *free; }; + +struct _ErrorState { + err_type type; + http_status http_status; + request_t *request; + char *url; + int errno; + char *host; + u_short port; + char *dnsserver_msg; + time_t ttl; + struct in_addr src_addr; + char *redirect_url; + ERCB *callback; + void *callback_data; +}; diff --git a/src/tunnel.cc b/src/tunnel.cc index abf0fbb9d8..0b10c634ee 100644 --- a/src/tunnel.cc +++ b/src/tunnel.cc @@ -1,6 +1,6 @@ /* - * $Id: tunnel.cc,v 1.59 1997/07/21 07:21:01 wessels Exp $ + * $Id: tunnel.cc,v 1.60 1997/07/28 06:41:03 wessels Exp $ * * DEBUG: section 26 Secure Sockets Layer Proxy * AUTHOR: Duane Wessels @@ -55,7 +55,7 @@ static void sslWriteServer _PARAMS((int fd, void *)); static void sslWriteClient _PARAMS((int fd, void *)); static void sslConnected _PARAMS((int fd, void *)); static void sslProxyConnected _PARAMS((int fd, void *)); -static void sslErrorComplete _PARAMS((int, char *, int, int, void *)); +static ERCB sslErrorComplete; static void sslClose _PARAMS((SslStateData * sslState)); static void sslClientClosed _PARAMS((int fd, void *)); static void sslConnectDone _PARAMS((int fd, int status, void *data)); @@ -306,13 +306,9 @@ sslConnected(int fd, void *data) } static void -sslErrorComplete(int fd, char *buf, int size, int errflag, void *sslState) +sslErrorComplete(int fd, void *sslState, int size) { - safe_free(buf); - if (sslState == NULL) { - debug_trap("sslErrorComplete: NULL sslState\n"); - return; - } + assert(sslState != NULL); sslClose(sslState); } @@ -322,35 +318,29 @@ sslConnectDone(int fd, int status, void *data) { SslStateData *sslState = data; request_t *request = sslState->request; - char *buf = NULL; + ErrorState *err = NULL; if (status == COMM_ERR_DNS) { debug(26, 4) ("sslConnect: Unknown host: %s\n", sslState->host); - buf = squid_error_url(sslState->url, - request->method, - ERR_DNS_FAIL, - fd_table[fd].ipaddr, - 500, - dns_error_message); - comm_write(sslState->client.fd, - xstrdup(buf), - strlen(buf), - sslErrorComplete, - sslState, - xfree); + err = xcalloc(1, sizeof(ErrorState)); + err->type = ERR_DNS_FAIL; + err->http_status = HTTP_NOT_FOUND; + err->request = requestLink(request); + err->dnsserver_msg = xstrdup(dns_error_message); + err->callback = sslErrorComplete; + err->callback_data = sslState; + errorSend(sslState->client.fd, err); return; } else if (status != COMM_OK) { - buf = squid_error_url(sslState->url, - sslState->request->method, - ERR_CONNECT_FAIL, - fd_table[fd].ipaddr, - 500, - xstrerror()); - comm_write(sslState->client.fd, - xstrdup(buf), - strlen(buf), - sslErrorComplete, - sslState, - xfree); + err = xcalloc(1, sizeof(ErrorState)); + err->type = ERR_CONNECT_FAIL; + err->http_status = HTTP_SERVICE_UNAVAILABLE; + err->errno = errno; + err->host = xstrdup(sslState->host); + err->port = sslState->port; + err->request = requestLink(request); + err->callback = sslErrorComplete; + err->callback_data = sslState; + errorSend(sslState->client.fd, err); return; } if (sslState->proxying) @@ -360,12 +350,12 @@ sslConnectDone(int fd, int status, void *data) } void -sslStart(int fd, const char *url, request_t * request, size_t *size_ptr) +sslStart(int fd, const char *url, request_t * request, size_t * size_ptr) { /* Create state structure. */ SslStateData *sslState = NULL; int sock; - char *buf = NULL; + ErrorState *err = NULL; debug(26, 3) ("sslStart: '%s %s'\n", RequestMethodStr[request->method], url); /* Create socket. */ @@ -377,18 +367,12 @@ sslStart(int fd, const char *url, request_t * request, size_t *size_ptr) url); if (sock == COMM_ERROR) { debug(26, 4) ("sslStart: Failed because we're out of sockets.\n"); - buf = squid_error_url(url, - request->method, - ERR_NO_FDS, - fd_table[fd].ipaddr, - 500, - xstrerror()); - comm_write(fd, - xstrdup(buf), - strlen(buf), - NULL, - NULL, - xfree); + err = xcalloc(1, sizeof(ErrorState)); + err->type = ERR_SOCKET_FAILURE; + err->http_status = HTTP_INTERNAL_SERVER_ERROR; + err->errno = errno; + err->request = requestLink(request); + errorSend(fd, err); return; } sslState = xcalloc(1, sizeof(SslStateData)); @@ -469,6 +453,12 @@ static void sslPeerSelectFail(peer * p, void *data) { SslStateData *sslState = data; - squid_error_request(sslState->url, ERR_CANNOT_FETCH, 400); - sslClose(sslState); + ErrorState *err = xcalloc(1, sizeof(ErrorState)); + err->type = ERR_CANNOT_FORWARD; + err->http_status = HTTP_SERVICE_UNAVAILABLE; + err->request = requestLink(sslState->request); + err->callback = sslErrorComplete; + err->callback_data = sslState; + errorSend(sslState->client.fd, err); + } diff --git a/src/typedefs.h b/src/typedefs.h index 3ce4a398dc..89b0ab310b 100644 --- a/src/typedefs.h +++ b/src/typedefs.h @@ -71,6 +71,7 @@ typedef struct _AccessLogEntry AccessLogEntry; typedef struct _cachemgr_passwd cachemgr_passwd; typedef struct _refresh_t refresh_t; typedef struct _CommWriteStateData CommWriteStateData; +typedef struct _ErrorState ErrorState; typedef void AIOCB _PARAMS((void *, int aio_return, int aio_errno)); typedef void CWCB _PARAMS((int fd, char *, int size, int errflag, void *data)); @@ -96,3 +97,4 @@ typedef void SIH _PARAMS((void *, int)); /* swap in */ typedef int QS _PARAMS((const void *, const void *)); /* qsort */ typedef void STCB _PARAMS((void *, char *, ssize_t)); /* store callback */ typedef void STABH _PARAMS((void *)); +typedef void ERCB _PARAMS((int fd, void *, int size)); diff --git a/src/wais.cc b/src/wais.cc index e46423e834..68212b5e39 100644 --- a/src/wais.cc +++ b/src/wais.cc @@ -1,6 +1,6 @@ /* - * $Id: wais.cc,v 1.79 1997/07/14 23:45:08 wessels Exp $ + * $Id: wais.cc,v 1.80 1997/07/28 06:41:07 wessels Exp $ * * DEBUG: section 24 WAIS Relay * AUTHOR: Harvest Derived @@ -144,7 +144,8 @@ waisTimeout(int fd, void *data) WaisStateData *waisState = data; StoreEntry *entry = waisState->entry; debug(24, 4) ("waisTimeout: FD %d: '%s'\n", fd, entry->url); - storeAbort(entry, ERR_READ_TIMEOUT, NULL, 0); + assert(!ERR_READ_TIMEOUT); + storeAbort(entry, 0); comm_close(fd); } @@ -163,13 +164,15 @@ waisReadReply(int fd, void *data) int off; int bin; if (protoAbortFetch(entry)) { - storeAbort(entry, ERR_CLIENT_ABORT, NULL, 0); + assert(!ERR_CLIENT_ABORT); + storeAbort(entry, 0); comm_close(fd); return; } if (entry->flag & DELETE_BEHIND && !storeClientWaiting(entry)) { /* we can terminate connection right now */ - storeAbort(entry, ERR_NO_CLIENTS_BIG_OBJ, NULL, 0); + assert(!ERR_NO_CLIENTS); + storeAbort(entry, 0); comm_close(fd); return; } @@ -218,11 +221,13 @@ waisReadReply(int fd, void *data) } else { BIT_RESET(entry->flag, ENTRY_CACHABLE); storeReleaseRequest(entry); - storeAbort(entry, ERR_READ_ERROR, xstrerror(), 0); + assert(!ERR_READ_ERROR); + storeAbort(entry, 0); comm_close(fd); } } else if (len == 0 && entry->mem_obj->e_current_len == 0) { - storeAbort(entry, ERR_ZERO_SIZE_OBJECT, errno ? xstrerror() : NULL, 0); + assert(!ERR_ZERO_SIZE_OBJECT); + storeAbort(entry, 0); comm_close(fd); } else if (len == 0) { /* Connection closed; retrieval done. */ @@ -248,7 +253,8 @@ waisSendComplete(int fd, char *buf, int size, int errflag, void *data) debug(24, 5) ("waisSendComplete: FD %d size: %d errflag: %d\n", fd, size, errflag); if (errflag) { - storeAbort(entry, ERR_CONNECT_FAIL, xstrerror(), 0); + assert(!ERR_CONNECT_FAIL); + storeAbort(entry, 0); comm_close(fd); } else { /* Schedule read reply. */ @@ -303,7 +309,8 @@ waisStart(request_t * request, StoreEntry * entry) debug(24, 3) ("waisStart: \"%s %s\"\n", RequestMethodStr[method], url); if (!Config.Wais.relayHost) { debug(24, 0) ("waisStart: Failed because no relay host defined!\n"); - storeAbort(entry, ERR_NO_RELAY, NULL, 0); + assert(!ERR_NO_RELAY); + storeAbort(entry, 0); return; } fd = comm_open(SOCK_STREAM, @@ -314,7 +321,8 @@ waisStart(request_t * request, StoreEntry * entry) url); if (fd == COMM_ERROR) { debug(24, 4) ("waisStart: Failed because we're out of sockets.\n"); - storeAbort(entry, ERR_NO_FDS, xstrerror(), 0); + assert(!ERR_SOCKET_FAILURE); + storeAbort(entry, 0); return; } waisState = xcalloc(1, sizeof(WaisStateData)); @@ -342,10 +350,12 @@ waisConnectDone(int fd, int status, void *data) { WaisStateData *waisState = data; if (status == COMM_ERR_DNS) { - storeAbort(waisState->entry, ERR_DNS_FAIL, dns_error_message, 0); + assert(!ERR_DNS_FAIL); + storeAbort(waisState->entry, 0); comm_close(fd); } else if (status != COMM_OK) { - storeAbort(waisState->entry, ERR_CONNECT_FAIL, xstrerror(), 0); + assert(!ERR_CONNECT_FAIL); + storeAbort(waisState->entry, 0); comm_close(fd); } else { commSetSelect(fd, COMM_SELECT_WRITE, waisSendRequest, waisState, 0);