? base64
? rfc1186.html
? curl-whitespace-redir.patch
Index: transfer.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/transfer.c,v
retrieving revision 1.162
diff -u -r1.162 transfer.c
--- transfer.c	12 Jun 2003 23:03:09 -0000	1.162
+++ transfer.c	17 Jun 2003 00:01:18 -0000
@@ -368,6 +368,7 @@
             k->hbufp += full_length;
             k->hbuflen += full_length;
             *k->hbufp = 0;
+            k->end_ptr = k->hbufp;
               
             k->p = data->state.headerbuff;
               
@@ -786,11 +787,17 @@
                    white spaces after the "Location:" keyword. */
                 while(*start && isspace((int)*start ))
                   start++;
-                ptr = start; /* start scanning here */
+                
+                /* Scan through the string from the end to find the last
+                   non-space. k->end_ptr points to the actual terminating zero
+                   letter, move pointer one letter back and start from
+                   there. This logic strips off trailing whitespace, but keeps
+                   any embedded whitespace. */
+                ptr = k->end_ptr-1;
+                while((ptr>=start) && isspace((int)*ptr))
+                  ptr--;
+                ptr++;
 
-                /* scan through the string to find the end */
-                while(*ptr && !isspace((int)*ptr))
-                  ptr++;
                 backup = *ptr; /* store the ending letter */
                 if(ptr != start) {
                   *ptr = '\0';   /* zero terminate */
@@ -1535,6 +1542,9 @@
     char *newest;
 
     char *useurl = newurl;
+    int newlen=0;
+    int urllen;
+    bool whitespace=FALSE;
 
     /* we must make our own copy of the URL to play with, as it may
        point to read-only data */
@@ -1607,16 +1617,84 @@
         *pathsep=0;
     }
 
-    newest=(char *)malloc( strlen(url_clone) +
-                           1 + /* possible slash */
-                           strlen(useurl) + 1/* zero byte */);
+    if(strchr(useurl, ' ')) {
+      /* If the new part contains a space, this is a mighty stupid redirect
+         but we still make an effort to do "right". To the left of a '?'
+         letter we replace each space with %20 while it is replaced with '+'
+         on the right side of the '?' letter.
+      */
+      bool left=TRUE; /* left side of the ? */
+      char *ptr = useurl;
+      whitespace=TRUE;
+      while(*ptr) {
+        switch(*ptr) {
+        case '?':
+          left=FALSE;
+        default:
+          newlen++;
+          break;
+        case ' ':
+          if(left)
+            newlen+=3;
+          else
+            newlen++;
+          break;
+        }
+        ptr++;
+      }
+    }
+    else
+      newlen = strlen(useurl);
+
+    urllen = strlen(url_clone);
+    
+    newest=(char *)malloc( urllen + 1 + /* possible slash */
+                           newlen + 1 /* zero byte */);
     
     if(!newest)
       return CURLE_OUT_OF_MEMORY; /* go out from this */
 
-    sprintf(newest, "%s%s%s", url_clone,
-            (('/' == useurl[0]) || (protsep && !*protsep))?"":"/",
-            useurl);
+    /* copy over the root url part */
+    memcpy(newest, url_clone, urllen);
+
+    /* check if we need to append a slash */
+    if(('/' == useurl[0]) || (protsep && !*protsep))
+      ;
+    else
+      newest[urllen++]='/';
+
+    /* then append the new piece on the right */
+    if(whitespace) {
+      /* we must add this with whitespace-replacing */
+      bool left=TRUE;
+      char *iptr;
+      char *optr = &newest[urllen]; /* start writing here */
+      for(iptr = useurl; /* read from here */
+          *iptr;         /* until zero byte */
+          iptr++) {
+        switch(*iptr) {
+        case '?':
+          left=FALSE;
+        default:
+          *optr++=*iptr;
+          break;
+        case ' ':
+          if(left) {
+            *optr++='%'; /* add a '%' */
+            *optr++='2'; /* add a '2' */
+            *optr++='0'; /* add a '0' */
+          }
+          else
+            *optr++='+'; /* add a '+' here */
+          break;
+        }
+      }
+      *optr=0; /* zero terminate output buffer */
+    }
+    else
+      /* we know this fits */
+      strcpy(&newest[urllen], useurl);
+
     free(newurl); /* newurl is the allocated pointer */
     free(url_clone);
     newurl = newest;
