Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
better tests for message parser
  • Loading branch information
kraih committed May 29, 2014
1 parent 81ea5fa commit 3c74b0e
Show file tree
Hide file tree
Showing 17 changed files with 72 additions and 63 deletions.
19 changes: 7 additions & 12 deletions lib/Mojo/Message.pm
Expand Up @@ -74,15 +74,9 @@ sub dom {

sub error {
my $self = shift;

# Set
if (@_) {
$self->{error} = shift;
return $self->finish;
}

# Get
return $self->{error};
return $self->{error} unless @_;
$self->{error} = shift;
return $self->finish;
}

sub extract_start_line {
Expand Down Expand Up @@ -179,7 +173,8 @@ sub parse {
if $self->headers->is_limit_exceeded;

# Check buffer size
return $self->error({msg => 'Maximum buffer size exceeded', advise => 400})
return $self->error(
{message => 'Maximum buffer size exceeded', advise => 400})
if $self->content->is_limit_exceeded;

return $self->emit('progress')->content->is_finished ? $self->finish : $self;
Expand Down Expand Up @@ -254,7 +249,7 @@ sub _cache {
sub _limit {
my ($self, $msg, $code) = @_;
$self->{limit} = 1;
$self->error({msg => $msg, advise => $code});
$self->error({message => $msg, advise => $code});
}

sub _parse_formdata {
Expand Down Expand Up @@ -496,7 +491,7 @@ make sure it is not excessively large, there's a 10MB limit by default.
=head2 error
my $err = $msg->error;
$msg = $msg->error({msg => 'Parser error', advise => 500});
$msg = $msg->error({message => 'Parser error', advise => 500});
Message error.
Expand Down
2 changes: 1 addition & 1 deletion lib/Mojo/Message/Request.pm
Expand Up @@ -61,7 +61,7 @@ sub extract_start_line {
return undef unless $$bufref =~ s/^\s*(.*?)\x0d?\x0a//;

# We have a (hopefully) full request line
$self->error({msg => 'Bad request start line', advise => 400})
$self->error({message => 'Bad request start line', advise => 400})
and return undef
unless $1 =~ $START_LINE_RE;
my $url = $self->method($1)->version($3)->url;
Expand Down
2 changes: 1 addition & 1 deletion lib/Mojo/Message/Response.pm
Expand Up @@ -95,7 +95,7 @@ sub extract_start_line {

# We have a full response line
return undef unless $$bufref =~ s/^(.*?)\x0d?\x0a//;
$self->error({msg => 'Bad response start line'}) and return undef
$self->error({message => 'Bad response start line'}) and return undef
unless $1 =~ m!^\s*HTTP/(\d\.\d)\s+(\d\d\d)\s*(.+)?$!;
$self->content->skip_body(1) if $self->code($2)->is_empty;
return !!$self->version($1)->message($3)->content->auto_relax(1);
Expand Down
8 changes: 4 additions & 4 deletions lib/Mojo/Transaction.pm
Expand Up @@ -15,12 +15,12 @@ sub client_close {
# Premature connection close
my $res = $self->res->finish;
if ($close && !$res->code && !$res->error) {
$res->error({msg => 'Premature connection close'});
$res->error({message => 'Premature connection close'});
}

# 400/500
elsif ($res->is_status_class(400) || $res->is_status_class(500)) {
$res->error({msg => $res->message, code => $res->code});
$res->error({message => $res->message, code => $res->code});
}

return $self->server_close;
Expand Down Expand Up @@ -279,8 +279,8 @@ message in L</"error">, 400 and 500 responses also a code.
if (my $res = $tx->success) { say $res->body }
else {
my $err = $tx->error;
die "$err->{code} response: $err->{msg}" if $err->{code};
die "Connection error: $err->{msg}";
die "$err->{code} response: $err->{message}" if $err->{code};
die "Connection error: $err->{message}";
}
=head1 SEE ALSO
Expand Down
10 changes: 5 additions & 5 deletions lib/Mojo/UserAgent.pm
Expand Up @@ -130,7 +130,7 @@ sub _connect_proxy {

# CONNECT failed (connection needs to be kept alive)
unless ($tx->keep_alive && $tx->res->is_status_class(200)) {
$old->req->error({msg => 'Proxy connection failed'});
$old->req->error({message => 'Proxy connection failed'});
return $self->$cb($old);
}

Expand Down Expand Up @@ -234,7 +234,7 @@ sub _error {
my ($self, $id, $err, $timeout) = @_;

if (my $tx = $self->{connections}{$id}{tx}) {
$tx->res->error({msg => $err});
$tx->res->error({message => $err});
}
elsif (!$timeout) { return $self->emit(error => $err) }
$self->_handle($id, 1);
Expand Down Expand Up @@ -392,8 +392,8 @@ Mojo::UserAgent - Non-blocking I/O HTTP and WebSocket user agent
if (my $res = $tx->success) { say $res->body }
else {
my $err = $tx->error;
die "$err->{code} response: $err->{msg}" if $err->{code};
die "Connection error: $err->{msg}";
die "$err->{code} response: $err->{message}" if $err->{code};
die "Connection error: $err->{message}";
}
# Quick JSON API request with Basic authentication
Expand Down Expand Up @@ -679,7 +679,7 @@ L<Mojo::UserAgent::Transactor/"tx">.
$tx->res->on(progress => sub {
my $res = shift;
return unless my $server = $res->headers->server;
$res->error({msg => 'Oh noes, it is IIS!'}) if $server =~ /IIS/;
$res->error({message => 'Oh noes, it is IIS!'}) if $server =~ /IIS/;
});
$tx = $ua->start($tx);
Expand Down
2 changes: 1 addition & 1 deletion lib/Mojolicious/Command/cpanify.pm
Expand Up @@ -29,7 +29,7 @@ sub run {

unless ($tx->success) {
my $code = $tx->res->code // 0;
my $msg = $tx->error->{msg};
my $msg = $tx->error->{message};
if ($code == 401) { $msg = 'Wrong username or password.' }
elsif ($code == 409) { $msg = 'File already exists on CPAN.' }
die qq{Problem uploading file "$file". ($msg)\n};
Expand Down
2 changes: 1 addition & 1 deletion lib/Mojolicious/Command/get.pm
Expand Up @@ -67,7 +67,7 @@ sub run {
my $tx = $ua->start($ua->build_tx($method, $url, \%headers, $content));
my $err = $tx->error;
$url = encode 'UTF-8', $url;
warn qq{Problem loading URL "$url". ($err->{msg})\n}
warn qq{Problem loading URL "$url". ($err->{message})\n}
if $err && !$err->{code};

# JSON Pointer
Expand Down
4 changes: 2 additions & 2 deletions lib/Test/Mojo.pm
Expand Up @@ -337,8 +337,8 @@ sub _request_ok {
# Perform request
$self->tx($self->ua->start($tx));
my $err = $self->tx->error;
Test::More::diag $err->{msg}
if !(my $ok = !$err->{msg} || $err->{code}) && $err;
Test::More::diag $err->{message}
if !(my $ok = !$err->{message} || $err->{code}) && $err;
my $desc = encode 'UTF-8', "@{[uc $tx->req->method]} $url";
return $self->_test('ok', $ok, $desc);
}
Expand Down
3 changes: 2 additions & 1 deletion lib/ojo.pm
Expand Up @@ -43,7 +43,8 @@ sub _request {

my $tx = $ua->start($ua->build_tx(@_));
my $err = $tx->error;
warn qq/Problem loading URL "@{[$tx->req->url->to_abs]}". ($err->{msg})\n/
warn
qq/Problem loading URL "@{[$tx->req->url->to_abs]}". ($err->{message})\n/
if $err && !$err->{code};

return $tx->res;
Expand Down
2 changes: 1 addition & 1 deletion t/mojo/daemon.t
Expand Up @@ -234,7 +234,7 @@ is scalar @{$daemon->acceptors}, 0, 'no active acceptors';
$tx = $ua->inactivity_timeout(0.5)
->get("http://127.0.0.1:$port/throttle2" => {Connection => 'close'});
ok !$tx->success, 'not successful';
is $tx->error->{msg}, 'Inactivity timeout', 'right error';
is $tx->error->{message}, 'Inactivity timeout', 'right error';
$daemon->start;
$tx = $ua->inactivity_timeout(10)
->get("http://127.0.0.1:$port/throttle3" => {Connection => 'close'});
Expand Down
33 changes: 20 additions & 13 deletions t/mojo/request.t
Expand Up @@ -19,7 +19,7 @@ $req->parse('Cookie: ' . ('a=b; ' x (1024 * 1024 * 2)) . "\x0d\x0a");
$req->parse("Content-Length: 0\x0d\x0a\x0d\x0a");
ok $finished, 'finish event has been emitted';
ok $req->is_finished, 'request is finished';
is $req->error->{msg}, 'Maximum message size exceeded', 'right error';
is $req->error->{message}, 'Maximum message size exceeded', 'right error';
is $req->method, 'GET', 'right method';
is $req->version, '1.1', 'right version';
is $req->url, '/', 'right URL';
Expand All @@ -32,7 +32,7 @@ $req->parse("GET / HTTP/1.1\x0d\x0a");
$req->parse('Cookie: ' . ('a=b; ' x 131072) . "\x0d\x0a");
$req->parse("Content-Length: 0\x0d\x0a\x0d\x0a");
ok $req->is_finished, 'request is finished';
is $req->error->{msg}, 'Maximum line size exceeded', 'right error';
is $req->error->{message}, 'Maximum line size exceeded', 'right error';
is $req->method, 'GET', 'right method';
is $req->version, '1.1', 'right version';
is $req->url, '/', 'right URL';
Expand All @@ -47,7 +47,7 @@ $req->parse("Content-Length: 4\x0d\x0aCookie: "
. ('a=b; ' x 131072)
. "\x0d\x0aX-Test: 23\x0d\x0a\x0d\x0aabcd");
ok $req->is_finished, 'request is finished';
is $req->error->{msg}, 'Maximum line size exceeded', 'right error';
is $req->error->{message}, 'Maximum line size exceeded', 'right error';
is $req->method, 'GET', 'right method';
is $req->version, '1.1', 'right version';
is $req->url, '/', 'right URL';
Expand All @@ -66,12 +66,19 @@ is $req->version, '1.1', 'right version';
is $req->url, '/', 'right URL';
is $req->body, 'a=b; ' x 131072, 'right content';

# Parse broken start line
$req = Mojo::Message::Request->new;
$req->parse("12345\x0d\x0a");
ok $req->is_finished, 'request is finished';
is $req->error->{message}, 'Bad request start line', 'right error';
is $req->error->{advise}, 400, 'right advise';

# Parse broken HTTP 1.1 message with header exceeding line limit
$req = Mojo::Message::Request->new;
$req->parse("GET / HTTP/1.1\x0d\x0a");
$req->parse("Content-Length: 0\x0d\x0aCookie: " . ('a=b; ' x 131072));
ok $req->is_finished, 'request is finished';
is $req->error->{msg}, 'Maximum line size exceeded', 'right error';
is $req->error->{message}, 'Maximum line size exceeded', 'right error';
is $req->method, 'GET', 'right method';
is $req->version, '1.1', 'right version';
is $req->url, '/', 'right URL';
Expand All @@ -83,7 +90,7 @@ $req = Mojo::Message::Request->new;
is $req->max_line_size, 10240, 'right size';
$req->parse('GET /' . ('abcd' x 131072) . ' HTTP/1.1');
ok $req->is_finished, 'request is finished';
is $req->error->{msg}, 'Maximum line size exceeded', 'right error';
is $req->error->{message}, 'Maximum line size exceeded', 'right error';
is $req->method, 'GET', 'right method';
is $req->version, '1.1', 'right version';
is $req->url, '', 'no URL';
Expand All @@ -96,7 +103,7 @@ $req = Mojo::Message::Request->new;
$req->parse('GET /');
$req->parse('abcd' x 131072);
ok $req->is_finished, 'request is finished';
is $req->error->{msg}, 'Maximum line size exceeded', 'right error';
is $req->error->{message}, 'Maximum line size exceeded', 'right error';
is $req->method, 'GET', 'right method';
is $req->version, '1.1', 'right version';
is $req->url, '', 'no URL';
Expand Down Expand Up @@ -331,12 +338,12 @@ is $req->headers->content_length, undef, 'no "Content-Length" value';
is $req->headers->max_line_size, 5, 'right size';
$req->parse('GET /foo/bar/baz.html HTTP/1');
ok $req->is_finished, 'request is finished';
is $req->error->{msg}, 'Maximum line size exceeded', 'right error';
is $req->error->{message}, 'Maximum line size exceeded', 'right error';
is $req->error->{advise}, 431, 'right advise';
ok $req->is_limit_exceeded, 'limit is exceeded';
ok $limit, 'limit is exceeded';
$req->error({msg => 'Nothing important.'});
is $req->error->{msg}, 'Nothing important.', 'right error';
$req->error({message => 'Nothing important.'});
is $req->error->{message}, 'Nothing important.', 'right error';
is $req->error->{advise}, undef, 'no advise';
ok $req->is_limit_exceeded, 'limit is still exceeded';
}
Expand All @@ -349,7 +356,7 @@ is $req->headers->content_length, undef, 'no "Content-Length" value';
$req->parse("GET / HTTP/1.0\x0d\x0a");
$req->parse("Content-Type: text/plain\x0d\x0a");
ok $req->is_finished, 'request is finished';
is $req->error->{msg}, 'Maximum line size exceeded', 'right error';
is $req->error->{message}, 'Maximum line size exceeded', 'right error';
is $req->error->{advise}, 431, 'right advise';
ok $req->is_limit_exceeded, 'limit is exceeded';
}
Expand All @@ -363,7 +370,7 @@ is $req->headers->content_length, undef, 'no "Content-Length" value';
is $req->max_message_size, 5, 'right size';
$req->parse('GET /foo/bar/baz.html HTTP/1');
ok $req->is_finished, 'request is finished';
is $req->error->{msg}, 'Maximum message size exceeded', 'right error';
is $req->error->{message}, 'Maximum message size exceeded', 'right error';
is $req->error->{advise}, 413, 'right advise';
ok $req->is_limit_exceeded, 'limit is exceeded';
ok $limit, 'limit is exceeded';
Expand All @@ -376,7 +383,7 @@ is $req->headers->content_length, undef, 'no "Content-Length" value';
$req->parse("GET / HTTP/1.0\x0d\x0a");
$req->parse("Content-Type: text/plain\x0d\x0a");
ok $req->is_finished, 'request is finished';
is $req->error->{msg}, 'Maximum message size exceeded', 'right error';
is $req->error->{message}, 'Maximum message size exceeded', 'right error';
is $req->error->{advise}, 413, 'right advise';
ok $req->is_limit_exceeded, 'limit is exceeded';
}
Expand All @@ -390,7 +397,7 @@ is $req->headers->content_length, undef, 'no "Content-Length" value';
$req->parse('Hello World!');
$req->parse('Hello World!');
ok $req->is_finished, 'request is finished';
is $req->error->{msg}, 'Maximum message size exceeded', 'right error';
is $req->error->{message}, 'Maximum message size exceeded', 'right error';
is $req->error->{advise}, 413, 'right advise';
ok $req->is_limit_exceeded, 'limit is exceeded';
}
Expand Down
12 changes: 9 additions & 3 deletions t/mojo/response.t
Expand Up @@ -215,6 +215,12 @@ is $res->body, "Hello World!\n1234\nlalalala\n", 'right content';
is $res->body, "Hello World!\n1234\nlalalala\n", 'right content';
}

# Parse broken start line
$res = Mojo::Message::Response->new;
$res->parse("12345\x0d\x0a");
ok $res->is_finished, 'response is finished';
is $res->error->{message}, 'Bad response start line', 'right error';

# Parse full HTTP 1.0 response (missing Content-Length)
$res = Mojo::Message::Response->new;
$res->parse("HTTP/1.0 500 Internal Server Error\x0d\x0a");
Expand Down Expand Up @@ -339,7 +345,7 @@ is $res->headers->content_length, undef, 'right "Content-Length" value';
$res->parse('a' x 1000);
ok $res->is_finished, 'response is finished';
ok $res->content->is_finished, 'content is finished';
is $res->error->{msg}, 'Maximum buffer size exceeded', 'right error';
is $res->error->{message}, 'Maximum buffer size exceeded', 'right error';
is $res->error->{advise}, 400, 'right advise';
is $res->code, 200, 'right status';
is $res->message, 'OK', 'right message';
Expand All @@ -361,7 +367,7 @@ is $res->headers->content_length, undef, 'right "Content-Length" value';
ok $res->content->is_limit_exceeded, 'limit is exceeded';
ok $res->is_finished, 'response is finished';
ok $res->content->is_finished, 'content is finished';
is $res->error->{msg}, 'Maximum buffer size exceeded', 'right error';
is $res->error->{message}, 'Maximum buffer size exceeded', 'right error';
is $res->error->{advise}, 400, 'right advise';
is $res->code, 200, 'right status';
is $res->message, 'OK', 'right message';
Expand All @@ -385,7 +391,7 @@ is $res->headers->content_length, undef, 'right "Content-Length" value';
ok $res->content->is_limit_exceeded, 'limit is exceeded';
ok $res->is_finished, 'response is finished';
ok $res->content->is_finished, 'content is finished';
is $res->error->{msg}, 'Maximum buffer size exceeded', 'right error';
is $res->error->{message}, 'Maximum buffer size exceeded', 'right error';
is $res->error->{advise}, 400, 'right advise';
is $res->code, 200, 'right status';
is $res->message, 'OK', 'right message';
Expand Down
18 changes: 9 additions & 9 deletions t/mojo/user_agent.t
Expand Up @@ -94,8 +94,8 @@ my $get = my $post = '';
$ua->get('/' => sub { $get = pop->error });
$ua->post('/' => sub { $post = pop->error });
undef $ua;
is $get->{msg}, 'Premature connection close', 'right error';
is $post->{msg}, 'Premature connection close', 'right error';
is $get->{message}, 'Premature connection close', 'right error';
is $post->{message}, 'Premature connection close', 'right error';

# The poll reactor stops when there are no events being watched anymore
my $time = time;
Expand Down Expand Up @@ -266,7 +266,7 @@ $msg = app->log->on(message => sub { $log .= pop });
$tx = $ua->get('/timeout?timeout=0.25');
app->log->unsubscribe(message => $msg);
ok !$tx->success, 'not successful';
is $tx->error->{msg}, 'Premature connection close', 'right error';
is $tx->error->{message}, 'Premature connection close', 'right error';
is $timeout, 1, 'finish event has been emitted';
like $log, qr/Inactivity timeout\./, 'right log message';

Expand All @@ -284,7 +284,7 @@ $ua->once(
);
$tx = $ua->get('/timeout?timeout=5');
ok !$tx->success, 'not successful';
is $tx->error->{msg}, 'Inactivity timeout', 'right error';
is $tx->error->{message}, 'Inactivity timeout', 'right error';

# Keep alive connection times out
my ($fail, $id);
Expand Down Expand Up @@ -313,16 +313,16 @@ $ua->once(
);
$tx = $ua->get('/echo' => 'Hello World!');
ok !$tx->success, 'not successful';
is $tx->error->{msg}, 'Maximum message size exceeded', 'right error';
is $tx->error->{advise}, 413, 'right advise';
is $tx->error->{code}, undef, 'no status';
is $tx->error->{message}, 'Maximum message size exceeded', 'right error';
is $tx->error->{advise}, 413, 'right advise';
is $tx->error->{code}, undef, 'no status';
ok $tx->res->is_limit_exceeded, 'limit is exceeded';

# 404 response
$tx = $ua->get('/does_not_exist');
ok !$tx->success, 'not successful';
is $tx->error->{msg}, 'Not Found', 'right error';
is $tx->error->{code}, 404, 'right status';
is $tx->error->{message}, 'Not Found', 'right error';
is $tx->error->{code}, 404, 'right status';

# Fork safety
$tx = $ua->get('/');
Expand Down

0 comments on commit 3c74b0e

Please sign in to comment.