Utf-8 and Content-Length header
Pav Lucistnik <[email protected]>
| Newsgroups | gmane.comp.lang.perl.modules.lwp |
|---|---|
| Message-ID | <[email protected]> |
A general problem exists in libwww when POSTing data to HTTP servers, Content-Length headers and syswrite() calls use length() function over payload to determine it's size. This fails on Utf-8 encoded data, because length() function returns the count of _characters_, not count of bytes. It leads to a message truncated. Solution is to use bytes::length() instead - it returns the size of string in bytes. Patch attached. -- Pav Lucistnik <[email protected]> <[email protected]> Every man is as God made him, ay, and often worse. -- Miguel de Cervantes
http.pm.diff
(text/x-patch, 2.7 KB)
--- http.pm.orig Thu Dec 8 11:28:01 2005
+++ http.pm Thu Jun 8 14:24:21 2006
@@ -182,8 +182,8 @@
else {
# Set (or override) Content-Length header
my $clen = $request_headers->header('Content-Length');
- if (defined($$content_ref) && length($$content_ref)) {
- $has_content = length($$content_ref);
+ if (defined($$content_ref) && bytes::length($$content_ref)) {
+ $has_content = bytes::length($$content_ref);
if (!defined($clen) || $clen ne $has_content) {
if (defined $clen) {
warn "Content-Length header value was wrong, fixed";
@@ -207,9 +207,9 @@
if (!$has_content || $write_wait || $has_content > 8*1024) {
# XXX need to watch out for write timeouts
- my $n = $socket->syswrite($req_buf, length($req_buf));
+ my $n = $socket->syswrite($req_buf, bytes::length($req_buf));
die $! unless defined($n);
- die "short write" unless $n == length($req_buf);
+ die "short write" unless $n == bytes::length($req_buf);
#LWP::Debug::conns($req_buf);
$req_buf = "";
}
@@ -224,7 +224,7 @@
if (ref($content_ref) eq 'CODE') {
my $buf = &$content_ref();
$buf = "" unless defined($buf);
- $buf = sprintf "%x%s%s%s", length($buf), $CRLF, $buf, $CRLF
+ $buf = sprintf "%x%s%s%s", bytes::length($buf), $CRLF, $buf, $CRLF
if $chunked;
substr($buf, 0, 0) = $req_buf if $req_buf;
$wbuf = \$buf;
@@ -243,7 +243,7 @@
my $fbits = '';
vec($fbits, fileno($socket), 1) = 1;
- while ($woffset < length($$wbuf)) {
+ while ($woffset < bytes::length($$wbuf)) {
my $time_before;
my $sel_timeout = $timeout;
@@ -267,7 +267,7 @@
if (defined($rbits) && $rbits =~ /[^\0]/) {
# readable
my $buf = $socket->_rbuf;
- my $n = $socket->sysread($buf, 1024, length($buf));
+ my $n = $socket->sysread($buf, 1024, bytes::length($buf));
unless ($n) {
die "EOF";
}
@@ -289,19 +289,19 @@
}
}
if (defined($wbits) && $wbits =~ /[^\0]/) {
- my $n = $socket->syswrite($$wbuf, length($$wbuf), $woffset);
+ my $n = $socket->syswrite($$wbuf, bytes::length($$wbuf), $woffset);
unless ($n) {
die "syswrite: $!" unless defined $n;
die "syswrite: no bytes written";
}
$woffset += $n;
- if (!$eof && $woffset >= length($$wbuf)) {
+ if (!$eof && $woffset >= bytes::length($$wbuf)) {
# need to refill buffer from $content_ref code
my $buf = &$content_ref();
$buf = "" unless defined($buf);
- $eof++ unless length($buf);
- $buf = sprintf "%x%s%s%s", length($buf), $CRLF, $buf, $CRLF
+ $eof++ unless bytes::length($buf);
+ $buf = sprintf "%x%s%s%s", bytes::length($buf), $CRLF, $buf, $CRLF
if $chunked;
$wbuf = \$buf;
$woffset = 0;