Sorry no one answered this yet. I used to try to keep a closer eye on stack overflow but I got lazy :-P. This is a very interesting question.
Standard redirects (301/302) use the same verb as the original request UNLESS the original request was a POST
Interestingly, this behavior was not really intended. A redirect is supposed to use the same request method as the original, but the POST
->GET
redirect is so commonly intended that most browsers added this behavior even though it was against the original definition. However some people really wanted a POST
to remain a POST
and now it depended on the implementation. In fact this got so bad that HTTP added response statuses 307/308 which always redirects as the same http verb (ie POST
-> POST
), even thought that was already the official behavior of the old ones but that ship had sailed. This means that POST
->GET
, but DELETE
->DELETE
is the defacto behavior of the 301/302.
This can be demonstrated in the following one liner ($_
in these one-liners is the controller):
perl -Mojo -E 'del "/delete" => sub { $_->redirect_to("/") }; any "/" => { inline => q[I got a <%= $c->req->method %>] }; app->start' get -r -v -M DELETE /delete
DELETE /delete HTTP/1.1
Host: 127.0.0.1:62690
Accept-Encoding: gzip
User-Agent: Mojolicious (Perl)
Content-Length: 0
HTTP/1.1 302 Found
Date: Sun, 18 Sep 2016 03:25:58 GMT
Server: Mojolicious (Perl)
Location: /
Content-Length: 0
DELETE / HTTP/1.1
Content-Length: 0
User-Agent: Mojolicious (Perl)
Host: 127.0.0.1:62690
Accept-Encoding: gzip
HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
Content-Length: 5
Date: Sun, 18 Sep 2016 03:25:58 GMT
Server: Mojolicious (Perl)
I got a DELETE
You can see that since my /
route handles all methods we get a response, however the request was a DELETE
. I see that in your app, you redirect to another named route whose url also handles DELETE
. This is a source of your confusion as you are actually ending up there in your tests. Your redirect is effectively DELETE /backups/<<id>>
-> DELETE /backups
, if I'm reading your code correctly.
Now as opposed to the people who wanted to keep POST
as POST
, what you want here is the opposite, you want to redirect from DELETE
to GET
because you are trying to show a response that is not the original resource. This is the defined behavior of the little-known 303 response in which any request method is redirected to a GET
. Indeed this is what early browsers should have insisted on rather than breaking the 302.
In the following example I modify the response code to 303 explicitly.
$ perl -Mojo -E 'del "/delete" => sub { $_->res->code(303); $_->redirect_to("/") }; any "/" => { inline => q[I got a <%= $c->req->method %>] }; app->start' get -r -v -M DELETE /delete
DELETE /delete HTTP/1.1
User-Agent: Mojolicious (Perl)
Host: 127.0.0.1:62716
Accept-Encoding: gzip
Content-Length: 0
HTTP/1.1 303 See Other
Location: /
Content-Length: 0
Server: Mojolicious (Perl)
Date: Sun, 18 Sep 2016 03:27:19 GMT
DELETE / HTTP/1.1
User-Agent: Mojolicious (Perl)
Accept-Encoding: gzip
Content-Length: 0
Host: 127.0.0.1:62716
HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
Server: Mojolicious (Perl)
Content-Length: 5
Date: Sun, 18 Sep 2016 03:27:19 GMT
I got a DELETE
But whoops, that's still a DELETE
! That's because there was a bug in Mojo::UserAgent so that it didn't handle 303s correctly. I'd suggest you still make the change to your code since browsers seem to handle 303s correctly. However since Mojo::UserAgent powers Test::Mojo, your tests can't test that behavior yet. Once fixed you will see it work correctly, as my example does in my local branch:
$ perl -Ilib -Mojo -E 'del "/delete" => sub { $_->res->code(303); $_->redirect_to("/") }; any "/" => { inline => q[I got a <%= $c->req->method %>] }; app->start' get -r -v -M DELETE /delete
DELETE /delete HTTP/1.1
Content-Length: 0
User-Agent: Mojolicious (Perl)
Host: 127.0.0.1:64924
Accept-Encoding: gzip
HTTP/1.1 303 See Other
Date: Sun, 18 Sep 2016 04:59:37 GMT
Location: /
Server: Mojolicious (Perl)
Content-Length: 0
GET / HTTP/1.1
Content-Length: 0
User-Agent: Mojolicious (Perl)
Host: 127.0.0.1:64924
Accept-Encoding: gzip
HTTP/1.1 200 OK
Date: Sun, 18 Sep 2016 04:59:37 GMT
Content-Type: text/html;charset=UTF-8
Server: Mojolicious (Perl)
Content-Length: 12
I got a GET
To see more about redirect response types see https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#3xx_Redirection
response to http://stackoverflow.com/q/38054279/468327