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

📄 http_protocol.c

📁 linux网络服务器工具
💻 C
📖 第 1 页 / 共 4 页
字号:
                               "misconfiguration and was unable to complete\n"                               "your request.</p>\n"                               "<p>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.</p>\n"                               "<p>More information about this error "                               "may be available\n"                               "in the server error log.</p>\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, "<p />\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), * and 5xx (server error) messages that have not been redirected to another * handler via the ErrorDocument feature. */AP_DECLARE(void) ap_send_error_response(request_rec *r, int recursive_error){    int status = r->status;    int idx = ap_index_of_response(status);    char *custom_response;    const char *location = apr_table_get(r->headers_out, "Location");    /* At this point, we are starting the response over, so we have to reset     * this value.     */    r->eos_sent = 0;    /* and we need to get rid of any RESOURCE filters that might be lurking     * around, thinking they are in the middle of the original request     */    r->output_filters = r->proto_output_filters;    ap_run_insert_error_filter(r);    /*     * It's possible that the Location field might be in r->err_headers_out     * instead of r->headers_out; use the latter if possible, else the     * former.     */    if (location == NULL) {        location = apr_table_get(r->err_headers_out, "Location");    }    /* We need to special-case the handling of 204 and 304 responses,     * since they have specific HTTP requirements and do not include a     * message body.  Note that being assbackwards here is not an option.     */    if (status == HTTP_NOT_MODIFIED) {        ap_finalize_request_protocol(r);        return;    }    if (status == HTTP_NO_CONTENT) {        ap_finalize_request_protocol(r);        return;    }    if (!r->assbackwards) {        apr_table_t *tmp = r->headers_out;        /* For all HTTP/1.x responses for which we generate the message,         * we need to avoid inheriting the "normal status" header fields         * that may have been set by the request handler before the         * error or redirect, except for Location on external redirects.         */        r->headers_out = r->err_headers_out;        r->err_headers_out = tmp;        apr_table_clear(r->err_headers_out);        if (ap_is_HTTP_REDIRECT(status) || (status == HTTP_CREATED)) {            if ((location != NULL) && *location) {                apr_table_setn(r->headers_out, "Location", location);            }            else {                location = "";   /* avoids coredump when printing, below */            }        }        r->content_languages = NULL;        r->content_encoding = NULL;        r->clength = 0;        if (apr_table_get(r->subprocess_env,                          "suppress-error-charset") != NULL) {            core_request_config *request_conf =                        ap_get_module_config(r->request_config, &core_module);            request_conf->suppress_charset = 1; /* avoid adding default                                                 * charset later                                                 */            ap_set_content_type(r, "text/html");        }        else {            ap_set_content_type(r, "text/html; charset=iso-8859-1");        }        if ((status == HTTP_METHOD_NOT_ALLOWED)            || (status == HTTP_NOT_IMPLEMENTED)) {            apr_table_setn(r->headers_out, "Allow", make_allow(r));        }        if (r->header_only) {            ap_finalize_request_protocol(r);            return;        }    }    if ((custom_response = ap_response_code_string(r, idx))) {        /*         * We have a custom response output. This should only be         * a text-string to write back. But if the ErrorDocument         * was a local redirect and the requested resource failed         * for any reason, the custom_response will still hold the         * redirect URL. We don't really want to output this URL         * as a text message, so first check the custom response         * string to ensure that it is a text-string (using the         * same test used in ap_die(), i.e. does it start with a ").         *         * If it's not a text string, we've got a recursive error or         * an external redirect.  If it's a recursive error, ap_die passes         * us the second error code so we can write both, and has already         * backed up to the original error.  If it's an external redirect,         * it hasn't happened yet; we may never know if it fails.         */        if (custom_response[0] == '\"') {            ap_rputs(custom_response + 1, r);            ap_finalize_request_protocol(r);            return;        }    }    {        const char *title = status_lines[idx];        const char *h1;        /* Accept a status_line set by a module, but only if it begins         * with the 3 digit status code         */        if (r->status_line != NULL            && strlen(r->status_line) > 4       /* long enough */            && apr_isdigit(r->status_line[0])            && apr_isdigit(r->status_line[1])            && apr_isdigit(r->status_line[2])            && apr_isspace(r->status_line[3])            && apr_isalnum(r->status_line[4])) {            title = r->status_line;        }        /* folks decided they didn't want the error code in the H1 text */        h1 = &title[4];        /* can't count on a charset filter being in place here,         * so do ebcdic->ascii translation explicitly (if needed)         */        ap_rvputs_proto_in_ascii(r,                  DOCTYPE_HTML_2_0                  "<html><head>\n<title>", title,                  "</title>\n</head><body>\n<h1>", h1, "</h1>\n",                  NULL);        ap_rvputs_proto_in_ascii(r,                                 get_canned_error_string(status, r, location),                                 NULL);        if (recursive_error) {            ap_rvputs_proto_in_ascii(r, "<p>Additionally, a ",                      status_lines[ap_index_of_response(recursive_error)],                      "\nerror was encountered while trying to use an "                      "ErrorDocument to handle the request.</p>\n", NULL);        }        ap_rvputs_proto_in_ascii(r, ap_psignature("<hr>\n", r), NULL);        ap_rvputs_proto_in_ascii(r, "</body></html>\n", NULL);    }    ap_finalize_request_protocol(r);}/* * Create a new method list with the specified number of preallocated * extension slots. */AP_DECLARE(ap_method_list_t *) ap_make_method_list(apr_pool_t *p, int nelts){    ap_method_list_t *ml;    ml = (ap_method_list_t *) apr_palloc(p, sizeof(ap_method_list_t));    ml->method_mask = 0;    ml->method_list = apr_array_make(p, nelts, sizeof(char *));    return ml;}/* * Make a copy of a method list (primarily for subrequests that may * subsequently change it; don't want them changing the parent's, too!). */AP_DECLARE(void) ap_copy_method_list(ap_method_list_t *dest,                                     ap_method_list_t *src){    int i;    char **imethods;    char **omethods;    dest->method_mask = src->method_mask;    imethods = (char **) src->method_list->elts;    for (i = 0; i < src->method_list->nelts; ++i) {        omethods = (char **) apr_array_push(dest->method_list);        *omethods = apr_pstrdup(dest->method_list->pool, imethods[i]);    }}/* * Return true if the specified HTTP method is in the provided * method list. */AP_DECLARE(int) ap_method_in_list(ap_method_list_t *l, const char *method){    int methnum;    int i;    char **methods;    /*     * If it's one of our known methods, use the shortcut and check the     * bitmask.     */    methnum = ap_method_number_of(method);    if (methnum != M_INVALID) {        return !!(l->method_mask & (AP_METHOD_BIT << methnum));    }    /*     * Otherwise, see if the method name is in the array or string names     */    if ((l->method_list == NULL) || (l->method_list->nelts == 0)) {        return 0;    }    methods = (char **)l->method_list->elts;    for (i = 0; i < l->method_list->nelts; ++i) {        if (strcmp(method, methods[i]) == 0) {            return 1;        }    }    return 0;}/* * Add the specified method to a method list (if it isn't already there). */AP_DECLARE(void) ap_method_list_add(ap_method_list_t *l, const char *method){    int methnum;    int i;    const char **xmethod;    char **methods;    /*     * If it's one of our known methods, use the shortcut and use the     * bitmask.     */    methnum = ap_method_number_of(method);    l->method_mask |= (AP_METHOD_BIT << methnum);    if (methnum != M_INVALID) {        return;    }    /*     * Otherwise, see if the method name is in the array of string names.     */    if (l->method_list->nelts != 0) {        methods = (char **)l->method_list->elts;        for (i = 0; i < l->method_list->nelts; ++i) {            if (strcmp(method, methods[i]) == 0) {                return;            }        }    }    xmethod = (const char **) apr_array_push(l->method_list);    *xmethod = method;}/* * Remove the specified method from a method list. */AP_DECLARE(void) ap_method_list_remove(ap_method_list_t *l,                                       const char *method){    int methnum;    char **methods;    /*     * If it's a known methods, either builtin or registered     * by a module, use the bitmask.     */    methnum = ap_method_number_of(method);    l->method_mask |= ~(AP_METHOD_BIT << methnum);    if (methnum != M_INVALID) {        return;    }    /*     * Otherwise, see if the method name is in the array of string names.     */    if (l->method_list->nelts != 0) {        register int i, j, k;        methods = (char **)l->method_list->elts;        for (i = 0; i < l->method_list->nelts; ) {            if (strcmp(method, methods[i]) == 0) {                for (j = i, k = i + 1; k < l->method_list->nelts; ++j, ++k) {                    methods[j] = methods[k];                }                --l->method_list->nelts;            }            else {                ++i;            }        }    }}/* * Reset a method list to be completely empty. */AP_DECLARE(void) ap_clear_method_list(ap_method_list_t *l){    l->method_mask = 0;    l->method_list->nelts = 0;}

⌨️ 快捷键说明

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