diff options
author | Jim Jagielski <jim@apache.org> | 2000-03-13 21:27:29 +0100 |
---|---|---|
committer | Jim Jagielski <jim@apache.org> | 2000-03-13 21:27:29 +0100 |
commit | 70ef1e69d59b6a1db04870c4f0edeec730cd5ea4 (patch) | |
tree | 2d2b886ae7df8d230e5853a09d07d223208bff14 /modules/http | |
parent | Update the version string to reflect that we are currently working on (diff) | |
download | apache2-70ef1e69d59b6a1db04870c4f0edeec730cd5ea4.tar.xz apache2-70ef1e69d59b6a1db04870c4f0edeec730cd5ea4.zip |
Backport the CSS security fixes to Apache 2.0a. Or is that forward
port? My sense of direction is all confused.
PR:
Obtained from:
Submitted by:
Reviewed by:
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@84751 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules/http')
-rw-r--r-- | modules/http/http_core.c | 34 | ||||
-rw-r--r-- | modules/http/http_protocol.c | 51 |
2 files changed, 77 insertions, 8 deletions
diff --git a/modules/http/http_core.c b/modules/http/http_core.c index 126920f95c..0bb8447e2b 100644 --- a/modules/http/http_core.c +++ b/modules/http/http_core.c @@ -146,6 +146,9 @@ static void *create_core_dir_config(ap_context_t *a, char *dir) conf->server_signature = srv_sig_unset; + conf->add_default_charset = ADD_DEFAULT_CHARSET_UNSET; + conf->add_default_charset_name = DEFAULT_ADD_DEFAULT_CHARSET_NAME; + return (void *)conf; } @@ -257,6 +260,14 @@ static void *merge_core_dir_configs(ap_context_t *a, void *basev, void *newv) conf->server_signature = new->server_signature; } + if (new->add_default_charset != ADD_DEFAULT_CHARSET_UNSET) { + conf->add_default_charset = new->add_default_charset; + } + + if (new->add_default_charset_name) { + conf->add_default_charset_name = new->add_default_charset_name; + } + return (void*)conf; } @@ -1000,6 +1011,27 @@ static const char *set_gprof_dir(cmd_parms *cmd, void *dummy, char *arg) } #endif /*GPROF*/ +static const char *set_add_default_charset(cmd_parms *cmd, + core_dir_config *d, char *arg) +{ + const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); + if (err != NULL) { + return err; + } + if (!strcasecmp(arg, "Off")) { + d->add_default_charset = ADD_DEFAULT_CHARSET_OFF; + } + else if (!strcasecmp(arg, "On")) { + d->add_default_charset = ADD_DEFAULT_CHARSET_ON; + d->add_default_charset_name = DEFAULT_ADD_DEFAULT_CHARSET_NAME; + } + else { + d->add_default_charset = ADD_DEFAULT_CHARSET_ON; + d->add_default_charset_name = arg; + } + return NULL; +} + static const char *set_document_root(cmd_parms *cmd, void *dummy, char *arg) { void *sconf = cmd->server->module_config; @@ -2294,6 +2326,8 @@ static const command_rec core_cmds[] = { { "GprofDir", set_gprof_dir, NULL, RSRC_CONF, TAKE1, "Directory to plop gmon.out files" }, #endif +{ "AddDefaultCharset", set_add_default_charset, NULL, OR_FILEINFO, + TAKE1, "The name of the default charset to add to any Content-Type without one or 'Off' to disable" }, /* Old resource config file commands */ diff --git a/modules/http/http_protocol.c b/modules/http/http_protocol.c index 7011be758d..e345e57eb1 100644 --- a/modules/http/http_protocol.c +++ b/modules/http/http_protocol.c @@ -90,6 +90,43 @@ HOOK_STRUCT( } while (0) +/* + * Builds the content-type that should be sent to the client from the + * content-type specified. The following rules are followed: + * - if type is NULL, type is set to ap_default_type(r) + * - if charset adding is disabled, stop processing and return type. + * - then, if there are no parameters on type, add the default charset + * - return type + */ +static const char *make_content_type(request_rec *r, const char *type) { + char *needcset[] = { + "text/plain", + "text/html", + NULL }; + char **pcset; + core_dir_config *conf = (core_dir_config *)ap_get_module_config( + r->per_dir_config, &core_module); + if (!type) type = ap_default_type(r); + if (conf->add_default_charset != ADD_DEFAULT_CHARSET_ON) return type; + + if (ap_strcasestr(type, "charset=") != NULL) { + /* already has parameter, do nothing */ + /* XXX we don't check the validity */ + ; + } else { + /* see if it makes sense to add the charset. At present, + * we only add it if the Content-type is one of needcset[] + */ + for (pcset = needcset; *pcset ; pcset++) + if (ap_strcasestr(type, *pcset) != NULL) { + type = ap_pstrcat(r->pool, type, "; charset=", + conf->add_default_charset_name, NULL); + break; + } + } + return type; +} + static int parse_byterange(char *range, long clength, long *start, long *end) { char *dash = strchr(range, '-'); @@ -240,7 +277,7 @@ static int internal_byterange(int realreq, long *tlength, request_rec *r, length); if (r->byterange > 1) { - const char *ct = r->content_type ? r->content_type : ap_default_type(r); + const char *ct = make_content_type(r, r->content_type); char ts[MAX_STRING_LEN]; ap_snprintf(ts, sizeof(ts), "%ld-%ld/%ld", range_start, range_end, @@ -897,7 +934,7 @@ static void get_mime_headers(request_rec *r) r->status = HTTP_BAD_REQUEST; ap_table_setn(r->notes, "error-notes", ap_pstrcat(r->pool, "Size of a request header field exceeds server limit.<P>\n" - "<PRE>\n", field, "</PRE>\n", NULL)); + "<PRE>\n", ap_escape_html(r->pool, field), "</PRE>\n", NULL)); return; } copy = ap_palloc(r->pool, len + 1); @@ -907,7 +944,7 @@ static void get_mime_headers(request_rec *r) r->status = HTTP_BAD_REQUEST; /* or abort the bad request */ ap_table_setn(r->notes, "error-notes", ap_pstrcat(r->pool, "Request header field is missing colon separator.<P>\n" - "<PRE>\n", copy, "</PRE>\n", NULL)); + "<PRE>\n", ap_escape_html(r->pool, copy), "</PRE>\n", NULL)); return; } @@ -1604,10 +1641,8 @@ API_EXPORT(void) ap_send_http_header(request_rec *r) ap_table_setn(r->headers_out, "Content-Type", ap_pstrcat(r->pool, "multipart", use_range_x(r) ? "/x-" : "/", "byteranges; boundary=", r->boundary, NULL)); - else if (r->content_type) - ap_table_setn(r->headers_out, "Content-Type", r->content_type); - else - ap_table_setn(r->headers_out, "Content-Type", ap_default_type(r)); + else ap_table_setn(r->headers_out, "Content-Type", make_content_type(r, + r->content_type)); if (r->content_encoding) ap_table_setn(r->headers_out, "Content-Encoding", r->content_encoding); @@ -2493,7 +2528,7 @@ API_EXPORT(void) ap_send_error_response(request_rec *r, int recursive_error) r->content_languages = NULL; r->content_encoding = NULL; r->clength = 0; - r->content_type = "text/html"; + r->content_type = "text/html; charset=iso-8859-1"; if ((status == METHOD_NOT_ALLOWED) || (status == NOT_IMPLEMENTED)) ap_table_setn(r->headers_out, "Allow", make_allow(r)); |