File Coverage

blib/lib/Apache/MimeXML.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


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__