--- mod_czs.c 2000/08/11 09:58:04 1.10 +++ mod_czs.c 2000/08/12 21:38:04 1.11 @@ -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,7 +59,7 @@ 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) { @@ -61,14 +69,24 @@ #endif #ifdef TEST_QUERYSTRINGV - if(r->args == 0 && !do_czs || strstr(r->content_type,"cgi") != NULL) { + if(r->args == 0 && !ap_table_get(r->notes,"do_czs") || + strstr(r->content_type,"cgi") != NULL) { #else - if(!do_czs || strstr(r->content_type,"cgi") != NULL) { + if(!ap_table_get(r->notes,"do_czs") || + strstr(r->content_type,"cgi") != NULL) { #endif 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); @@ -78,6 +96,7 @@ 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); @@ -106,9 +148,6 @@ char *uri = r->uri; request_rec *subr; char *type = NULL; - extern do_czs; - - do_czs=0; #ifdef DEBUG ap_table_setn(r->headers_out, "X-translate", r->uri); @@ -127,18 +166,47 @@ if (type == NULL) { return DECLINED; /* hm? */ } - do_czs=1; + ap_table_setn(r->notes,"do_czs",1); ap_destroy_sub_req(subr); -#ifdef XHEADER -# ifdef DEBUG - ap_table_setn(r->headers_out, "X-debug", XHEADER); -# endif -#endif 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 }, @@ -160,7 +228,7 @@ 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 */