cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: Patch for 301/302 redirect after post

From: Martin Drasar <drasar_at_optimsys.cz>
Date: Thu, 07 Aug 2008 10:50:09 +0200

Daniel Stenberg napsal(a):
> On Mon, 4 Aug 2008, Martin Drasar wrote:
>
>> Looking back in thread, this is the approach you have suggested before
>> and I am completely ok with that. I don't care how it is done as long
>> as it gets done :-) And with that headerfunction I don't have a reason
>> to rant ;-)
>>
>> Do you want me to write a patch?
>
> Yes please, I'd love that!
>

Ok, here it is...

I don't know if I have renamed the POST301 option correctly, i.e. is
using CINIT with different name but same number what you call renaming?

I have tried to keep the spirit of "non-zero turns it on", but for
obvious reasons, anyone who use 2 as a setting value for CURLOPT_POST301
will not get it working as he/she wanted.

As for the magic names - I was too scared to try to insert them into
some file, so it will probably up to you :-)
My suggestion:
either
0 = 301_GET_302_GET
1 = 301_POST_302_GET
2 = 301_GET_302_POST
3 = 301_POST_302_POST
or
0 = GET_ALL
1 = POST_301
2 = POST_302
3 = POST_ALL
and maybe some prefixes or suffixes ;-)

Martin

-- 
   Martin Drasar, Developer / Analyst
   OptimSys, s.r.o.
   drasar_at_optimsys.cz
   Tel: +420 541 143 065
   Fax: +420 541 143 066
   http://www.optimsys.cz

? patch
Index: include/curl/curl.h
===================================================================
RCS file: /cvsroot/curl/curl/include/curl/curl.h,v
retrieving revision 1.361
diff -u -r1.361 curl.h
--- include/curl/curl.h 7 Aug 2008 00:29:08 -0000 1.361
+++ include/curl/curl.h 7 Aug 2008 08:36:37 -0000
@@ -1123,6 +1123,10 @@
   /* Obey RFC 2616/10.3.2 and keep POSTs as POSTs after a 301 */
   CINIT(POST301, LONG, 161),
 
+ /* Set the behaviour of POST when redirecting. Alias for POST301 that is kept
+ for compatibility reasons */
+ CINIT(POSTREDIR, LONG, 161),
+
   /* used by scp/sftp to verify the host's public key */
   CINIT(SSH_HOST_PUBLIC_KEY_MD5, OBJECTPOINT, 162),
 
Index: lib/transfer.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/transfer.c,v
retrieving revision 1.399
diff -u -r1.399 transfer.c
--- lib/transfer.c 4 Aug 2008 22:00:22 -0000 1.399
+++ lib/transfer.c 7 Aug 2008 08:36:37 -0000
@@ -2192,7 +2192,8 @@
      * libcurl gets the page that most user agents would get, libcurl has to
      * force GET.
      *
- * This behaviour can be overriden with CURLOPT_POST301.
+ * This behaviour can be overriden with CURLOPT_POST301 or
+ * CURLOPT_POSTREDIR
      */
     if( (data->set.httpreq == HTTPREQ_POST
          || data->set.httpreq == HTTPREQ_POST_FORM)
@@ -2219,7 +2220,18 @@
     status. When interoperability with such clients is a concern, the
     302 status code may be used instead, since most user agents react
     to a 302 response as described here for 303.
+
+ This behaviour can be overriden with CURLOPT_POSTREDIR
     */
+ if( (data->set.httpreq == HTTPREQ_POST
+ || data->set.httpreq == HTTPREQ_POST_FORM)
+ && !data->set.post302) {
+ infof(data,
+ "Violate RFC 2616/10.3.3 and switch from POST to GET\n");
+ data->set.httpreq = HTTPREQ_GET;
+ }
+ break;
+
   case 303: /* See Other */
     /* Disable both types of POSTs, since doing a second POST when
      * following isn't what anyone would want! */
Index: lib/url.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/url.c,v
retrieving revision 1.726
diff -u -r1.726 url.c
--- lib/url.c 1 Aug 2008 02:09:08 -0000 1.726
+++ lib/url.c 7 Aug 2008 08:36:37 -0000
@@ -1021,11 +1021,19 @@
     data->set.maxredirs = va_arg(param, long);
     break;
 
- case CURLOPT_POST301:
+ case CURLOPT_POSTREDIR:
     /*
- * Obey RFC 2616/10.3.2 and resubmit a POST as a POST after a 301.
- */
- data->set.post301 = (bool)(0 != va_arg(param, long));
+ * Set the behaviour of POST when redirecting
+ * 0 - POST is changed to GET after 301 and 302
+ * 1 - POST is kept as POST after 301
+ * 2 - POST is kept as POST after 302
+ * 3 - POST is kept as POST after 301 and 302
+ * other - POST is kept as POST after 301 and 302
+ */
+ data->set.post301 = (0 != va_arg(param, long)) &&
+ (2 != va_arg(param, long));
+ data->set.post302 = (0 != va_arg(param, long)) &&
+ (1 != va_arg(param, long));
     break;
 
   case CURLOPT_POST:
Index: lib/urldata.h
===================================================================
RCS file: /cvsroot/curl/curl/lib/urldata.h,v
retrieving revision 1.384
diff -u -r1.384 urldata.h
--- lib/urldata.h 30 Jul 2008 21:55:27 -0000 1.384
+++ lib/urldata.h 7 Aug 2008 08:36:37 -0000
@@ -1348,6 +1348,7 @@
                         for infinity */
   bool post301; /* Obey RFC 2616/10.3.2 and keep POSTs as POSTs after a
                         301 */
+ bool post302; /* keep POSTs as POSTs after a 302 */
   bool free_referer; /* set TRUE if 'referer' points to a string we
                         allocated */
   void *postfields; /* if POST, set the fields' values here */
Received on 2008-08-07