… | |
… | |
37 | . "access-control-allow-origin: *\015\012" |
37 | . "access-control-allow-origin: *\015\012" |
38 | . $_[0]{ohdr} |
38 | . $_[0]{ohdr} |
39 | . "$_[3]\015\012" . ($_[0]{give_head} ? "" : $_[2])); |
39 | . "$_[3]\015\012" . ($_[0]{give_head} ? "" : $_[2])); |
40 | } |
40 | } |
41 | |
41 | |
42 | my $cache_headers = "cache-control: max-age=8640000\015\012" |
42 | my $cache_headers = "cache-control: public, max-age=8640000\015\012" |
43 | . "etag: \"0\"\015\012"; |
43 | . "etag: \"0\"\015\012"; |
44 | |
44 | |
|
|
45 | my $revalidate_headers = "cache-control: public, max-age=60, must-revalidate\015\012"; |
|
|
46 | |
|
|
47 | my $nocache_headers = "cache-control: no-cache, max-age=0\015\012"; |
|
|
48 | |
45 | sub content_type { |
49 | sub content_type($$) { |
46 | return "content-type: image/png\015\012" if $_[0] =~ /^\x89PNG/; |
50 | return "content-type: image/png\015\012" if $_[1] =~ /^\x89PNG/; |
47 | return "content-type: image/jpeg\015\012" if $_[0] =~ /^......JFIF/s; |
51 | return "content-type: image/jpeg\015\012" if $_[1] =~ /^......JFIF/s; |
48 | return "content-type: audio/wav\015\012" if $_[0] =~ /^RIFF/; |
52 | return "content-type: audio/wav\015\012" if $_[1] =~ /^RIFF/; |
49 | return "content-type: audio/ogg\015\012" if $_[0] =~ /^OggS/; |
53 | return "content-type: audio/ogg\015\012" if $_[1] =~ /^OggS/; |
|
|
54 | return "content-type: text/css; charset=utf-8\015\012" if $_[0] =~ /\.css$/; |
|
|
55 | return "content-type: application/javascript; charset=utf-8\015\012" if $_[0] =~ /\.js$/; |
50 | return "content-type: text/html\015\012" if $_[0] =~ /^</; |
56 | return "content-type: text/html; charset=utf-8\015\012" if $_[1] =~ /^</; |
51 | |
57 | |
52 | "content-type: text/plain\015\012" |
58 | "content-type: text/plain; charset=utf-8\015\012" |
53 | } |
59 | } |
54 | |
60 | |
55 | sub handle_con { |
61 | sub handle_con { |
56 | my ($self) = @_; |
62 | my ($self) = @_; |
57 | |
63 | |
… | |
… | |
133 | (my $meta, $data) = unpack "(w/a*)*", $data |
139 | (my $meta, $data) = unpack "(w/a*)*", $data |
134 | if $type & 1; |
140 | if $type & 1; |
135 | |
141 | |
136 | if ($want_meta) { |
142 | if ($want_meta) { |
137 | if ($type & 1) { |
143 | if ($type & 1) { |
138 | $self->respond ("200 OK", $meta, "content-type: text/plain\015\012" . $cache_headers); |
144 | $self->respond ("200 OK", $meta, "content-type: text/plain; charset=utf-8\015\012" . $cache_headers); |
139 | } else { |
145 | } else { |
140 | $self->respond ("404 type $type has no metadata"); |
146 | $self->respond ("404 type $type has no metadata"); |
141 | } |
147 | } |
142 | } else { |
148 | } else { |
143 | $self->respond ("200 OK", $data, (content_type $data) . $cache_headers); |
149 | $self->respond ("200 OK", $data, (content_type $uri, $data) . $cache_headers); |
144 | } |
150 | } |
145 | |
151 | |
146 | } elsif (my $idx = (cf::face::find "res/http$uri") || (cf::face::find "res/http${uri}index.html")) { |
152 | } elsif (my $idx = (cf::face::find "res/http$uri") || (cf::face::find "res/http${uri}index.html")) { |
147 | # TODO: use etag (shudder) |
|
|
148 | my $data = cf::face::get_data $idx; |
153 | my $data = cf::face::get_data $idx; |
|
|
154 | my $csum = unpack "H*", cf::face::get_csum $idx; |
|
|
155 | my $hdr = "etag: \"$csum\"\015\012" . $revalidate_headers; |
|
|
156 | |
|
|
157 | if ($req =~ /if-none-match: "$csum"/i) { # dirtiest hack evar |
|
|
158 | $self->respond ("304 not modified", "", $hdr); |
|
|
159 | next; |
|
|
160 | } |
|
|
161 | |
149 | $self->respond ("200 OK", $data, (content_type $data) . $cache_headers); |
162 | $self->respond ("200 OK", $data, (content_type $uri, $data) . $hdr); |
150 | |
163 | |
151 | } elsif (cf::face::find "res/http$uri/index.html") { |
164 | } elsif (cf::face::find "res/http$uri/index.html") { |
152 | $self->respond ("302 dirslash", "", "location: $uri/\015\012"); |
165 | $self->respond ("302 dirslash", "", "location: $uri/\015\012" . $nocache_headers); |
153 | |
166 | |
154 | } elsif ($uri eq "/debug") { # for debugging |
167 | } elsif ($uri eq "/debug") { # for debugging |
155 | my @body = <<EOF; |
168 | my @body = <<EOF; |
156 | <html><head><style> |
169 | <html><head><style> |
157 | th:nth-child(1) { text-align: right; } |
170 | th:nth-child(1) { text-align: right; } |
… | |
… | |
185 | |
198 | |
186 | push @body, "</body></html>"; |
199 | push @body, "</body></html>"; |
187 | |
200 | |
188 | my $body = join "", @body; |
201 | my $body = join "", @body; |
189 | utf8::encode $body; |
202 | utf8::encode $body; |
190 | $self->respond ("200 OK", $body, "content-type: text/html\015\012"); |
203 | $self->respond ("200 OK", $body, "content-type: text/html; charset=utf-8\015\012"); |
191 | |
204 | |
192 | } else { |
205 | } else { |
193 | $self->respond ("404 not found"); |
206 | $self->respond ("404 not found"); |
194 | } |
207 | } |
195 | |
208 | |