/[mws]/trunk/httpd.pl
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /trunk/httpd.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 30 - (show annotations)
Sun May 9 00:09:32 2004 UTC (19 years, 11 months ago) by dpavlin
File MIME type: text/plain
File size: 6987 byte(s)
this is 0.9-rc2:
- added apropos functionality based on Text::Soundex (activated if no results
  are found)
- cleanup of debugging and minor other improvements in preparation for 0.9

1 #!/usr/bin/perl
2
3 # based on post
4 # http://www.mail-archive.com/libwww@perl.org/msg04750.html
5
6 use strict;
7 use warnings;
8 use HTTP::Daemon;
9 use HTTP::Status;
10 use IO::String;
11 use CGI::Lite;
12 use Template;
13 use MWS;
14 use URI::Escape;
15
16 use Data::Dumper;
17
18 my $debug = 1;
19
20 my $config_file = shift @ARGV || 'global.conf';
21
22 if (! -f $config_file) {
23 print qq{Usage: $0 [/path/to/local.conf]
24
25 If local.conf is not specified, global.conf in current directory will
26 be used.
27 };
28 exit 1;
29 }
30
31 my $d = HTTP::Daemon->new( Reuse => 1, LocalPort => 6969 ) || die;
32 my $cgi = new CGI::Lite;
33 my $mws = MWS->new($config_file);
34 my $tt = Template->new({
35 INCLUDE_PATH => $mws->{config}->val('global', 'templates'),
36 FILTERS => {
37 'body5' => \&body5_filter,
38 'body' => \&body_filter,
39 },
40 EVAL_PERL => 1,
41 });
42
43 my $static_html = $mws->{config}->val('global', 'static_html');
44
45 print "Web server ready at: ", $d->url, "\n";
46
47
48 while ( my $c = $d->accept ) {
49 while ( my $r = $c->get_request ) {
50
51 # environs that a webserver should set.
52 $ENV{'REQUEST_METHOD'} = $r->method;
53 $ENV{'GATEWAY_INTERFACE'} = "CGI/1.0";
54 $ENV{'SERVER_PROTOCOL'} = $r->protocol;
55 $ENV{'CONTENT_TYPE'} = $r->content_type;
56
57 # this part is based on CGI::Lite
58
59 $cgi->close_all_files();
60 $cgi->{web_data} = {};
61 $cgi->{ordered_keys} = [];
62 $cgi->{all_handles} = [];
63 $cgi->{error_status} = 0;
64 $cgi->{error_message} = undef;
65
66 if ( $r->method eq 'GET' || $r->uri =~ /\?/ ) {
67 my $query_string = $r->uri;
68 $query_string =~ s/[^\?]+\?(.*)/$1/;
69 $cgi->_decode_url_encoded_data (\$query_string, 'form');
70
71 } elsif ( $r->method eq 'POST' ) {
72
73 if ($r->content_type eq 'application/x-www-form-urlencoded') {
74 # local $^W = 0;
75 $cgi->_decode_url_encoded_data (\$r->content, 'form');
76 } elsif ($r->content_type =~ /multipart\/form-data/) {
77 my ($boundary) = $r->content_type =~ /boundary=(\S+)$/;
78 $cgi->_parse_multipart_data ($r->content_length, $boundary);
79 }
80 } else {
81 $c->send_error(RC_FORBIDDEN);
82 }
83
84 my $param = $cgi->{web_data};
85 my $url = $r->url->path;
86
87 # XXX LOG
88 print $r->method," ",$url,"\n";
89 print Dumper($param),"\n" if ($debug);
90
91 # is this static page?
92 if ($static_html && -f "$static_html/$url") {
93 print "static file: $static_html/$url\n" if ($debug);
94 $c->send_file_response("$static_html/$url");
95 $c->close;
96 next;
97 }
98
99 # template file name (use ?format=html as default)
100 my $tpl_file = 'master.';
101 $tpl_file .= $param->{'format'} || 'html';
102
103 # parse date from url
104 my ($yyyy,$mm,$dd) = $mws->yyyymmdd;
105
106 my $yyyymm;
107
108 my $date_limit;
109
110 if ($url =~ m,^/(\d{4})[/-](\d+)[/-](\d+),) {
111 ($yyyy, $mm, $dd) = $mws->fmtdate($1,$2,$3);
112 $date_limit = "$yyyy-$mm-$dd";
113 } elsif ($url =~ m,^/(\d{4})[/-](\d+),) {
114 ($yyyy,$mm) = $mws->fmtdate($1,$2);
115 $date_limit = "$yyyy-$mm";
116 } elsif ($url =~ m,^/(\d{4}),) {
117 $date_limit = $mws->fmtdate($1);
118 }
119
120 #
121 # implement functionality and generate HTML
122 #
123 my $html;
124
125 if ($param->{'search_val'} && $param->{'search_fld'} && !$param->{'search'}) {
126 $param->{'search'} = $param->{'search_fld'}.":".$param->{'search_val'};
127 } elsif ($param->{'search'}) {
128 ($param->{'search_fld'}, $param->{'search_val'}) = split(/:/,$param->{'search'},2);
129 }
130
131 my $tpl_var = {
132 param => $param,
133 yyyy => $yyyy,
134 mm => $mm,
135 dd => $dd,
136 date_limit => $date_limit,
137 };
138
139 # is this access to root of web server?
140 if ($url eq "/" && !$param->{'search'}) {
141 # if first access, go to current year
142 $date_limit = $mws->fmtdate($yyyy);
143 $param->{sort_by} = "date desc";
144 }
145
146 # ?show_id=XXXXxxxx___message_id___xxxxXXXX
147 if ($param->{'show_id'}) {
148
149 $mws->reset_counters;
150 my $row = $mws->fetch_result_by_id($param->{'show_id'});
151 $tpl_var->{message} = $row;
152 } elsif ($param->{'search'} || $date_limit) {
153
154 # show search results
155 # ?search=foo:bar
156
157 my @search;
158 push @search, $param->{'search'} if ($param->{'search'});
159
160 if ($date_limit) {
161 push @search, "and" if (@search);
162 push @search, "date:\"$date_limit\"";
163 }
164
165 if ($param->{sort_by}) {
166 push @search, "sort:".$param->{sort_by};
167 }
168
169 print STDERR "search: ",join(" ",@search),"\n";
170
171 my $results = $mws->search(@search);
172 my @res = $mws->fetch_all_results();
173
174 $tpl_var->{results} = \@res if (@res);
175 $tpl_var->{total_hits} = $mws->{total_hits} || 0;
176
177 # no hits, offer suggestions
178 if (! $tpl_var->{results}) {
179 @{$tpl_var->{apropos}} = $mws->apropos_index($param->{'search_fld'}, $param->{'search_val'});
180 }
181
182 }
183
184
185 # push counters to template
186 foreach my $f (qw(from to cc bcc)) {
187 my $h = $mws->counter($f) || next;
188 my @a;
189 foreach my $k (sort { $h->{$b}->{usage} <=> $h->{$a}->{usage} } keys %$h) {
190 push @a, $h->{$k};
191 }
192 $tpl_var->{counters}->{$f} = [ @a ] if (@a);
193 }
194
195 # push calendar in template
196 $tpl_var->{calendar} = $mws->counter('calendar');
197
198 $tt->process($tpl_file, $tpl_var, \$html) || die $tt->error();
199
200 #
201 # send HTMLto client
202 #
203
204 my $res = HTTP::Response->new(RC_OK);
205 $res->header( 'Content-type' => 'text/html; charset=ISO-8859-2' );
206 $res->content($html);
207 $c->send_response($res);
208
209 $c->close;
210 }
211 undef($c);
212 }
213
214 # template toolkit filter
215
216 sub html_escape($) {
217 my $text = shift || return;
218
219 # don't re-escape html
220 #return $text if ($text =~ /&(:?lt|gt|amp|quot);/);
221
222 # Escape <, >, & and ", and to produce valid XML
223 my %escape = ('<'=>'&lt;', '>'=>'&gt;', '&'=>'&amp;', '"'=>'&quot;');
224 my $escape_re = join '|' => keys %escape;
225
226 $text =~ s/($escape_re)/$escape{$1}/gs;
227 return $text;
228 }
229
230 #use Text::Context::EitherSide;
231
232 sub body5_filter {
233 my $text = shift;
234
235 # remove quote
236 $text =~ s/^[\>:\|=]+\s*.*?$/#-q-#/msg;
237 # remove quote author
238 $text =~ s/[\n\r]+[^\n\r]+:\s*(:?#-q-#[\n\r*])+//gs;
239 $text =~ s/^[^\n\r]+:\s*(:?#-q-#[\n\r]*)+//gs;
240 $text =~ s/#-q-#[\n\r]*//gs;
241 # outlook quoting
242 $text =~ s/(\s*--+\s*Original\s+Message\s*--+.*)$//si;
243 $text =~ s/(\s*--+\s*Forwarded\s+message\s*from\s+.+\s*--+.*)$//si;
244
245 # remove signature
246 $text =~ s/[\n\r]+--\s*[\n\r]+.*$//s;
247
248 # compress cr/lf
249 $text =~ s/[\n\r]+/\n/gs;
250
251 # remove whitespaces
252 $text =~ s/^\n+//gs;
253 $text =~ s/[\s\n]+$//gs;
254
255 # cut to 5 lines;
256 if ($text =~ s,^((?:.*?[\n\r]){5}).*$,$1,s) {
257 $text =~ s/[\n\r]*$/ .../;
258 }
259
260 # my $context = Text::Context::EitherSide->new($text, context => 5);
261 # return $context->as_string("perl");
262
263 return html_escape($text);
264 }
265
266 sub body_filter {
267 my $text = shift;
268
269 my $sig = '';
270
271 # remove signature
272 if ($text =~ s/([\n\r]+)(--\s*[\n\r]+.*)$//s) {
273 $sig = "$1#-#signature##$2##signature#-#";
274 }
275
276 # find quoted text
277 $text =~ s/^([\>:\|=]+\s*.*?)$/#-#quote1##$1##quote1#-#/msg;
278 $text =~ s/(--+\s*Original\s+Message\s*--+.*)$/#-#quote2##$1##quote2#-#/si;
279 $text =~ s/(--+\s*Forwarded\s+message\s*from\s+.+\s*--+.*)$/#-#quote3##$1##quote3#-#/si;
280
281 $text = html_escape($text . $sig);
282 while ($text =~ s/#-#(quote|signature)(\d*)##(.+?)##\1\2#-#/<span class="$1">$3<\/span>/gs) { } ;
283 return $text;
284 }
285

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26