Return-Path: Delivered-To: apmail-apache-cvs-archive@apache.org Received: (qmail 91954 invoked by uid 500); 26 Sep 2000 23:01:57 -0000 Mailing-List: contact apache-cvs-help@apache.org; run by ezmlm Precedence: bulk Reply-To: new-httpd@apache.org list-help: list-unsubscribe: list-post: Delivered-To: mailing list apache-cvs@apache.org Received: (qmail 91943 invoked by uid 500); 26 Sep 2000 23:01:56 -0000 Delivered-To: apmail-apache-2.0-cvs@apache.org Date: 26 Sep 2000 23:01:56 -0000 Message-ID: <20000926230156.91938.qmail@locus.apache.org> From: gregames@locus.apache.org To: apache-2.0-cvs@apache.org Subject: cvs commit: apache-2.0/src/main http_protocol.c gregames 00/09/26 16:01:55 Modified: src/main http_protocol.c Log: Create a helper function "get_canned_error_string" for use by ap_send_error_response. The new function simply returns the error response string corresponding to given HTTP error core. This makes it easier to change the mechanism for sending these strings, because we no longer have r[v]puts calls spread throughout the error string generation code. Revision Changes Path 1.132 +239 -223 apache-2.0/src/main/http_protocol.c Index: http_protocol.c =================================================================== RCS file: /home/cvs/apache-2.0/src/main/http_protocol.c,v retrieving revision 1.131 retrieving revision 1.132 diff -u -r1.131 -r1.132 --- http_protocol.c 2000/09/23 18:39:29 1.131 +++ http_protocol.c 2000/09/26 23:01:55 1.132 @@ -2838,6 +2838,243 @@ return 0; } +static const char *add_optional_notes(request_rec *r, + const char *prefix, + const char *key, + const char *suffix) +{ + const char *notes, *result; + + if ((notes = apr_table_get(r->notes, key)) == NULL) { + result = prefix; + } + else { + result = apr_pstrcat(r->pool, prefix, notes, suffix, NULL); + } + + return result; +} + +static const char *get_canned_error_string(int status, + request_rec *r, + const char *location) + +/* construct and return the default error message for a given + * HTTP defined error code + */ +{ + apr_pool_t *p = r->pool; + const char *error_notes, *h1, *s1; + + switch (status) { + case HTTP_MOVED_PERMANENTLY: + case HTTP_MOVED_TEMPORARILY: + case HTTP_TEMPORARY_REDIRECT: + return(apr_pstrcat(p, + "The document has moved pool, location), + "\">here.

\n", + NULL)); + case HTTP_SEE_OTHER: + return(apr_pstrcat(p, + "The answer to your request is located pool, location), + "\">here.

\n", + NULL)); + case HTTP_USE_PROXY: + return(apr_pstrcat(p, + "This resource is only accessible " + "through the proxy\n", + ap_escape_html(r->pool, location), + "
\nYou will need to " + "configure your client to use that proxy.

\n", + NULL)); + case HTTP_PROXY_AUTHENTICATION_REQUIRED: + case HTTP_UNAUTHORIZED: + return("This server could not verify that you\n" + "are authorized to access the document\n" + "requested. Either you supplied the wrong\n" + "credentials (e.g., bad password), or your\n" + "browser doesn't understand how to supply\n" + "the credentials required.

\n"); + case HTTP_BAD_REQUEST: + return(add_optional_notes(r, + "Your browser sent a request that " + "this server could not understand.

\n", + "error-notes", + "

\n")); + case HTTP_FORBIDDEN: + return(apr_pstrcat(p, + "You don't have permission to access ", + ap_escape_html(r->pool, r->uri), + "\non this server.

\n", + NULL)); + case HTTP_NOT_FOUND: + return(apr_pstrcat(p, + "The requested URL ", + ap_escape_html(r->pool, r->uri), + " was not found on this server.

\n", + NULL)); + case HTTP_METHOD_NOT_ALLOWED: + return(apr_pstrcat(p, + "The requested method ", r->method, + " is not allowed for the URL ", + ap_escape_html(r->pool, r->uri), + ".

\n", + NULL)); + case HTTP_NOT_ACCEPTABLE: + s1 = apr_pstrcat(p, + "An appropriate representation of the " + "requested resource ", + ap_escape_html(r->pool, r->uri), + " could not be found on this server.

\n", + NULL); + return(add_optional_notes(r, s1, "variant-list", "")); + case HTTP_MULTIPLE_CHOICES: + return(add_optional_notes(r, "", "variant-list", "")); + case HTTP_LENGTH_REQUIRED: + s1 = apr_pstrcat(p, + "A request of the requested method ", + r->method, + " requires a valid Content-length.

\n", + NULL); + return(add_optional_notes(r, s1, "error-notes", "

\n")); + case HTTP_PRECONDITION_FAILED: + return(apr_pstrcat(p, + "The precondition on the request for the URL ", + ap_escape_html(r->pool, r->uri), + " evaluated to false.

\n", + NULL)); + case HTTP_NOT_IMPLEMENTED: + s1 = apr_pstrcat(p, + ap_escape_html(r->pool, r->method), " to ", + ap_escape_html(r->pool, r->uri), + " not supported.

\n", + NULL); + return(add_optional_notes(r, s1, "error-notes", "

\n")); + case HTTP_BAD_GATEWAY: + s1 = "The proxy server received an invalid" CRLF + "response from an upstream server.

" CRLF; + return(add_optional_notes(r, s1, "error-notes", "

\n")); + case HTTP_VARIANT_ALSO_VARIES: + return(apr_pstrcat(p, + "A variant for the requested resource\n

\n",
  +		                   ap_escape_html(r->pool, r->uri),
  +		                   "\n
\nis itself a negotiable resource. " + "This indicates a configuration error.

\n", + NULL)); + case HTTP_REQUEST_TIME_OUT: + return("I'm tired of waiting for your request.\n"); + case HTTP_GONE: + return(apr_pstrcat(p, + "The requested resource
", + ap_escape_html(r->pool, r->uri), + "
\nis no longer available on this server " + "and there is no forwarding address.\n" + "Please remove all references to this resource.\n", + NULL)); + case HTTP_REQUEST_ENTITY_TOO_LARGE: + return(apr_pstrcat(p, + "The requested resource
", + ap_escape_html(r->pool, r->uri), "
\n", + "does not allow request data with ", + r->method, + " requests, or the amount of data provided in\n" + "the request exceeds the capacity limit.\n", + NULL)); + case HTTP_REQUEST_URI_TOO_LARGE: + s1 = "The requested URL's length exceeds the capacity\n" + "limit for this server.

\n"; + return(add_optional_notes(r, s1, "error-notes", "

\n")); + case HTTP_UNSUPPORTED_MEDIA_TYPE: + return("The supplied request data is not in a format\n" + "acceptable for processing by this resource.\n"); + case HTTP_RANGE_NOT_SATISFIABLE: + return("None of the range-specifier values in the Range\n" + "request-header field overlap the current extent\n" + "of the selected resource.\n"); + case HTTP_EXPECTATION_FAILED: + return(apr_pstrcat(p, + "The expectation given in the Expect request-header" + "\nfield could not be met by this server.

\n" + "The client sent

\n    Expect: ",
  +	                       apr_table_get(r->headers_in, "Expect"), "\n
\n" + "but we only allow the 100-continue expectation.\n", + NULL)); + case HTTP_UNPROCESSABLE_ENTITY: + return("The server understands the media type of the\n" + "request entity, but was unable to process the\n" + "contained instructions.\n"); + case HTTP_LOCKED: + return("The requested resource is currently locked.\n" + "The lock must be released or proper identification\n" + "given before the method can be applied.\n"); + case HTTP_FAILED_DEPENDENCY: + return("The method could not be performed on the resource\n" + "because the requested action depended on another\n" + "action and that other action failed.\n"); + case HTTP_INSUFFICIENT_STORAGE: + return("The method could not be performed on the resource\n" + "because the server is unable to store the\n" + "representation needed to successfully complete the\n" + "request. There is insufficient free space left in\n" + "your storage allocation.\n"); + case HTTP_SERVICE_UNAVAILABLE: + return("The server is temporarily unable to service your\n" + "request due to maintenance downtime or capacity\n" + "problems. Please try again later.\n"); + case HTTP_GATEWAY_TIME_OUT: + return("The proxy server did not receive a timely response\n" + "from the upstream server.\n"); + case HTTP_NOT_EXTENDED: + return("A mandatory extension policy in the request is not\n" + "accepted by the server for this resource.\n"); + default: /* HTTP_INTERNAL_SERVER_ERROR */ + /* + * This comparison to expose error-notes could be modified to + * use a configuration directive and export based on that + * directive. For now "*" is used to designate an error-notes + * that is totally safe for any user to see (ie lacks paths, + * database passwords, etc.) + */ + if (((error_notes = apr_table_get(r->notes, "error-notes")) != NULL) + && (h1 = apr_table_get(r->notes, "verbose-error-to")) != NULL + && (strcmp(h1, "*") == 0)) { + return(apr_pstrcat(p, error_notes, "

\n", NULL)); + } + else { + return(apr_pstrcat(p, + "The server encountered an internal error or\n" + "misconfiguration and was unable to complete\n" + "your request.

\n" + "Please contact the server administrator,\n ", + ap_escape_html(r->pool, r->server->server_admin), + " and inform them of the time the error occurred,\n" + "and anything you might have done that may have\n" + "caused the error.

\n" + "More information about this error may be available\n" + "in the server error log.

\n", + NULL)); + } + /* + * It would be nice to give the user the information they need to + * fix the problem directly since many users don't have access to + * the error_log (think University sites) even though they can easily + * get this error by misconfiguring an htaccess file. However, the + e error notes tend to include the real file pathname in this case, + * which some people consider to be a breach of privacy. Until we + * can figure out a way to remove the pathname, leave this commented. + * + * if ((error_notes = apr_table_get(r->notes, "error-notes")) != NULL) { + * return(apr_pstrcat(p, error_notes, "

\n", NULL); + * } + * else { + * return ""; + * } + */ + } +} + /* We should have named this send_canned_response, since it is used for any * response that can be generated by the server from the request record. * This includes all 204 (no content), 3xx (redirect), 4xx (client error), @@ -2973,7 +3210,6 @@ { const char *title = status_lines[idx]; const char *h1; - const char *error_notes; /* Accept a status_line set by a module, but only if it begins * with the 3 digit status code @@ -2996,228 +3232,8 @@ "\n", title, "\n\n

", h1, "

\n", NULL); - - switch (status) { - case HTTP_MOVED_PERMANENTLY: - case HTTP_MOVED_TEMPORARILY: - case HTTP_TEMPORARY_REDIRECT: - ap_rvputs(r, "The document has moved pool, location), "\">here.

\n", - NULL); - break; - case HTTP_SEE_OTHER: - ap_rvputs(r, "The answer to your request is located pool, location), "\">here.

\n", - NULL); - break; - case HTTP_USE_PROXY: - ap_rvputs(r, "This resource is only accessible " - "through the proxy\n", - ap_escape_html(r->pool, location), - "
\nYou will need to ", - "configure your client to use that proxy.

\n", NULL); - break; - case HTTP_PROXY_AUTHENTICATION_REQUIRED: - case HTTP_UNAUTHORIZED: - ap_rputs("This server could not verify that you\n" - "are authorized to access the document\n" - "requested. Either you supplied the wrong\n" - "credentials (e.g., bad password), or your\n" - "browser doesn't understand how to supply\n" - "the credentials required.

\n", r); - break; - case HTTP_BAD_REQUEST: - ap_rputs("Your browser sent a request that " - "this server could not understand.

\n", r); - if ((error_notes = apr_table_get(r->notes, "error-notes")) - != NULL) { - ap_rvputs(r, error_notes, "

\n", NULL); - } - break; - case HTTP_FORBIDDEN: - ap_rvputs(r, "You don't have permission to access ", - ap_escape_html(r->pool, r->uri), - "\non this server.

\n", NULL); - break; - case HTTP_NOT_FOUND: - ap_rvputs(r, "The requested URL ", - ap_escape_html(r->pool, r->uri), - " was not found on this server.

\n", NULL); - break; - case HTTP_METHOD_NOT_ALLOWED: - ap_rvputs(r, "The requested method ", r->method, - " is not allowed " - "for the URL ", ap_escape_html(r->pool, r->uri), - ".

\n", NULL); - break; - case HTTP_NOT_ACCEPTABLE: - ap_rvputs(r, - "An appropriate representation of the " - "requested resource ", - ap_escape_html(r->pool, r->uri), - " could not be found on this server.

\n", NULL); - /* fall through */ - case HTTP_MULTIPLE_CHOICES: - { - const char *list; - if ((list = apr_table_get(r->notes, "variant-list"))) - ap_rputs(list, r); - } - break; - case HTTP_LENGTH_REQUIRED: - ap_rvputs(r, "A request of the requested method ", r->method, - " requires a valid Content-length.

\n", NULL); - if ((error_notes = apr_table_get(r->notes, "error-notes")) - != NULL) { - ap_rvputs(r, error_notes, "

\n", NULL); - } - break; - case HTTP_PRECONDITION_FAILED: - ap_rvputs(r, "The precondition on the request for the URL ", - ap_escape_html(r->pool, r->uri), - " evaluated to false.

\n", NULL); - break; - case HTTP_NOT_IMPLEMENTED: - ap_rvputs(r, ap_escape_html(r->pool, r->method), " to ", - ap_escape_html(r->pool, r->uri), - " not supported.

\n", NULL); - if ((error_notes = apr_table_get(r->notes, "error-notes")) - != NULL) { - ap_rvputs(r, error_notes, "

\n", NULL); - } - break; - case HTTP_BAD_GATEWAY: - ap_rputs("The proxy server received an invalid" CRLF - "response from an upstream server.

" CRLF, r); - if ((error_notes = apr_table_get(r->notes, "error-notes")) - != NULL) { - ap_rvputs(r, error_notes, "

\n", NULL); - } - break; - case HTTP_VARIANT_ALSO_VARIES: - ap_rvputs(r, "A variant for the requested resource\n

\n",
  -		      ap_escape_html(r->pool, r->uri),
  -		      "\n
\nis itself a negotiable resource. " - "This indicates a configuration error.

\n", NULL); - break; - case HTTP_REQUEST_TIME_OUT: - ap_rputs("I'm tired of waiting for your request.\n", r); - break; - case HTTP_GONE: - ap_rvputs(r, "The requested resource
", - ap_escape_html(r->pool, r->uri), - "
\nis no longer available on this server ", - "and there is no forwarding address.\n", - "Please remove all references to this resource.\n", - NULL); - break; - case HTTP_REQUEST_ENTITY_TOO_LARGE: - ap_rvputs(r, "The requested resource
", - ap_escape_html(r->pool, r->uri), "
\n", - "does not allow request data with ", r->method, - " requests, or the amount of data provided in\n", - "the request exceeds the capacity limit.\n", NULL); - break; - case HTTP_REQUEST_URI_TOO_LARGE: - ap_rputs("The requested URL's length exceeds the capacity\n" - "limit for this server.

\n", r); - if ((error_notes = apr_table_get(r->notes, "error-notes")) - != NULL) { - ap_rvputs(r, error_notes, "

\n", NULL); - } - break; - case HTTP_UNSUPPORTED_MEDIA_TYPE: - ap_rputs("The supplied request data is not in a format\n" - "acceptable for processing by this resource.\n", r); - break; - case HTTP_RANGE_NOT_SATISFIABLE: - ap_rputs("None of the range-specifier values in the Range\n" - "request-header field overlap the current extent\n" - "of the selected resource.\n", r); - break; - case HTTP_EXPECTATION_FAILED: - ap_rvputs(r, "The expectation given in the Expect request-header" - "\nfield could not be met by this server.

\n" - "The client sent

\n    Expect: ",
  -	              apr_table_get(r->headers_in, "Expect"), "\n
\n" - "but we only allow the 100-continue expectation.\n", - NULL); - break; - case HTTP_UNPROCESSABLE_ENTITY: - ap_rputs("The server understands the media type of the\n" - "request entity, but was unable to process the\n" - "contained instructions.\n", r); - break; - case HTTP_LOCKED: - ap_rputs("The requested resource is currently locked.\n" - "The lock must be released or proper identification\n" - "given before the method can be applied.\n", r); - break; - case HTTP_FAILED_DEPENDENCY: - ap_rputs("The method could not be performed on the resource\n" - "because the requested action depended on another\n" - "action and that other action failed.\n", r); - break; - case HTTP_INSUFFICIENT_STORAGE: - ap_rputs("The method could not be performed on the resource\n" - "because the server is unable to store the\n" - "representation needed to successfully complete the\n" - "request. There is insufficient free space left in\n" - "your storage allocation.\n", r); - break; - case HTTP_SERVICE_UNAVAILABLE: - ap_rputs("The server is temporarily unable to service your\n" - "request due to maintenance downtime or capacity\n" - "problems. Please try again later.\n", r); - break; - case HTTP_GATEWAY_TIME_OUT: - ap_rputs("The proxy server did not receive a timely response\n" - "from the upstream server.\n", r); - break; - case HTTP_NOT_EXTENDED: - ap_rputs("A mandatory extension policy in the request is not\n" - "accepted by the server for this resource.\n", r); - break; - default: /* HTTP_INTERNAL_SERVER_ERROR */ - /* - * This comparison to expose error-notes could be modified to - * use a configuration directive and export based on that - * directive. For now "*" is used to designate an error-notes - * that is totally safe for any user to see (ie lacks paths, - * database passwords, etc.) - */ - if (((error_notes = apr_table_get(r->notes, "error-notes")) != NULL) - && (h1 = apr_table_get(r->notes, "verbose-error-to")) != NULL - && (strcmp(h1, "*") == 0)) { - ap_rvputs(r, error_notes, "

\n", NULL); - } - else { - ap_rvputs(r, "The server encountered an internal error or\n" - "misconfiguration and was unable to complete\n" - "your request.

\n" - "Please contact the server administrator,\n ", - ap_escape_html(r->pool, r->server->server_admin), - " and inform them of the time the error occurred,\n" - "and anything you might have done that may have\n" - "caused the error.

\n" - "More information about this error may be available\n" - "in the server error log.

\n", NULL); - } - /* - * It would be nice to give the user the information they need to - * fix the problem directly since many users don't have access to - * the error_log (think University sites) even though they can easily - * get this error by misconfiguring an htaccess file. However, the - * error notes tend to include the real file pathname in this case, - * which some people consider to be a breach of privacy. Until we - * can figure out a way to remove the pathname, leave this commented. - * - * if ((error_notes = apr_table_get(r->notes, "error-notes")) != NULL) { - * ap_rvputs(r, error_notes, "

\n", NULL); - * } - */ - break; - } + + ap_rputs(get_canned_error_string(status, r, location),r); if (recursive_error) { ap_rvputs(r, "

Additionally, a ",