[mod-xhtml-neg-cvs] mod_xhtml_neg mod_xhtml_neg.c,1.8,1.9
Brought to you by:
run2000
From: <ru...@us...> - 2004-03-11 12:31:31
|
Update of /cvsroot/mod-xhtml-neg/mod_xhtml_neg In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3487 Modified Files: mod_xhtml_neg.c Log Message: Reworked and simplified ETag handling. Index: mod_xhtml_neg.c =================================================================== RCS file: /cvsroot/mod-xhtml-neg/mod_xhtml_neg/mod_xhtml_neg.c,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** mod_xhtml_neg.c 11 Mar 2004 09:52:02 -0000 1.8 --- mod_xhtml_neg.c 11 Mar 2004 12:04:53 -0000 1.9 *************** *** 79,92 **** * 0.7 Added profile handling, fixed up default charset for text/xml * 0.8 First public release. ! * 0.82 Development of ETag handling. * * Todo: * ! * Make sure ETag is handled correctly. I assume from * http://www.w3.org/2003/01/xhtml-mimetype/content-negotiation ! * that ETags should be unique for each content-type returned. This should * be doable by intercepting requests containing If-None-Match headers ! * and fixing up ETags on the way in, and by adding our own prefix to ! * ETag headers on the way out. * * Directives: --- 79,92 ---- * 0.7 Added profile handling, fixed up default charset for text/xml * 0.8 First public release. ! * 0.82 Development of Etag handling. * * Todo: * ! * Make sure Etag is handled correctly. I assume from * http://www.w3.org/2003/01/xhtml-mimetype/content-negotiation ! * that Etags should be unique for each content-type returned. This should * be doable by intercepting requests containing If-None-Match headers ! * and fixing up Etags on the way in, and by adding our own prefix to ! * Etag headers on the way out. * * Directives: *************** *** 158,174 **** /* - * Record of incoming and outgoing ETag information. For content-negotiated - * responses, we add a prefix to outgoing ETag headers, so that each - * distinct content-type is given a unique ETag. On conditional GET - * requests, we need to strip out the prefix we added earlier, so that the - * core Apache code will correctly return 304 responses, etc. - */ - - typedef struct { - char *etag; /* The incoming ETag */ - int weak; /* Whether the validator is weak or strong */ - } etag_rec; - - /* * Record the maps a file extension to zero or more content-types. The content * types themselves are stored as an array of accept_rec records. --- 158,161 ---- *************** *** 471,474 **** --- 458,466 ---- } + static char *construct_new_etag( pool *p, int index ) + { + return ap_psprintf( p, "\"mxn-%d\"", index ); + } + /* * For a given filename, scan through an array of extension_rec records *************** *** 585,648 **** /* - * Following code modified from mod_negotiate.c - * - * Get a single ETag entry --- one quoted string with optional - * "weak" prefix. - */ - - static const char *get_etag(pool *p, etag_rec *result, - const char *accept_line) - { - char *token, *end; - - result->weak = 0; - result->etag = ""; - - /* - * Note that this handles the format: - * - * If-None-Match: "etag-1", W/"etag2", "etag3" - * - * If the token begins with a "W/", we're looking at a weak - * mnodifier, otherwise we parse the quoted ETag immediately - */ - - token = ap_get_token(p, &accept_line, 0); - - if( *token == 'W' || *token == 'w' ) { - ++token; - result->weak = 1; - /* Skip the slash */ - if( *token != '\0' ) { - ++token; - } - } - - if (*token == '"') { - ++token; - for (end = token; - (*end && *end != '\n' && *end != '\r' && *end != '\"'); - end++); - } else { - for (end = token; (*end && !ap_isspace(*end)); end++); - } - if (*end) { - *end = '\0'; /* strip ending quote or return */ - } - - /** Assign the ETag to the parsed token */ - result->etag = token; - - if (*accept_line == ',') { - ++accept_line; - } - - return accept_line; - } - - /* * Dealing with Accept header lines ... * ! * The Accept request header is handled by do_header_line() - it has the * basic structure of a list of items of the format: * --- 577,583 ---- /* * Dealing with Accept header lines ... * ! * The Accept request header is handled by do_accept_line() - it has the * basic structure of a list of items of the format: * *************** *** 657,661 **** */ ! static array_header *do_header_line(pool *p, const char *accept_line) { array_header *accept_recs; --- 592,596 ---- */ ! static array_header *do_accept_line(pool *p, const char *accept_line) { array_header *accept_recs; *************** *** 1091,1095 **** (content_accept ? content_accept : ""), "\n", "Accept charset is: ", ! (accept_charset ? accept_charset : ""), "\n", NULL); write(xns->log_fd, logmessage, mod_xhtml_strlen( logmessage )); --- 1026,1031 ---- (content_accept ? content_accept : ""), "\n", "Accept charset is: ", ! (accept_charset ? accept_charset : ""), "\n", ! NULL); write(xns->log_fd, logmessage, mod_xhtml_strlen( logmessage )); *************** *** 1097,1101 **** /* Translate into content arrays. */ ! accept_types = do_header_line(r->pool, content_accept); accept_charsets = do_accept_charset_line(r->pool, accept_charset); --- 1033,1037 ---- /* Translate into content arrays. */ ! accept_types = do_accept_line(r->pool, content_accept); accept_charsets = do_accept_charset_line(r->pool, accept_charset); *************** *** 1105,1112 **** if( result_type != NULL ) { r->content_type = result_type; if( xns->log_fd > 0 ) { logmessage = ap_pstrcat(r->pool, ! "Best content-type: ", result_type, "\n", NULL ); write(xns->log_fd, logmessage, mod_xhtml_strlen( logmessage )); } --- 1041,1057 ---- if( result_type != NULL ) { + /* Construct a "suffix" for the ETag, and make sure it gets + * appended to the ETag that would normally be returned + * by Apache. + */ + char *new_etag = construct_new_etag( r->pool, 4 ); + r->vlist_validator = new_etag; r->content_type = result_type; + if( xns->log_fd > 0 ) { logmessage = ap_pstrcat(r->pool, ! "Best content-type: ", result_type, "\n", ! "New Etag is: ", new_etag, "\n", ! NULL ); write(xns->log_fd, logmessage, mod_xhtml_strlen( logmessage )); } *************** *** 1134,1206 **** } - /* - * This phase fixes up any incoming ETag headers so that conditional - * GET requests work correctly for content-negotiated requests. - */ - - int xhtml_fixup_etags(request_rec *r) - { - const char *if_match, *if_none_match, *if_range; - char *logmessage; - xhtml_dir_config *conf; - xhtml_neg_state *xns; - table *hdrs; - - conf = (xhtml_dir_config *) ap_get_module_config( - r->per_dir_config, &xhtml_neg_module); - - xns = ap_get_module_config (r->server->module_config, &xhtml_neg_module); - - if (conf == NULL) { - ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, - "internal error -- no configuration: mod_xhtml_neg.c"); - return SERVER_ERROR; - }; - - /* Return OK if either active isn't ON, or stars_ignore is 0. */ - if( conf->active != ACTIVE_ON ) { - return OK; - } - - if( conf->stars_ignore == 0 ) { - return OK; - } - - /* This handler is concerned with rewriting ETag headers. - * For HTTP 0.9, this is definitely not relevant. - */ - if( r->assbackwards ) { - return OK; - } - - /* Retrieve the HTTP request headers table. */ - hdrs = r->headers_in; - if( hdrs == NULL ) { - return OK; - } - - /* Look for If-Match, If-None-Match, or If-Range */ - if_match = ap_table_get(hdrs, "If-Match"); - if_none_match = ap_table_get(hdrs, "If-None-Match"); - if_range = ap_table_get(hdrs, "If-Range"); - - /* Log the results to the log file. */ - if( xns->log_fd > 0 ) { - if( if_match != NULL || if_none_match != NULL || if_range != NULL ) { - logmessage = ap_pstrcat(r->pool, - "If-Match is: ", - (if_match ? if_match : ""), "\n", - "If-None-Match is: ", - (if_none_match ? if_none_match : ""), "\n", - "If-Range is: ", - (if_range ? if_range : ""), "\n", - NULL); - - write(xns->log_fd, logmessage, mod_xhtml_strlen( logmessage )); - } - } - - return OK; - } /* All Apache configuration file code goes here... */ --- 1079,1082 ---- *************** *** 1418,1422 **** xhtml_negotiate, /* fixups */ NULL, /* logger */ ! xhtml_fixup_etags, /* header parser */ NULL, /* child_init */ NULL, /* child_exit */ --- 1294,1298 ---- xhtml_negotiate, /* fixups */ NULL, /* logger */ ! NULL, /* header parser */ NULL, /* child_init */ NULL, /* child_exit */ |