curl-library
POST+30x=GET?
Date: Mon, 15 Apr 2002 00:58:55 +0200
Hallo,
being non RFC conform to be browser conform?
While doing a login transaction with my libcurl application I noticed
that libcurl does a post after getting a 301 from a previous post request.
Looking into http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.2:
| Note: When automatically redirecting a POST request after
| receiving a 301 status code, some existing HTTP/1.0 user agents
| will erroneously change it into a GET request.
Hmm, libcurl is right...but most browsers do a get after a 301 to follow Location,
see anonymized extract from by squid log:
Mozilla 0.9.9
TCP_MISS/301 648 POST http://.../login_check - DIRECT/... text/html
TCP_MISS/301 353 GET http://.../cookie_check/1,9144,,00.html? - DIRECT/64.39.40.14
Konqueror 3.0
TCP_MISS/301 648 POST http://.../login_check - DIRECT/... text/html
TCP_MISS/301 353 GET http://.../cookie_check/1,9144,,00.html? - DIRECT/64.39.40.14 text/html
NS 4.79
TCP_MISS/301 648 POST http://.../login_check - DIRECT/... text/html
TCP_MISS/301 353 GET http://.../cookie_check/1,9144,,00.html? - DIRECT/... text/html
Opera 6.0beta1
TCP_MISS/301 648 POST http://.../login_check - DIRECT/... text/html
TCP_MISS/404 455 POST http://.../cookie_check/1,9144,,00.html? - DIRECT/...
Links 0.96
TCP_MISS/301 743 POST http://.../login_check - DIRECT/... text/html
TCP_MISS/404 450 POST http://.../cookie_check/1,9144,,00.html? - DIRECT/... text/html
w3m 0.2.4
TCP_MISS/301 643 POST http://.../login_check - DIRECT/... text/html
TCP_MISS/301 348 GET http://.../cookie_check/1,9144,,00.html? - DIRECT/... text/html
Summarize: Mozilla,Konqueror,NS4, and w3m do a get
Opera6 and Links do a post.
2:1 get/post
When doing post login will fail (webserver answers 404).
So I have done this provisionally patch againt 7.9.5:
--- snip (hand made diff)
/* TBD: set the URL with curl_setopt() */
data->change.url = newurl;
newurl = NULL; /* don't free! */
infof(data, "Follows Location: to new URL: '%s'\n", data->change.url);
+ if(data->set.httpreq==HTTPREQ_POST || data->set.httpreq==HTTPREQ_POST_FORM){
+ infof(data, "Follows Location: switch from post to get\n");
+ data->set.httpreq=HTTPREQ_GET;
+ }
/*
* We get here when the HTTP code is 300-399. We need to perform
* differently based on exactly what return code there was.
--- snip
With these changes login wrongs with libcurl.
But is this the right way?
May be it is better to switch to get only when the location url contains a '?':
--- snip (hande made diff)
/* TBD: set the URL with curl_setopt() */
data->change.url = newurl;
newurl = NULL; /* don't free! */
+ infof(data, "Follows Location: to new URL: '%s'\n", data->change.url);
+ if((data->set.httpreq==HTTPREQ_POST || data->set.httpreq==HTTPREQ_POST_FORM)
+ && strchr(data->change.url,'?') ){
+ infof(data, "Follows Location: switch from post to get\n");
+ data->set.httpreq=HTTPREQ_GET;
+ }
+
/*
* We get here when the HTTP code is 300-399. We need to perform
* differently based on exactly what return code there was.
--- snip
[Warning: these patches are not well tested.]
Comments?
Live long a prosper,
Dirk Manske
Received on 2002-04-15