--- mod_czs.c 2000/08/09 20:34:29 1.7 +++ mod_czs.c 2000/08/13 18:30:24 1.12 @@ -1,6 +1,10 @@ /* * mod_czs -- nuke iso8859-2 characters + * sets `Contnet-type: text/html; charset=foobar' based on user agent string + * from client browser + * * Dobrica Pavlinusic + * Robert Avilov (some fixes of ua_charset part) * * based on mod_format by Stephen F. Booth and * mod_mocrify by Peter Triller, Ernst Bachmann @@ -32,12 +36,16 @@ module MODULE_VAR_EXPORT mod_czs; FILE *in; -int do_czs; static int czs_handler(request_rec *r) { char buffer[MAX_STRING_LEN] = "undefined buffer content"; - int i; + char *b; + char *rexp = "< *META *HTTP-EQUIV=\"(Content-Type)\" *CONTENT=\"(text/html[^\"]+)\" *>"; + regex_t *regexp; + int nsub = 10; + regmatch_t regm[10]; + int i,f_ch=MAX_STRING_LEN,l_ch=0; if(r->method_number != M_GET) return DECLINED; @@ -51,31 +59,44 @@ return FORBIDDEN; } #ifdef DEBUG - if(r->args != 0 || do_czs) { + if(r->args != 0 || ap_table_get(r->notes,"do_czs")) { ap_table_setn(r->headers_out, "X-czs_filename", r->filename); + ap_table_setn(r->headers_out, "X-czs_content-type", r->content_type); if (r->args != 0) { ap_table_setn(r->headers_out, "X-czs_args", r->args); } } #endif - ap_soft_timeout("send", r); - ap_send_http_header(r); - - if(r->header_only) { - ap_kill_timeout(r); - ap_pfclose(r->pool, in); - return OK; - } - -#ifdef TEST_QUERYSTRING - if(r->args == 0 && !do_czs) { +#ifdef TEST_QUERYSTRINGV + if(r->args == 0 && !ap_table_get(r->notes,"do_czs") || + ap_strcasestr(r->content_type,"cgi") != NULL) { #else - if(!do_czs) { + if(!ap_table_get(r->notes,"do_czs") || + ap_strcasestr(r->content_type,"cgi") != NULL) { #endif - ap_send_fd(in, r); + return DECLINED; +/* ap_send_fd(in, r); */ } else { + regexp = ap_pregcomp(r->pool, rexp, REG_EXTENDED | REG_ICASE ); + + if (regexp == NULL) { + ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, + "unable to compile pattern \"%s\"", rexp); + return DECLINED; + } + + ap_soft_timeout("send", r); + ap_send_http_header(r); + + if(r->header_only) { + ap_kill_timeout(r); + ap_pfclose(r->pool, in); + return OK; + } + + while(fgets(buffer,MAX_STRING_LEN,in)) { for(i=0; i\n",i,regm[i].rm_so,regm[i].rm_eo); +#endif + for (i=0; i<10; i++) { + if (regm[i].rm_so != -1) { + if (regm[i].rm_so < f_ch) + f_ch = regm[i].rm_so; + if (regm[i].rm_eo > l_ch) + l_ch = regm[i].rm_eo; + } +#if 0 + ap_rprintf(r,"\n",i,regm[i].rm_so,regm[i].rm_eo); +#endif + } + buffer[f_ch]=0; + ap_rprintf(r,"%s", ap_pstrcat(r->pool, buffer,"", buffer+l_ch, NULL)); + } else { + ap_rprintf(r,"%s",buffer); + } } +/* ap_pregfree(r->pool, regexp); */ } ap_kill_timeout(r); @@ -103,23 +147,66 @@ int translate_path(request_rec *r) { char *uri = r->uri; request_rec *subr; - do_czs=0; + char *type = NULL; - if (uri[0]=='/' && uri[1]=='c' && uri[2]=='z' && uri[3]=='s') { +#ifdef DEBUG + ap_table_setn(r->headers_out, "X-translate", r->uri); +#endif + if (uri[0]=='/' && (uri[1] | 0x20) =='c' && (uri[2] | 0x20)=='z' && (uri[3] | 0x20) =='s') { #if 0 ap_table_setn(r->headers_out, "Location", ap_pstrcat(r->pool, uri+2, "?czs", NULL)); return REDIRECT; #endif subr = (request_rec *) ap_sub_req_lookup_uri(r->uri+4, r); r->filename=ap_pstrdup(r->pool, subr->filename); + type = subr->content_type; +#ifdef DEBUG + ap_table_setn(r->headers_out, "X-translate-content-type", type); +#endif + if (type == NULL) { + return DECLINED; /* hm? */ + } + ap_table_setn(r->notes,"do_czs",1); ap_destroy_sub_req(subr); - do_czs=1; return OK; } return DECLINED; } - + +static int add_charset_header(request_rec * r) +{ + const char *ua, *ct; + + ua = ap_table_get(r->headers_in, "User-Agent"); + if (ua == NULL) + ua = ""; + + ct = r->content_type; + + if (ct != NULL && !ap_table_get(r->notes,"do_czs")) { + + if (strstr(ct, "text/html") == NULL) + return DECLINED; /* Don't mess with other types */ + + if (strstr(ua, "Mac") != NULL) { + if (strstr(ua, "MSIE") != NULL) + r->content_type = "text/html; charset=x-mac-roman"; + else + r->content_type = "text/html; charset=MacCE"; + } else + r->content_type = "text/html; charset=iso-8859-2"; + } + +#ifdef DEBUG + ap_table_setn(r->headers_out, "X-Content-Type", ct); + ap_table_setn(r->headers_out, "X-new-Content-Type", r->content_type); + ap_table_setn(r->headers_out, "X-User-Agent", ua); +#endif + return DECLINED; +} + + /* Dispatch list of content handlers */ static const handler_rec czs_handlers[] = { { "czs", czs_handler }, @@ -141,11 +228,17 @@ NULL, /* [#5] check if the user is ok _here_ */ NULL, /* [#2] check access by host address */ NULL, /* [#6] determine MIME type */ - NULL, /* [#7] pre-run fixups */ + add_charset_header, /* [#7] pre-run fixups */ NULL, /* [#9] log a transaction */ NULL, /* [#3] header parser */ NULL, /* child_init */ NULL, /* child_exit */ NULL /* [#0] post read-request */ +#ifdef EAPI + ,NULL, /* EAPI: add_module */ + NULL, /* EAPI: remove_module */ + NULL, /* EAPI: rewrite_command */ + NULL /* EAPI: new_connection */ +#endif };