| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
# $Id: MimeXML.pm,v 1.2 2000/05/10 21:23:41 matt Exp $ |
|
2
|
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
package Apache::MimeXML; |
|
4
|
|
|
|
|
|
|
|
|
5
|
1
|
|
|
1
|
|
851
|
use strict; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
48
|
|
|
6
|
1
|
|
|
1
|
|
1848
|
use Apache::Constants qw(:common); |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
use Apache::File; |
|
8
|
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
$Apache::MimeXML::VERSION = '0.08'; |
|
10
|
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
my $feff = chr(0xFE) . chr(0xFF); |
|
12
|
|
|
|
|
|
|
my $fffe = chr(0xFF) . chr(0xFE); |
|
13
|
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
my @ebasci = ( |
|
15
|
|
|
|
|
|
|
0x00, 0x01, 0x02, 0x03, 0x9C, 0x09, 0x86, 0x7F, |
|
16
|
|
|
|
|
|
|
0x97, 0x8D, 0x8E, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, |
|
17
|
|
|
|
|
|
|
0x10, 0x11, 0x12, 0x13, 0x9D, 0x85, 0x08, 0x87, |
|
18
|
|
|
|
|
|
|
0x18, 0x19, 0x92, 0x8F, 0x1C, 0x1D, 0x1E, 0x1F, |
|
19
|
|
|
|
|
|
|
0x80, 0x81, 0x82, 0x83, 0x84, 0x0A, 0x17, 0x1B, |
|
20
|
|
|
|
|
|
|
0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x05, 0x06, 0x07, |
|
21
|
|
|
|
|
|
|
0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, |
|
22
|
|
|
|
|
|
|
0x98, 0x99, 0x9A, 0x9B, 0x14, 0x15, 0x9E, 0x1A, |
|
23
|
|
|
|
|
|
|
0x20, 0xA0, 0xE2, 0xE4, 0xE0, 0xE1, 0xE3, 0xE5, |
|
24
|
|
|
|
|
|
|
0xE7, 0xF1, 0xA2, 0x2E, 0x3C, 0x28, 0x2B, 0x7C, |
|
25
|
|
|
|
|
|
|
0x26, 0xE9, 0xEA, 0xEB, 0xE8, 0xED, 0xEE, 0xEF, |
|
26
|
|
|
|
|
|
|
0xEC, 0xDF, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAC, |
|
27
|
|
|
|
|
|
|
0x2D, 0x2F, 0xC2, 0xC4, 0xC0, 0xC1, 0xC3, 0xC5, |
|
28
|
|
|
|
|
|
|
0xC7, 0xD1, 0xA6, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, |
|
29
|
|
|
|
|
|
|
0xF8, 0xC9, 0xCA, 0xCB, 0xC8, 0xCD, 0xCE, 0xCF, |
|
30
|
|
|
|
|
|
|
0xCC, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, |
|
31
|
|
|
|
|
|
|
0xD8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, |
|
32
|
|
|
|
|
|
|
0x68, 0x69, 0xAB, 0xBB, 0xF0, 0xFD, 0xFE, 0xB1, |
|
33
|
|
|
|
|
|
|
0xB0, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, |
|
34
|
|
|
|
|
|
|
0x71, 0x72, 0xAA, 0xBA, 0xE6, 0xB8, 0xC6, 0xA4, |
|
35
|
|
|
|
|
|
|
0xB5, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, |
|
36
|
|
|
|
|
|
|
0x79, 0x7A, 0xA1, 0xBF, 0xD0, 0xDD, 0xDE, 0xAE, |
|
37
|
|
|
|
|
|
|
0x5E, 0xA3, 0xA5, 0xB7, 0xA9, 0xA7, 0xB6, 0xBC, |
|
38
|
|
|
|
|
|
|
0xBD, 0xBE, 0x5B, 0x5D, 0xAF, 0xA8, 0xB4, 0xD7, |
|
39
|
|
|
|
|
|
|
0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, |
|
40
|
|
|
|
|
|
|
0x48, 0x49, 0xAD, 0xF4, 0xF6, 0xF2, 0xF3, 0xF5, |
|
41
|
|
|
|
|
|
|
0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, |
|
42
|
|
|
|
|
|
|
0x51, 0x52, 0xB9, 0xFB, 0xFC, 0xF9, 0xFA, 0xFF, |
|
43
|
|
|
|
|
|
|
0x5C, 0xF7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, |
|
44
|
|
|
|
|
|
|
0x59, 0x5A, 0xB2, 0xD4, 0xD6, 0xD2, 0xD3, 0xD5, |
|
45
|
|
|
|
|
|
|
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, |
|
46
|
|
|
|
|
|
|
0x38, 0x39, 0xB3, 0xDB, 0xDC, 0xD9, 0xDA, 0x9F); |
|
47
|
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
sub handler { |
|
49
|
|
|
|
|
|
|
my $r = shift; |
|
50
|
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
return DECLINED unless -e $r->finfo; |
|
52
|
|
|
|
|
|
|
return DECLINED if -d $r->finfo; |
|
53
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
my $encoding = check_for_xml($r->filename); |
|
55
|
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
if ($encoding) { |
|
57
|
|
|
|
|
|
|
my $type = $r->dir_config('XMLMimeType') || 'application/xml'; |
|
58
|
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
if ($encoding eq 'utf-16-be') { |
|
60
|
|
|
|
|
|
|
$encoding = $r->dir_config('XMLUtf16EncodingBE') || 'utf-16'; |
|
61
|
|
|
|
|
|
|
$type =~ s/^text\/xml$/application\/xml/; |
|
62
|
|
|
|
|
|
|
} |
|
63
|
|
|
|
|
|
|
elsif ($encoding eq 'utf-16-le') { |
|
64
|
|
|
|
|
|
|
$encoding = $r->dir_config('XMLUtf16EncodingLE') || 'utf-16-le'; |
|
65
|
|
|
|
|
|
|
$type =~ s/^text\/xml$/application\/xml/; |
|
66
|
|
|
|
|
|
|
} |
|
67
|
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
$r->notes('is_xml', 1); |
|
69
|
|
|
|
|
|
|
$r->push_handlers('PerlFixupHandler', |
|
70
|
|
|
|
|
|
|
sub { |
|
71
|
|
|
|
|
|
|
my $r = shift; |
|
72
|
|
|
|
|
|
|
$r->content_type("$type; charset=$encoding"); |
|
73
|
|
|
|
|
|
|
return OK; |
|
74
|
|
|
|
|
|
|
}); |
|
75
|
|
|
|
|
|
|
} |
|
76
|
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
return DECLINED; |
|
78
|
|
|
|
|
|
|
} |
|
79
|
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
sub check_for_xml { |
|
81
|
|
|
|
|
|
|
my $filename = shift; |
|
82
|
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
my $firstline; |
|
84
|
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
if (ref($filename) && UNIVERSAL::isa($filename, 'IO::Handler')) { |
|
86
|
|
|
|
|
|
|
my $fh = $filename; |
|
87
|
|
|
|
|
|
|
binmode $fh; |
|
88
|
|
|
|
|
|
|
sysread($fh, $firstline, 200); # Read 200 bytes. This is a guestimate... |
|
89
|
|
|
|
|
|
|
} |
|
90
|
|
|
|
|
|
|
else { |
|
91
|
|
|
|
|
|
|
eval { |
|
92
|
|
|
|
|
|
|
my $fh = *{$filename}{IO}; |
|
93
|
|
|
|
|
|
|
binmode $fh; |
|
94
|
|
|
|
|
|
|
sysread($fh, $firstline, 200); # Read 200 bytes. This is a guestimate... |
|
95
|
|
|
|
|
|
|
}; |
|
96
|
|
|
|
|
|
|
if ($@) { |
|
97
|
|
|
|
|
|
|
eval { |
|
98
|
|
|
|
|
|
|
open(FH, $filename) or die "Open failed: $!"; |
|
99
|
|
|
|
|
|
|
binmode FH; |
|
100
|
|
|
|
|
|
|
sysread(FH, $firstline, 200); # Read 200 bytes. This is a guestimate... |
|
101
|
|
|
|
|
|
|
close FH; |
|
102
|
|
|
|
|
|
|
}; |
|
103
|
|
|
|
|
|
|
if ($@) { |
|
104
|
|
|
|
|
|
|
warn "failed? $@\n"; |
|
105
|
|
|
|
|
|
|
return; |
|
106
|
|
|
|
|
|
|
} |
|
107
|
|
|
|
|
|
|
} |
|
108
|
|
|
|
|
|
|
} |
|
109
|
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
if (substr($firstline, 0, 2) eq $feff) { |
|
111
|
|
|
|
|
|
|
# Probably utf-16 |
|
112
|
|
|
|
|
|
|
if ($firstline =~ m/^$feff\x00<\x00\?\x00x\x00m\x00l/) { |
|
113
|
|
|
|
|
|
|
return 'utf-16-be'; |
|
114
|
|
|
|
|
|
|
} |
|
115
|
|
|
|
|
|
|
} |
|
116
|
|
|
|
|
|
|
elsif (substr($firstline, 0, 2) eq $fffe) { |
|
117
|
|
|
|
|
|
|
# Probably utf-16-little-endian... |
|
118
|
|
|
|
|
|
|
if ($firstline =~ m/^$fffe<\x00\?\x00x\x00m\x00l\x00/) { |
|
119
|
|
|
|
|
|
|
return 'utf-16-le'; |
|
120
|
|
|
|
|
|
|
} |
|
121
|
|
|
|
|
|
|
} |
|
122
|
|
|
|
|
|
|
elsif (substr($firstline, 0, 1) eq chr(0x4C)) { |
|
123
|
|
|
|
|
|
|
# Possibly ebdic... |
|
124
|
|
|
|
|
|
|
if ($firstline =~ m/^\x4C\x6F\xA7\x94\x93(.*?)\x6F\x6E/s) { |
|
125
|
|
|
|
|
|
|
my $attribs = $1; |
|
126
|
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
# EBCDIC things we need to know... |
|
128
|
|
|
|
|
|
|
# encoding = 85 95 83 96 84 89 95 87 |
|
129
|
|
|
|
|
|
|
# whitespace = [ 40 05 0D 25 ] |
|
130
|
|
|
|
|
|
|
# quote/apos = [ 7F 7D ] |
|
131
|
|
|
|
|
|
|
# '=' = 7E |
|
132
|
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
my $ws = '\x40\x05\x0d\x25'; |
|
134
|
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
if ($attribs =~ m/\x85\x95\x83\x96\x84\x89\x95\x87[$ws]*\x7e[$ws]*(\x7f|\x7d)(.*?)\1/s) { |
|
136
|
|
|
|
|
|
|
my $encoding = $2; |
|
137
|
|
|
|
|
|
|
$encoding =~ s/(.)/chr($ebasci[ord($1)])/eg; |
|
138
|
|
|
|
|
|
|
return $encoding; |
|
139
|
|
|
|
|
|
|
} |
|
140
|
|
|
|
|
|
|
} |
|
141
|
|
|
|
|
|
|
} |
|
142
|
|
|
|
|
|
|
else { |
|
143
|
|
|
|
|
|
|
if ($firstline =~ m/^<\?xml(.*?)\?>/s) { |
|
144
|
|
|
|
|
|
|
my $attribs = $1; |
|
145
|
|
|
|
|
|
|
if ($attribs =~ m/encoding[\s]*=[\s]*(["'])(.*?)\1/s) { |
|
146
|
|
|
|
|
|
|
return $2; |
|
147
|
|
|
|
|
|
|
} |
|
148
|
|
|
|
|
|
|
else { |
|
149
|
|
|
|
|
|
|
# Assume utf-8 |
|
150
|
|
|
|
|
|
|
return 'utf-8'; |
|
151
|
|
|
|
|
|
|
} |
|
152
|
|
|
|
|
|
|
} |
|
153
|
|
|
|
|
|
|
} |
|
154
|
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
return; |
|
156
|
|
|
|
|
|
|
} |
|
157
|
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
1; |
|
159
|
|
|
|
|
|
|
__END__ |