cURL / Mailing Lists / curl-library / Single Mail

curl-library

Patch for 301/302 redirect after post

From: Martin Drasar <drasar_at_optimsys.cz>
Date: Mon, 14 Jul 2008 17:11:32 +0200

Hi curl devs,
I have created a patch that lets user to chose a way to handle redirect
after 301 or 302.
CURLOPT_POST301 is changed from bool to long
CURLOPT_POST302 (long) is added
These two options set the behavior in such way:
-1: error is reported after post followed by 301/302
  0: post is resent
  1: post is changed to get

This is my first patch and I am pretty new to curl bowels, that's why I
decided not to name the values for those two options - I don't know
where to put them and how to name them ;o)

I hope the patch doesn't screw something else up :o)

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

Index: include/curl/curl.h
===================================================================
RCS file: /cvsroot/curl/curl/include/curl/curl.h,v
retrieving revision 1.359
diff -u -r1.359 curl.h
--- include/curl/curl.h 3 Jul 2008 06:56:03 -0000 1.359
+++ include/curl/curl.h 14 Jul 2008 14:55:41 -0000
@@ -1211,6 +1211,9 @@
   /* Issuer certificate */
   CINIT(ISSUERCERT, OBJECTPOINT, 170),
 
+ /* Added option for CURLOPT_POST302 */
+ CINIT(POST302, LONG, 171),
+
   CURLOPT_LASTENTRY /* the last unused */
 } CURLoption;
 
Index: lib/transfer.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/transfer.c,v
retrieving revision 1.395
diff -u -r1.395 transfer.c
--- lib/transfer.c 10 Jul 2008 18:15:22 -0000 1.395
+++ lib/transfer.c 14 Jul 2008 14:54:22 -0000
@@ -2223,11 +2223,27 @@
      * This behaviour can be overriden with CURLOPT_POST301.
      */
     if( (data->set.httpreq == HTTPREQ_POST
- || data->set.httpreq == HTTPREQ_POST_FORM)
- && !data->set.post301) {
- infof(data,
+ || data->set.httpreq == HTTPREQ_POST_FORM))
+ {
+ switch (data->set.post301)
+ {
+ case -1:
+ {
+ data->state.errorbuf = TRUE;
+ failf(data, "re-POSTing disabled for 301 redirect");
+ return CURLE_HTTP_POST_ERROR;
+ }
+ break;
+ case 0:
+ break;
+ case 1:
+ {
+ infof(data,
             "Violate RFC 2616/10.3.2 and switch from POST to GET\n");
- data->set.httpreq = HTTPREQ_GET;
+ data->set.httpreq = HTTPREQ_GET;
+ }
+ break;
+ }
     }
     break;
   case 302: /* Found */
@@ -2248,6 +2264,30 @@
     302 status code may be used instead, since most user agents react
     to a 302 response as described here for 303.
     */
+ if( (data->set.httpreq == HTTPREQ_POST
+ || data->set.httpreq == HTTPREQ_POST_FORM))
+ {
+ switch (data->set.post302)
+ {
+ case -1:
+ {
+ data->state.errorbuf = TRUE;
+ failf(data, "re-POSTing disabled for 302 redirect");
+ return CURLE_HTTP_POST_ERROR;
+ }
+ break;
+ case 0:
+ break;
+ case 1:
+ {
+ infof(data,
+ "Violate RFC 2616/10.3.2 and switch from POST to GET\n");
+ data->set.httpreq = HTTPREQ_GET;
+ }
+ break;
+ }
+ }
+ break;
   case 303: /* See Other */
     /* Disable both types of POSTs, since doing a second POST when
      * following isn't what anyone would want! */
@@ -2461,6 +2501,12 @@
           }
           /* else we break out of the loop below */
         }
+ else if (CURLE_HTTP_POST_ERROR == res)
+ {
+ newurl = NULL;
+ follow = FOLLOW_NONE;
+ break;
+ }
       }
     }
     break; /* it only reaches here when this shouldn't loop */
Index: lib/url.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/url.c,v
retrieving revision 1.720
diff -u -r1.720 url.c
--- lib/url.c 11 Jul 2008 09:18:30 -0000 1.720
+++ lib/url.c 14 Jul 2008 14:51:07 -0000
@@ -1023,9 +1023,16 @@
 
   case CURLOPT_POST301:
     /*
- * Obey RFC 2616/10.3.2 and resubmit a POST as a POST after a 301.
+ * Set the behavior of post when 301 redirect appears
      */
- data->set.post301 = (bool)(0 != va_arg(param, long));
+ data->set.post301 = va_arg(param, long);
+ break;
+
+ case CURLOPT_POST302:
+ /*
+ * Set the behavior of post when 302 redirect appears
+ */
+ data->set.post302 = va_arg(param, long);
     break;
 
   case CURLOPT_POST:
Index: lib/urldata.h
===================================================================
RCS file: /cvsroot/curl/curl/lib/urldata.h,v
retrieving revision 1.382
diff -u -r1.382 urldata.h
--- lib/urldata.h 3 Jul 2008 06:56:04 -0000 1.382
+++ lib/urldata.h 14 Jul 2008 14:50:17 -0000
@@ -1343,8 +1343,12 @@
   long followlocation; /* as in HTTP Location: */
   long maxredirs; /* maximum no. of http(s) redirects to follow, set to -1
                         for infinity */
- bool post301; /* Obey RFC 2616/10.3.2 and keep POSTs as POSTs after a
- 301 */
+ /* both post301 and post302 have three possible values.
+ -1: POST followed by 301/2 is not finished and error is reported
+ 0: POST is kept as it is
+ 1: POST is changed to GET */
+ int post301;
+ int post302;
   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-07-14