Sorry, I don't want to harass someone, but there are two pending patches of
mod_negotiation.c. This is just a reminder, since the patches seem to
become overlooked and/or forgotten.
Short summary of the previous mails:
- env.patch introduces a behaviour similar to mod_deflate and drops all
non-identity encoded ressources from the variant list according to the
current no-gzip or gzip-only-text/html settings. Useful for statically
compressed content.
- body.patch sets the appropriate MIME headers, if a type map body is
applied (Content-language, Content-type; charset, Content-Encoding)
(both are against HEAD; both.patch contains...both ;-)
TIA, nd
--
If God intended people to be naked, they would be born that way.
-- Oscar Wilde
Index: mod_negotiation.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/modules/mappers/mod_negotiation.c,v
retrieving revision 1.108
diff -u -r1.108 mod_negotiation.c
--- mod_negotiation.c 18 Nov 2002 14:13:53 -0000 1.108
+++ mod_negotiation.c 20 Nov 2002 02:10:27 -0000
@@ -901,6 +901,60 @@
return cp;
}
+/* is_identity_encoding is included for back-compat, but does anyone
+ * use 7bit, 8bit or binary in their var files??
+ */
+
+static int is_identity_encoding(const char *enc)
+{
+ return (!enc || !enc[0] || !strcmp(enc, "7bit") || !strcmp(enc, "8bit")
+ || !strcmp(enc, "binary"));
+}
+
+/* check for environment variables 'no-gzip' and
+ * 'gzip-only-text/html' to get a behaviour similiar
+ * to mod_deflate
+ */
+
+static int discard_by_encoding(negotiation_state *neg, const char *encoding,
+ const char *type)
+{
+ request_rec *r = neg->r;
+ accept_rec current;
+
+ int discard_all, discard_nonhtml;
+ int is_identity = 1;
+
+ /* don't bother */
+ if (!encoding) {
+ return 0;
+ }
+
+ if (!(discard_all = !!apr_table_get(r->subprocess_env, "no-gzip"))) {
+ const char *env_value = apr_table_get(r->subprocess_env,
+ "gzip-only-text/html");
+
+ if (!(discard_nonhtml = (env_value && !strcmp(env_value, "1")))) {
+ return 0;
+ }
+ }
+
+ while (*encoding) {
+ encoding = get_entry(neg->pool, ¤t, encoding);
+
+ if (!is_identity_encoding(current.name) &&
+ strcmp(current.name, "identity")) {
+ is_identity = 0;
+ break;
+ }
+ }
+
+ return (!is_identity &&
+ (discard_all ||
+ (discard_nonhtml &&
+ (!type || strncmp(type, "text/html", 9)))));
+}
+
static int read_type_map(apr_file_t **map, negotiation_state *neg, request_rec *rr)
{
request_rec *r = neg->r;
@@ -992,7 +1046,9 @@
}
}
else {
- if (*mime_info.file_name && has_content) {
+ if (*mime_info.file_name && has_content &&
+ !discard_by_encoding(neg, mime_info.content_encoding,
+ mime_info.mime_type)) {
void *new_var = apr_array_push(neg->avail_vars);
memcpy(new_var, (void *) &mime_info, sizeof(var_rec));
@@ -1207,6 +1263,12 @@
return read_type_map(NULL, neg, sub_req);
}
+ if (discard_by_encoding(neg, sub_req->content_encoding,
+ sub_req->content_type)) {
+ ap_destroy_sub_req(sub_req);
+ continue;
+ }
+
/* Have reasonable variant --- gather notes. */
mime_info.sub_req = sub_req;
@@ -1862,17 +1924,6 @@
else {
variant->charset_quality = 0.0f;
}
-}
-
-
-/* is_identity_encoding is included for back-compat, but does anyone
- * use 7bit, 8bin or binary in their var files??
- */
-
-static int is_identity_encoding(const char *enc)
-{
- return (!enc || !enc[0] || !strcmp(enc, "7bit") || !strcmp(enc, "8bit")
- || !strcmp(enc, "binary"));
}
/*
Index: mod_negotiation.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/modules/mappers/mod_negotiation.c,v
retrieving revision 1.108
diff -u -r1.108 mod_negotiation.c
--- mod_negotiation.c 18 Nov 2002 14:13:53 -0000 1.108
+++ mod_negotiation.c 20 Nov 2002 02:05:27 -0000
@@ -901,6 +901,60 @@
return cp;
}
+/* is_identity_encoding is included for back-compat, but does anyone
+ * use 7bit, 8bit or binary in their var files??
+ */
+
+static int is_identity_encoding(const char *enc)
+{
+ return (!enc || !enc[0] || !strcmp(enc, "7bit") || !strcmp(enc, "8bit")
+ || !strcmp(enc, "binary"));
+}
+
+/* check for environment variables 'no-gzip' and
+ * 'gzip-only-text/html' to get a behaviour similiar
+ * to mod_deflate
+ */
+
+static int discard_by_encoding(negotiation_state *neg, const char *encoding,
+ const char *type)
+{
+ request_rec *r = neg->r;
+ accept_rec current;
+
+ int discard_all, discard_nonhtml;
+ int is_identity = 1;
+
+ /* don't bother */
+ if (!encoding) {
+ return 0;
+ }
+
+ if (!(discard_all = !!apr_table_get(r->subprocess_env, "no-gzip"))) {
+ const char *env_value = apr_table_get(r->subprocess_env,
+ "gzip-only-text/html");
+
+ if (!(discard_nonhtml = (env_value && !strcmp(env_value, "1")))) {
+ return 0;
+ }
+ }
+
+ while (*encoding) {
+ encoding = get_entry(neg->pool, ¤t, encoding);
+
+ if (!is_identity_encoding(current.name) &&
+ strcmp(current.name, "identity")) {
+ is_identity = 0;
+ break;
+ }
+ }
+
+ return (!is_identity &&
+ (discard_all ||
+ (discard_nonhtml &&
+ (!type || strncmp(type, "text/html", 9)))));
+}
+
static int read_type_map(apr_file_t **map, negotiation_state *neg, request_rec *rr)
{
request_rec *r = neg->r;
@@ -992,7 +1046,9 @@
}
}
else {
- if (*mime_info.file_name && has_content) {
+ if (*mime_info.file_name && has_content &&
+ !discard_by_encoding(neg, mime_info.content_encoding,
+ mime_info.mime_type)) {
void *new_var = apr_array_push(neg->avail_vars);
memcpy(new_var, (void *) &mime_info, sizeof(var_rec));
@@ -1207,6 +1263,12 @@
return read_type_map(NULL, neg, sub_req);
}
+ if (discard_by_encoding(neg, sub_req->content_encoding,
+ sub_req->content_type)) {
+ ap_destroy_sub_req(sub_req);
+ continue;
+ }
+
/* Have reasonable variant --- gather notes. */
mime_info.sub_req = sub_req;
@@ -1864,17 +1926,6 @@
}
}
-
-/* is_identity_encoding is included for back-compat, but does anyone
- * use 7bit, 8bin or binary in their var files??
- */
-
-static int is_identity_encoding(const char *enc)
-{
- return (!enc || !enc[0] || !strcmp(enc, "7bit") || !strcmp(enc, "8bit")
- || !strcmp(enc, "binary"));
-}
-
/*
* set_encoding_quality determines whether the encoding for a particular
* variant is acceptable for the user-agent.
@@ -2845,6 +2896,33 @@
*/
apr_table_setn(r->headers_out, "Accept-Ranges", "bytes");
ap_set_content_length(r, best->bytes);
+
+ /* set MIME type and charset as negotiated */
+ if (best->mime_type && *best->mime_type) {
+ if (best->content_charset && *best->content_charset) {
+ ap_set_content_type(r, apr_pstrcat(r->pool,
+ best->mime_type,
+ "; charset=",
+ best->content_charset,
+ NULL));
+ }
+ else {
+ ap_set_content_type(r, apr_pstrdup(r->pool, best->mime_type));
+ }
+ }
+
+ /* set Content-language(s) as negotiated */
+ if (best->content_languages && best->content_languages->nelts) {
+ r->content_languages = apr_array_copy(r->pool,
+ best->content_languages);
+ }
+
+ /* set Content-Encoding as negotiated */
+ if (best->content_encoding && *best->content_encoding) {
+ r->content_encoding = apr_pstrdup(r->pool,
+ best->content_encoding);
+ }
+
if ((res = ap_meets_conditions(r)) != OK) {
return res;
}
Index: mod_negotiation.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/modules/mappers/mod_negotiation.c,v
retrieving revision 1.108
diff -u -r1.108 mod_negotiation.c
--- mod_negotiation.c 18 Nov 2002 14:13:53 -0000 1.108
+++ mod_negotiation.c 20 Nov 2002 02:15:35 -0000
@@ -2844,7 +2844,34 @@
* ap_set_etag(r);
*/
apr_table_setn(r->headers_out, "Accept-Ranges", "bytes");
- ap_set_content_length(r, best->bytes);
+ ap_set_content_length(r, best->bytes);
+
+ /* set MIME type and charset as negotiated */
+ if (best->mime_type && *best->mime_type) {
+ if (best->content_charset && *best->content_charset) {
+ ap_set_content_type(r, apr_pstrcat(r->pool,
+ best->mime_type,
+ "; charset=",
+ best->content_charset,
+ NULL));
+ }
+ else {
+ ap_set_content_type(r, apr_pstrdup(r->pool, best->mime_type));
+ }
+ }
+
+ /* set Content-language(s) as negotiated */
+ if (best->content_languages && best->content_languages->nelts) {
+ r->content_languages = apr_array_copy(r->pool,
+ best->content_languages);
+ }
+
+ /* set Content-Encoding as negotiated */
+ if (best->content_encoding && *best->content_encoding) {
+ r->content_encoding = apr_pstrdup(r->pool,
+ best->content_encoding);
+ }
+
if ((res = ap_meets_conditions(r)) != OK) {
return res;
}