Codebase list libhttp-tiny-perl / 92e1a27
Preserve header case for non-standard headers. This commit adds a list of well-known headers. The case for those headers is canonicalized. All other headers are sent with the case provided by users. Fixes #79. David Golden 8 years ago
2 changed file(s) with 36 addition(s) and 13 deletion(s). Raw diff Collapse all Expand all
44 headers
55 Accept: */*
66 X-Custom: This is a custom header
7 x-lower: This is a lower-case custom header
8 authorization: fake auth data
79 ----------
810 GET /index.html HTTP/1.1
911 Host: example.com
1012 Accept: */*
13 Authorization: fake auth data
1114 Connection: close
1215 User-Agent: HTTP-Tiny/VERSION
1316 X-Custom: This is a custom header
17 x-lower: This is a lower-case custom header
1418
1519 ----------
1620 HTTP/1.1 200 OK
706706 next unless defined;
707707 while (my ($k, $v) = each %$_) {
708708 $request->{headers}{lc $k} = $v;
709 $request->{header_case}{lc $k} = $k;
709710 }
710711 }
711712
11771178 sub write_request {
11781179 @_ == 2 || die(q/Usage: $handle->write_request(request)/ . "\n");
11791180 my($self, $request) = @_;
1180 $self->write_request_header(@{$request}{qw/method uri headers/});
1181 $self->write_request_header(@{$request}{qw/method uri headers header_case/});
11811182 $self->write_body($request) if $request->{cb};
11821183 return;
11831184 }
11841185
1185 my %HeaderCase = (
1186 'content-md5' => 'Content-MD5',
1187 'etag' => 'ETag',
1188 'te' => 'TE',
1189 'www-authenticate' => 'WWW-Authenticate',
1190 'x-xss-protection' => 'X-XSS-Protection',
1186 # Standard request header names/case from HTTP/1.1 RFCs
1187 my @rfc_request_headers = qw(
1188 Accept Accept-Charset Accept-Encoding Accept-Language Authorization
1189 Cache-Control Connection Content-Length Expect From Host
1190 If-Match If-Modified-Since If-None-Match If-Range If-Unmodified-Since
1191 Max-Forwards Pragma Proxy-Authorization Range Referer TE Trailer
1192 Transfer-Encoding Upgrade User-Agent Via
11911193 );
1194
1195 my @other_request_headers = qw(
1196 Content-Encoding Content-MD5 Content-Type Cookie DNT Date Origin
1197 X-XSS-Protection
1198 );
1199
1200 my %HeaderCase = map { lc($_) => $_ } @rfc_request_headers, @other_request_headers;
11921201
11931202 # to avoid multiple small writes and hence nagle, you can pass the method line or anything else to
11941203 # combine writes.
11951204 sub write_header_lines {
1196 (@_ == 2 || @_ == 3 && ref $_[1] eq 'HASH') || die(q/Usage: $handle->write_header_lines(headers[,prefix])/ . "\n");
1197 my($self, $headers, $prefix_data) = @_;
1205 (@_ >= 2 && @_ <= 4 && ref $_[1] eq 'HASH') || die(q/Usage: $handle->write_header_lines(headers, [header_case, prefix])/ . "\n");
1206 my($self, $headers, $header_case, $prefix_data) = @_;
1207 $header_case ||= {};
11981208
11991209 my $buf = (defined $prefix_data ? $prefix_data : '');
12001210 while (my ($k, $v) = each %$headers) {
12011211 my $field_name = lc $k;
12021212 if (exists $HeaderCase{$field_name}) {
12031213 $field_name = $HeaderCase{$field_name};
1214 }
1215 elsif (exists $header_case->{$field_name}) {
1216 $field_name = $header_case->{$field_name};
12041217 }
12051218 else {
12061219 $field_name =~ /\A $Token+ \z/xo
13631376 }
13641377
13651378 sub write_request_header {
1366 @_ == 4 || die(q/Usage: $handle->write_request_header(method, request_uri, headers)/ . "\n");
1367 my ($self, $method, $request_uri, $headers) = @_;
1368
1369 return $self->write_header_lines($headers, "$method $request_uri HTTP/1.1\x0D\x0A");
1379 @_ == 5 || die(q/Usage: $handle->write_request_header(method, request_uri, headers, header_case)/ . "\n");
1380 my ($self, $method, $request_uri, $headers, $header_case) = @_;
1381
1382 return $self->write_header_lines($headers, $header_case, "$method $request_uri HTTP/1.1\x0D\x0A");
13701383 }
13711384
13721385 sub _do_timeout {
17061719
17071720 There is no support for a Request-URI of '*' for the 'OPTIONS' request.
17081721
1722 =item *
1723
1724 Headers mentioned in the RFCs and some other, well-known headers are
1725 generated with their canonical case. Other headers are sent in the
1726 case provided by the user. There is no order to header fields.
1727
17091728 =back
17101729
17111730 Despite the limitations listed above, HTTP::Tiny is considered