=== modified file 'src/errorpage.cc' --- src/errorpage.cc 2013-01-28 16:56:05 +0000 +++ src/errorpage.cc 2013-01-30 16:29:12 +0000 @@ -557,143 +557,139 @@ } /// \ingroup ErrorPageInternal 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 < (ssize_t)ErrorDynamicPages.size()) return ErrorDynamicPages.items[pageId - ERR_MAX]->page_name; return "ERR_UNKNOWN"; /* should not happen */ } ErrorState::ErrorState(err_type t, http_status status, HttpRequest * req) : type(t), page_id(t), err_language(NULL), httpStatus(status), #if USE_AUTH auth_user_request (NULL), #endif request(NULL), url(NULL), xerrno(0), port(0), dnsError(), ttl(0), src_addr(), redirect_url(NULL), callback(NULL), callback_data(NULL), request_hdrs(NULL), err_msg(NULL), #if USE_SSL detail(NULL), #endif detailCode(ERR_DETAIL_NONE) { - memset(&flags, 0, sizeof(flags)); memset(&ftp, 0, sizeof(ftp)); if (page_id >= ERR_MAX && ErrorDynamicPages.items[page_id - ERR_MAX]->page_redirect != HTTP_STATUS_NONE) httpStatus = ErrorDynamicPages.items[page_id - ERR_MAX]->page_redirect; if (req != NULL) { request = HTTPMSGLOCK(req); src_addr = req->client_addr; } } void errorAppendEntry(StoreEntry * entry, ErrorState * err) { assert(entry->mem_obj != NULL); assert (entry->isEmpty()); debugs(4, 4, "Creating an error page for entry " << entry << " with errorstate " << err << " page id " << err->page_id); if (entry->store_status != STORE_PENDING) { debugs(4, 2, "Skipping error page due to store_status: " << entry->store_status); /* * 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(entry->mem_obj->nclients == 0); delete err; return; } if (err->page_id == TCP_RESET) { if (err->request) { debugs(4, 2, "RSTing this reply"); err->request->flags.resetTcp = true; } } entry->lock(); entry->buffer(); entry->replaceHttpReply( err->BuildHttpReply() ); EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT); entry->flush(); entry->complete(); entry->negativeCache(); entry->releaseRequest(); entry->unlock(); delete err; } void errorSend(const Comm::ConnectionPointer &conn, ErrorState * err) { HttpReply *rep; debugs(4, 3, HERE << conn << ", err=" << err); assert(Comm::IsConnOpen(conn)); - /* moved in front of errorBuildBuf @?@ */ - err->flags.flag_cbdata = 1; - rep = err->BuildHttpReply(); MemBuf *mb = rep->pack(); AsyncCall::Pointer call = commCbCall(78, 5, "errorSendComplete", CommIoCbPtrFun(&errorSendComplete, err)); Comm::Write(conn, mb, call); delete mb; delete rep; } /** \ingroup ErrorPageAPI * * Called by commHandleWrite() after data has been written * to the client socket. * \note If there is a callback, the callback is responsible for * closing the FD, otherwise we do it ourselves. */ static void errorSendComplete(const Comm::ConnectionPointer &conn, char *bufnotused, size_t size, comm_err_t errflag, int xerrno, void *data) { ErrorState *err = static_cast(data); debugs(4, 3, HERE << conn << ", size=" << size); if (errflag != COMM_ERR_CLOSING) { if (err->callback) { debugs(4, 3, "errorSendComplete: callback"); err->callback(conn->fd, err->callback_data, size); } else { debugs(4, 3, "errorSendComplete: comm_close"); conn->close(); } } delete err; } ErrorState::~ErrorState() === modified file 'src/errorpage.h' --- src/errorpage.h 2012-10-03 17:32:57 +0000 +++ src/errorpage.h 2013-01-30 16:29:12 +0000 @@ -133,84 +133,80 @@ /** * Map the Error page and deny_info template % codes into textual output. * * Several of the codes produce blocks of non-URL compatible results. * When processing the deny_info location URL they will be skipped. * * \param token The token following % which need to be converted * \param building_deny_info_url Perform special deny_info actions, such as URL-encoding and token skipping. * \ allowRecursion True if the codes which do recursions should converted */ const char *Convert(char token, bool building_deny_info_url, bool allowRecursion); /** * CacheManager / Debug dump of the ErrorState object. * Writes output into the given MemBuf. \retval 0 successful completion. */ int Dump(MemBuf * mb); public: err_type type; int page_id; char *err_language; http_status httpStatus; #if USE_AUTH Auth::UserRequest::Pointer auth_user_request; #endif HttpRequest *request; char *url; int xerrno; unsigned short port; String dnsError; ///< DNS lookup error message time_t ttl; Ip::Address src_addr; char *redirect_url; ERCB *callback; void *callback_data; struct { - unsigned int flag_cbdata:1; - } flags; - - struct { wordlist *server_msg; char *request; char *reply; char *cwd_msg; MemBuf *listing; } ftp; char *request_hdrs; char *err_msg; /* Preformatted error message from the cache */ #if USE_SSL Ssl::ErrorDetail *detail; #endif /// type-specific detail about the transaction error; /// overwrites xerrno; overwritten by detail, if any. int detailCode; private: CBDATA_CLASS2(ErrorState); }; /** \ingroup ErrorPageAPI * * This function finds the error messages formats, and stores * them in error_text[] * \par Global effects: * error_text[] - is modified */ void errorInitialize(void); /// \ingroup ErrorPageAPI void errorClean(void); /** * \ingroup ErrorPageAPI * * 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