]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
urlapi: handle "redirects" smarter
authorStefan Eissing <stefan.eissing@greenbytes.de>
Mon, 14 Feb 2022 10:43:04 +0000 (11:43 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 14 Feb 2022 16:56:58 +0000 (17:56 +0100)
  - avoid one malloc when setting a new url via curl_url_set()
    and CURLUPART_URL.
  - extract common pattern into a new static function.

Closes #8450

lib/urlapi.c

index ebbc37f28269364a991029eda36a09b8c84d3e6a..ff00ee424364ad1b64f689b7ea54c1c01f4674a5 100644 (file)
@@ -90,16 +90,6 @@ static void free_urlhandle(struct Curl_URL *u)
   free(u->temppath);
 }
 
-/* move the full contents of one handle onto another and
-   free the original */
-static void mv_urlhandle(struct Curl_URL *from,
-                         struct Curl_URL *to)
-{
-  free_urlhandle(to);
-  *to = *from;
-  free(from);
-}
-
 /*
  * Find the separator at the end of the host name, or the '?' in cases like
  * http://www.url.com?id=2380
@@ -1153,6 +1143,25 @@ static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags)
   return result;
 }
 
+/*
+ * Parse the URL and, if successful, replace everyting in the Curl_URL struct.
+ */
+static CURLUcode parseurl_and_replace(const char *url, CURLU *u,
+                                      unsigned int flags)
+{
+  CURLUcode result;
+  CURLU tmpurl;
+  memset(&tmpurl, 0, sizeof(tmpurl));
+  result = parseurl(url, &tmpurl, flags);
+  if(!result) {
+    free_urlhandle(u);
+    *u = tmpurl;
+  }
+  else
+    free_urlhandle(&tmpurl);
+  return result;
+}
+
 /*
  */
 CURLU *curl_url(void)
@@ -1560,52 +1569,24 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
     CURLUcode result;
     char *oldurl;
     char *redired_url;
-    CURLU *handle2;
 
-    if(Curl_is_absolute_url(part, NULL, 0)) {
-      handle2 = curl_url();
-      if(!handle2)
-        return CURLUE_OUT_OF_MEMORY;
-      result = parseurl(part, handle2, flags);
-      if(!result)
-        mv_urlhandle(handle2, u);
-      else
-        curl_url_cleanup(handle2);
-      return result;
-    }
-    /* extract the full "old" URL to do the redirect on */
-    result = curl_url_get(u, CURLUPART_URL, &oldurl, flags);
-    if(result) {
-      /* couldn't get the old URL, just use the new! */
-      handle2 = curl_url();
-      if(!handle2)
-        return CURLUE_OUT_OF_MEMORY;
-      result = parseurl(part, handle2, flags);
-      if(!result)
-        mv_urlhandle(handle2, u);
-      else
-        curl_url_cleanup(handle2);
-      return result;
+    /* if the new thing is absolute or the old one is not
+     * (we could not get an absolute url in 'oldurl'),
+     * then replace the existing with the new. */
+    if(Curl_is_absolute_url(part, NULL, 0)
+       || curl_url_get(u, CURLUPART_URL, &oldurl, flags)) {
+      return parseurl_and_replace(part, u, flags);
     }
 
-    /* apply the relative part to create a new URL */
+    /* apply the relative part to create a new URL
+     * and replace the existing one with it. */
     redired_url = concat_url(oldurl, part);
     free(oldurl);
     if(!redired_url)
       return CURLUE_OUT_OF_MEMORY;
 
-    /* now parse the new URL */
-    handle2 = curl_url();
-    if(!handle2) {
-      free(redired_url);
-      return CURLUE_OUT_OF_MEMORY;
-    }
-    result = parseurl(redired_url, handle2, flags);
+    result = parseurl_and_replace(redired_url, u, flags);
     free(redired_url);
-    if(!result)
-      mv_urlhandle(handle2, u);
-    else
-      curl_url_cleanup(handle2);
     return result;
   }
   default: