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__ |