Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
fixed a few compression bugs in Mojo::Transaction::WebSocket and Mojo…
…::Content
  • Loading branch information
kraih committed Jan 28, 2014
1 parent a8deb4f commit f077d47
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 8 deletions.
4 changes: 3 additions & 1 deletion Changes
@@ -1,5 +1,7 @@

4.71 2014-01-27
4.71 2014-01-28
- Fixed a few compression bugs in Mojo::Transaction::WebSocket and
Mojo::Content.

4.70 2014-01-26
- Added extract_usage method to Mojolicious::Command.
Expand Down
3 changes: 2 additions & 1 deletion lib/Mojo/Content.pm
Expand Up @@ -286,7 +286,8 @@ sub _uncompress {
my ($self, $chunk) = @_;

# No compression
return $self->emit(read => $chunk) unless $self->is_compressed;
return $self->emit(read => $chunk)
unless $self->is_compressed && $self->auto_relax;

# Uncompress
$self->{post_buffer} .= $chunk;
Expand Down
16 changes: 10 additions & 6 deletions lib/Mojo/Transaction/WebSocket.pm
@@ -1,7 +1,7 @@
package Mojo::Transaction::WebSocket;
use Mojo::Base 'Mojo::Transaction';

use Compress::Raw::Zlib 'Z_SYNC_FLUSH';
use Compress::Raw::Zlib qw(Z_OK Z_SYNC_FLUSH);
use Config;
use Mojo::JSON;
use Mojo::Transaction::HTTP;
Expand Down Expand Up @@ -311,19 +311,23 @@ sub _message {
# Append chunk and check message size
$self->{op} = $op unless exists $self->{op};
$self->{message} .= $frame->[5];
return $self->finish(1009)
if length $self->{message} > $self->max_websocket_size;
my $max = $self->max_websocket_size;
return $self->finish(1009) if length $self->{message} > $max;

# No FIN bit (Continuation)
return unless $frame->[0];

# "permessage-deflate" extension (handshake and RSV1)
my $msg = delete $self->{message};
if ($self->compressed && $frame->[1]) {
my $inflate = $self->{inflate}
|| Compress::Raw::Zlib::Inflate->new(WindowBits => -15);
my $inflate = $self->{inflate} || Compress::Raw::Zlib::Inflate->new(
Bufsize => $max,
LimitOutput => 1,
WindowBits => -15
);
$self->{inflate} = $inflate if $self->context_takeover;
$inflate->inflate(\($msg .= "\x00\x00\xff\xff"), my $out);
return $self->finish(1009)
if $inflate->inflate(\($msg .= "\x00\x00\xff\xff"), my $out) != Z_OK;
$msg = $out;
}

Expand Down
20 changes: 20 additions & 0 deletions t/mojo/request.t
Expand Up @@ -3,6 +3,7 @@ use Mojo::Base -strict;
use Test::More;
use File::Spec::Functions 'catfile';
use File::Temp 'tempdir';
use IO::Compress::Gzip 'gzip';
use Mojo::Content::Single;
use Mojo::Content::MultiPart;
use Mojo::Cookie::Request;
Expand Down Expand Up @@ -480,6 +481,25 @@ is $req->headers->content_type, 'application/x-www-form-urlencoded',
is $req->headers->content_length, 14, 'right "Content-Length" value';
is $req->param('name'), '', 'right value';

# Parse HTTP 1.1 gzip compressed request (no decompression)
gzip \(my $uncompressed = 'abc' x 1000), \my $compressed;
$req = Mojo::Message::Request->new;
$req->parse("POST /foo HTTP/1.1\x0d\x0a");
$req->parse("Content-Type: text/plain\x0d\x0a");
$req->parse("Content-Length: @{[length $compressed]}\x0d\x0a");
$req->parse("Content-Encoding: GZip\x0d\x0a\x0d\x0a");
ok $req->content->is_compressed, 'content is compressed';
$req->parse($compressed);
ok $req->content->is_compressed, 'content is still compressed';
ok $req->is_finished, 'request is finished';
is $req->method, 'POST', 'right method';
is $req->version, '1.1', 'right version';
is $req->url, '/foo', 'right URL';
is $req->headers->content_type, 'text/plain', 'right "Content-Type" value';
is $req->headers->content_length, length($compressed),
'right "Content-Length" value';
is $req->body, $compressed, 'right content';

# Parse HTTP 1.1 chunked request
$req = Mojo::Message::Request->new;
is $req->content->progress, 0, 'right progress';
Expand Down

0 comments on commit f077d47

Please sign in to comment.