You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Rodent of Unusual Size <co...@decus.org> on 1997/07/18 18:31:29 UTC
[PATCH] AddTypeParameter for adding media-type parameters
(I know Dean is going to hate this because it adds a directive,
but..)
PR#241 requests the ability to add media-type parameters (in his
example, "charset=ISO8859-2"). This sounds like a primo enhancement
to me. The attached patch does this with a
AddTypeParameter parameter type [...]
For instance, for his example
AddTypeParameter charset=ISO8859-2 .html .shtml
#ken :-)}
Index: httpd.h
===================================================================
RCS file: /export/home/cvs/apache/src/httpd.h,v
retrieving revision 1.128
diff -c -r1.128 httpd.h
*** httpd.h 1997/07/17 19:44:49 1.128
--- httpd.h 1997/07/18 16:37:42
***************
*** 449,565 ****
struct request_rec {
! pool *pool;
! conn_rec *connection;
! server_rec *server;
! request_rec *next; /* If we wind up getting redirected,
* pointer to the request we redirected to.
*/
! request_rec *prev; /* If this is an internal redirect,
* pointer to where we redirected *from*.
*/
! request_rec *main; /* If this is a sub_request (see request.h)
* pointer back to the main request.
*/
! /* Info about the request itself... we begin with stuff that only
! * protocol.c should ever touch...
! */
!
! char *the_request; /* First line of request, so we can log it */
! int assbackwards; /* HTTP/0.9, "simple" request */
! int proxyreq; /* A proxy request */
! int header_only; /* HEAD request, as opposed to GET */
! char *protocol; /* Protocol, as given to us, or HTTP/0.9 */
! int proto_num; /* Number version of protocol; 1.1 = 1001 */
! char *hostname; /* Host, as set by full URI or Host: */
! int hostlen; /* Length of http://host:port in full URI */
!
! time_t request_time; /* When the request started */
!
! char *status_line; /* Status line, if set by script */
! int status; /* In any case */
!
! /* Request method, two ways; also, protocol, etc.. Outside of protocol.c,
! * look, but don't touch.
! */
!
! char *method; /* GET, HEAD, POST, etc. */
! int method_number; /* M_GET, M_POST, etc. */
! int allowed; /* Allowed methods - for 405, OPTIONS, etc */
!
! int sent_bodyct; /* byte count in stream is for body */
! long bytes_sent; /* body byte count, for easy access */
!
! /* HTTP/1.1 connection-level features */
!
! int chunked; /* sending chunked transfer-coding */
! int byterange; /* number of byte ranges */
! char *boundary; /* multipart/byteranges boundary */
! char *range; /* The Range: header */
! long clength; /* The "real" content length */
!
! long remaining; /* bytes left to read */
! long read_length; /* bytes that have been read */
! int read_body; /* how the request body should be read */
! int read_chunked; /* reading chunked transfer-coding */
!
! /* MIME header environments, in and out. Also, an array containing
! * environment variables to be passed to subprocesses, so people can
! * write modules to add to that environment.
! *
! * The difference between headers_out and err_headers_out is that the
! * latter are printed even on error, and persist across internal redirects
! * (so the headers printed for ErrorDocument handlers will have them).
! *
! * The 'notes' table is for notes from one module to another, with no
! * other set purpose in mind...
! */
!
! table *headers_in;
! table *headers_out;
! table *err_headers_out;
! table *subprocess_env;
! table *notes;
!
! char *content_type; /* Break these out --- we dispatch on 'em */
! char *handler; /* What we *really* dispatch on */
!
! char *content_encoding;
! char *content_language; /* for back-compat. only -- do not use */
! array_header *content_languages; /* array of (char*) */
!
! int no_cache;
! int no_local_copy;
!
! /* What object is being requested (either directly, or via include
! * or content-negotiation mapping).
! */
! char *uri; /* complete URI for a proxy req, or
URL path for a non-proxy req */
! char *filename;
! char *path_info;
! char *args; /* QUERY_ARGS, if any */
! struct stat finfo; /* ST_MODE set to zero if no such file */
!
! /* Various other config info which may change with .htaccess files
! * These are config vectors, with one void* pointer for each module
! * (the thing pointed to being the module's business).
! */
!
! void *per_dir_config; /* Options set in config files, etc. */
! void *request_config; /* Notes on *this* request */
!
! /*
! * a linked list of the configuration directives in the .htaccess files
! * accessed by this request.
! * N.B. always add to the head of the list, _never_ to the end.
! * that way, a sub request's list can (temporarily) point to a parent's list
! */
! const struct htaccess_result *htaccess;
};
--- 449,567 ----
struct request_rec {
! pool *pool;
! conn_rec *connection;
! server_rec *server;
! request_rec *next; /* If we wind up getting redirected,
* pointer to the request we redirected to.
*/
! request_rec *prev; /* If this is an internal redirect,
* pointer to where we redirected *from*.
*/
! request_rec *main; /* If this is a sub_request (see request.h)
* pointer back to the main request.
*/
! /* Info about the request itself... we begin with stuff that only
! * protocol.c should ever touch...
! */
!
! char *the_request; /* First line of request, so we can log it */
! int assbackwards; /* HTTP/0.9, "simple" request */
! int proxyreq; /* A proxy request */
! int header_only; /* HEAD request, as opposed to GET */
! char *protocol; /* Protocol, as given to us, or HTTP/0.9 */
! int proto_num; /* Number version of protocol; 1.1 = 1001 */
! char *hostname; /* Host, as set by full URI or Host: */
! int hostlen; /* Length of http://host:port in full URI */
!
! time_t request_time; /* When the request started */
!
! char *status_line; /* Status line, if set by script */
! int status; /* In any case */
!
! /* Request method, two ways; also, protocol, etc.. Outside of protocol.c,
! * look, but don't touch.
! */
!
! char *method; /* GET, HEAD, POST, etc. */
! int method_number; /* M_GET, M_POST, etc. */
! int allowed; /* Allowed methods - for 405, OPTIONS, etc */
!
! int sent_bodyct; /* byte count in stream is for body */
! long bytes_sent; /* body byte count, for easy access */
!
! /* HTTP/1.1 connection-level features */
!
! int chunked; /* sending chunked transfer-coding */
! int byterange; /* number of byte ranges */
! char *boundary; /* multipart/byteranges boundary */
! char *range; /* The Range: header */
! long clength; /* The "real" content length */
!
! long remaining; /* bytes left to read */
! long read_length; /* bytes that have been read */
! int read_body; /* how the request body should be read */
! int read_chunked; /* reading chunked transfer-coding */
!
! /* MIME header environments, in and out. Also, an array containing
! * environment variables to be passed to subprocesses, so people can
! * write modules to add to that environment.
! *
! * The difference between headers_out and err_headers_out is that the
! * latter are printed even on error, and persist across internal redirects
! * (so the headers printed for ErrorDocument handlers will have them).
! *
! * The 'notes' table is for notes from one module to another, with no
! * other set purpose in mind...
! */
!
! table *headers_in;
! table *headers_out;
! table *err_headers_out;
! table *subprocess_env;
! table *notes;
!
! char *content_type; /* Break these out --- we dispatch on 'em */
! char *content_params; /* Things like "; charset=mumble" */
! char *handler; /* What we *really* dispatch on */
!
! char *content_encoding;
! char *content_language; /* for back-compat. only -- do not use */
! array_header *content_languages; /* array of (char*) */
!
! int no_cache;
! int no_local_copy;
!
! /* What object is being requested (either directly, or via include
! * or content-negotiation mapping).
! */
! char *uri; /* complete URI for a proxy req, or
URL path for a non-proxy req */
! char *filename;
! char *path_info;
! char *args; /* QUERY_ARGS, if any */
! struct stat finfo; /* ST_MODE set to zero if no such file */
!
! /* Various other config info which may change with .htaccess files
! * These are config vectors, with one void* pointer for each module
! * (the thing pointed to being the module's business).
! */
!
! void *per_dir_config; /* Options set in config files, etc. */
! void *request_config; /* Notes on *this* request */
!
! /*
! * a linked list of the configuration directives in the .htaccess files
! * accessed by this request.
! * N.B. always add to the head of the list, _never_ to the end.
! * that way, a sub request's list can (temporarily) point to a parent's
! * list.
! */
! const struct htaccess_result *htaccess;
};
Index: http_protocol.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_protocol.c,v
retrieving revision 1.139
diff -c -r1.139 http_protocol.c
*** http_protocol.c 1997/07/15 22:36:51 1.139
--- http_protocol.c 1997/07/18 16:37:51
***************
*** 1215,1220 ****
--- 1215,1227 ----
else
table_set(r->headers_out, "Content-Type", default_type(r));
+ if (r->content_params != NULL) {
+ char *full_type;
+ full_type = pstrcat (r->pool,
+ table_get(r->headers_out, "Content-Type"),
+ r->content_params, NULL);
+ table_set(r->headers_out, "Content-Type", full_type);
+ }
if (r->content_encoding)
table_set(r->headers_out, "Content-Encoding", r->content_encoding);
Index: mod_mime.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_mime.c,v
retrieving revision 1.19
diff -c -r1.19 mod_mime.c
*** mod_mime.c 1997/07/17 22:27:39 1.19
--- mod_mime.c 1997/07/18 16:37:54
***************
*** 67,72 ****
--- 67,73 ----
table *encoding_types; /* Added with AddEncoding... */
table *language_types; /* Added with AddLanguage... */
table *handlers; /* Added with AddHandler... */
+ table *content_params; /* Added with AddTypeParameter... */
char *type; /* Type forced with ForceType */
char *handler; /* Handler forced with SetHandler */
***************
*** 83,88 ****
--- 84,90 ----
new->encoding_types = make_table (p, 4);
new->language_types = make_table (p, 4);
new->handlers = make_table (p, 4);
+ new->content_params = make_table (p, 4);
new->type = NULL;
new->handler = NULL;
***************
*** 104,110 ****
new->language_types = overlay_tables (p, add->language_types,
base->language_types);
new->handlers = overlay_tables (p, add->handlers,
! base->handlers);
new->type = add->type ? add->type : base->type;
new->handler = add->handler ? add->handler : base->handler;
--- 106,114 ----
new->language_types = overlay_tables (p, add->language_types,
base->language_types);
new->handlers = overlay_tables (p, add->handlers,
! base->handlers);
! new->content_params = overlay_tables (p, add->content_params,
! base->content_params);
new->type = add->type ? add->type : base->type;
new->handler = add->handler ? add->handler : base->handler;
***************
*** 119,124 ****
--- 123,149 ----
return NULL;
}
+ /*
+ * Add media parameters for the Content-Type header field (e.g.,
+ * charset=mumble).
+ */
+ const char *add_type_parameter(cmd_parms *cmd, mime_dir_config *m, char *cp,
+ char *ext)
+ {
+ char *newlist;
+
+ if (*ext == '.') ++ext;
+ newlist = table_get (m->content_params, ext);
+ if (newlist == NULL) {
+ newlist = pstrcat (cmd->pool, "; ", cp, NULL);
+ }
+ else {
+ newlist = pstrcat (cmd->pool, newlist, "; ", cp, NULL);
+ }
+ table_set (m->content_params, ext, newlist);
+ return NULL;
+ }
+
const char *add_encoding(cmd_parms *cmd, mime_dir_config *m, char *enc,
char *ext)
{
***************
*** 156,162 ****
command_rec mime_cmds[] = {
{ "AddType", add_type, NULL, OR_FILEINFO, ITERATE2,
! "a mime type followed by one or more file extensions" },
{ "AddEncoding", add_encoding, NULL, OR_FILEINFO, ITERATE2,
"an encoding (e.g., gzip), followed by one or more file extensions" },
{ "AddLanguage", add_language, NULL, OR_FILEINFO, ITERATE2,
--- 181,189 ----
command_rec mime_cmds[] = {
{ "AddType", add_type, NULL, OR_FILEINFO, ITERATE2,
! "a MIME type followed by one or more file extensions" },
! { "AddTypeParameter", add_type_parameter, NULL, OR_FILEINFO, ITERATE2,
! "an HTTP/1.1 media type parameter followed by one or more file extensions" },
{ "AddEncoding", add_encoding, NULL, OR_FILEINFO, ITERATE2,
"an encoding (e.g., gzip), followed by one or more file extensions" },
{ "AddLanguage", add_language, NULL, OR_FILEINFO, ITERATE2,
***************
*** 164,170 ****
{ "AddHandler", add_handler, NULL, OR_FILEINFO, ITERATE2,
"a handler name followed by one or more file extensions" },
{ "ForceType", set_string_slot, (void*)XtOffsetOf(mime_dir_config, type),
! OR_FILEINFO, TAKE1, "a media type" },
{ "SetHandler", set_string_slot, (void*)XtOffsetOf(mime_dir_config, handler),
OR_FILEINFO, TAKE1, "a handler name" },
{ "TypesConfig", set_types_config, NULL, RSRC_CONF, TAKE1,
--- 191,197 ----
{ "AddHandler", add_handler, NULL, OR_FILEINFO, ITERATE2,
"a handler name followed by one or more file extensions" },
{ "ForceType", set_string_slot, (void*)XtOffsetOf(mime_dir_config, type),
! OR_FILEINFO, TAKE1, "a MIME media type" },
{ "SetHandler", set_string_slot, (void*)XtOffsetOf(mime_dir_config, handler),
OR_FILEINFO, TAKE1, "a handler name" },
{ "TypesConfig", set_types_config, NULL, RSRC_CONF, TAKE1,
***************
*** 235,241 ****
* pointer to getword, causing a SEGV ..
*/
! if(fn == NULL) fn = r->filename;
/* Parse filename extensions, which can be in any order */
while ((ext = getword(r->pool, &fn, '.')) && *ext) {
--- 262,269 ----
* pointer to getword, causing a SEGV ..
*/
! if (fn == NULL)
! fn = r->filename;
/* Parse filename extensions, which can be in any order */
while ((ext = getword(r->pool, &fn, '.')) && *ext) {
***************
*** 248,253 ****
--- 276,287 ----
found = 1;
}
+ /* Check for media-type parameters */
+ if ((type = table_get (conf->content_params, ext)) != NULL) {
+ r->content_params = type;
+ found = 1;
+ }
+
/* Check for Content-Language */
if ((type = table_get (conf->language_types, ext))) {
char **new;
***************
*** 283,288 ****
--- 317,323 ----
if (!found) {
r->content_type = NULL;
+ r->content_params = NULL;
r->content_language = NULL;
r->content_languages = NULL;
r->content_encoding = NULL;