[dw-free] Need a way to cleanly call controllers from tests
[commit: http://hg.dwscoalition.org/dw-free/rev/37f7a2c8953c]
http://bugs.dwscoalition.org/show_bug.cgi?id=3547
Limit the methods that are supported by controllers to GET/POST/HEAD.
Controllers can override to allow other methods.
Patch by
exor674.
Files modified:
http://bugs.dwscoalition.org/show_bug.cgi?id=3547
Limit the methods that are supported by controllers to GET/POST/HEAD.
Controllers can override to allow other methods.
Patch by
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Files modified:
- cgi-bin/DW/Controller/Interface/S2.pm
- cgi-bin/DW/Request/Standard.pm
- cgi-bin/DW/Routing.pm
- cgi-bin/DW/Routing/CallInfo.pm
- t/routing.t
-------------------------------------------------------------------------------- diff -r b7d1369e7005 -r 37f7a2c8953c cgi-bin/DW/Controller/Interface/S2.pm --- a/cgi-bin/DW/Controller/Interface/S2.pm Mon Feb 28 16:33:50 2011 +0800 +++ b/cgi-bin/DW/Controller/Interface/S2.pm Mon Feb 28 18:44:54 2011 +0800 @@ -21,7 +21,7 @@ use DW::Routing; use DW::Routing; # handle, even with no id, so that we can present an informative error message -DW::Routing->register_regex( '^/interface/s2(?:/(\d+)?)?$', \&interface_handler, app => 1, format => 'plain' ); +DW::Routing->register_regex( '^/interface/s2(?:/(\d+)?)?$', \&interface_handler, app => 1, format => 'plain', methods => { GET => 1, PUT => 1 } ); # handles menu nav pages sub interface_handler { @@ -101,10 +101,6 @@ sub interface_handler { return $r->OK; } - } else { - # Return 'method not allowed' so that we can add methods in future - # and clients will get a sensible error from old servers. - return error( $r, $r->HTTP_METHOD_NOT_ALLOWED, 'Method Not Allowed', 'Only GET and PUT are supported for this resource' ); } } diff -r b7d1369e7005 -r 37f7a2c8953c cgi-bin/DW/Request/Standard.pm --- a/cgi-bin/DW/Request/Standard.pm Mon Feb 28 16:33:50 2011 +0800 +++ b/cgi-bin/DW/Request/Standard.pm Mon Feb 28 18:44:54 2011 +0800 @@ -291,10 +291,14 @@ sub OK { return 200; } sub OK { return 200; } sub HTTP_CREATED { return 201; } sub REDIRECT { return 302; } +sub NOT_FOUND { return 404; } +sub SERVER_ERROR { return 500; } +sub HTTP_UNAUTHORIZED { return 401; } sub HTTP_BAD_REQUEST { return 400; } -sub HTTP_UNAUTHORIZED { return 403; } -sub NOT_FOUND { return 404; } +sub HTTP_UNSUPPORTED_MEDIA_TYPE { return 415; } sub HTTP_SERVER_ERROR { return 500; } +sub HTTP_METHOD_NOT_ALLOWED { return 405; } +sub FORBIDDEN { return 403; } # spawn a process for an external program sub spawn { diff -r b7d1369e7005 -r 37f7a2c8953c cgi-bin/DW/Routing.pm --- a/cgi-bin/DW/Routing.pm Mon Feb 28 16:33:50 2011 +0800 +++ b/cgi-bin/DW/Routing.pm Mon Feb 28 18:44:54 2011 +0800 @@ -157,6 +157,10 @@ sub _call_hash { my $opts = $r->pnote('routing_opts'); $opts->prepare_for_call; + + # check method + my $method = uc( $r->method ); + return $r->HTTP_METHOD_NOT_ALLOWED unless $opts->method_valid( $method ); my $format = $opts->format; # check for format validity @@ -370,7 +374,7 @@ sub _apply_defaults { sub _apply_defaults { my ( $opts, $hash ) = @_; - $hash ||= 0; + $hash ||= {}; $opts->{app} = 1 if ! defined $opts->{app} && !$opts->{user}; $hash->{args} = $opts->{args}; $hash->{ssl} = $opts->{ssl} || 0; @@ -382,6 +386,7 @@ sub _apply_defaults { $formats = { map { ( $_, 1 ) } @$formats } if ( ref($formats) eq 'ARRAY' ); $hash->{formats} = $formats; + $hash->{methods} = $opts->{methods} || { GET => 1, POST => 1, HEAD => 1 }; return $hash; } diff -r b7d1369e7005 -r 37f7a2c8953c cgi-bin/DW/Routing/CallInfo.pm --- a/cgi-bin/DW/Routing/CallInfo.pm Mon Feb 28 16:33:50 2011 +0800 +++ b/cgi-bin/DW/Routing/CallInfo.pm Mon Feb 28 18:44:54 2011 +0800 @@ -114,6 +114,18 @@ sub format_valid { return $formats->{$_[0]->format} || 0; } +=head2 C<< $self->method_valid( $method ) >> + +Returns if the method is valid for the callinfo + +=cut + +sub method_valid { + my $methods = $_[0]->{__hash}->{methods}; + return 1 if $methods == 1; + return $methods->{$_[1]} || 0; +} + =head2 C<< $self->role >> Current mode: 'app' or 'user' or 'ssl' diff -r b7d1369e7005 -r 37f7a2c8953c t/routing.t --- a/t/routing.t Mon Feb 28 16:33:50 2011 +0800 +++ b/t/routing.t Mon Feb 28 18:44:54 2011 +0800 @@ -14,7 +14,7 @@ # 'perldoc perlartistic' or 'perldoc perlgpl'. # use strict; -use Test::More tests => 203; +use Test::More tests => 238; use lib "$ENV{LJHOME}/cgi-bin"; # don't let DW::Routing load DW::Controller subclasses @@ -251,7 +251,6 @@ handle_redirect( '/xx3', '/xx3/' ); handle_redirect( '/xx3', '/xx3/' ); # 194 - # test dying DW::Routing->register_string( "/test/die/all_format", \&died_handler, app => 1, formats => 1 ); @@ -259,6 +258,32 @@ handle_server_error( "/test die .json fo handle_server_error( "/test die .json format (app)", "/test/die/all_format.json", "json" ); # 2 tests handle_server_error( "/test die .html format (app)", "/test/die/all_format.html", "html" ); # 2 tests handle_server_error( "/test die .blah format (app)", "/test/die/all_format.blah", "blah" ); # 2 tests +# 203 ( I know this doesn't add up. ) + +DW::Routing->register_string( "/test/method/normal", \&handler, app => 1 ); + +handle_request( "Method GET - okay", "/test/method/normal", 1, undef, method => 'GET' ); # 3 tests +handle_request( "Method POST - okay", "/test/method/normal", 1, undef, method => 'POST' ); +handle_request( "Method HEAD - okay", "/test/method/normal", 1, undef, method => 'HEAD' ); +handle_request( "Method PUT - !ok", "/test/method/normal", 1, undef, method => 'PUT', expected_error => 405 ); # 1 test +# 213 + +DW::Routing->register_string( "/test/method/all", \&handler, app => 1, methods => 1 ); + +handle_request( "Method GET - okay", "/test/method/all", 1, undef, method => 'GET' ); # 3 tests +handle_request( "Method POST - okay", "/test/method/all", 1, undef, method => 'POST' ); +handle_request( "Method HEAD - okay", "/test/method/all", 1, undef, method => 'HEAD' ); +handle_request( "Method PUT - okay", "/test/method/all", 1, undef, method => 'PUT' ); +handle_request( "Method FOO - okay", "/test/method/all", 1, undef, method => 'FOO' ); +# 228 + +DW::Routing->register_string( "/test/method/no_post", \&handler, app => 1, methods => { GET => 1, HEAD => 1, PUT => 1 } ); + +handle_request( "Method GET - okay", "/test/method/no_post", 1, undef, method => 'GET' ); # 3 tests +handle_request( "Method POST - !ok", "/test/method/no_post", 1, undef, method => 'POST', expected_error => 405 ); # 1 test +handle_request( "Method HEAD - okay", "/test/method/no_post", 1, undef, method => 'HEAD' ); # 3 tests +handle_request( "Method PUT - okay", "/test/method/no_post", 1, undef, method => 'PUT' ); # 3 test +# 238 sub handle_redirect { @@ -286,7 +311,9 @@ sub handle_request { $DW::Request::determined = 0; $DW::Request::cur_req = undef; - my $req = HTTP::Request->new(GET=>"$uri"); + my $method = $opts{method} || 'GET'; + + my $req = HTTP::Request->new($method=>"$uri"); my $r = DW::Request::Standard->new($req); $result = undef; --------------------------------------------------------------------------------