You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2020/05/26 07:38:22 UTC

[incubator-nuttx-apps] branch master updated: webclient: Fix http -> https redirection

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx-apps.git


The following commit(s) were added to refs/heads/master by this push:
     new 276bf42  webclient: Fix http -> https redirection
276bf42 is described below

commit 276bf42e0d441c4ffba1ac70dd243a90e9900999
Author: YAMAMOTO Takashi <ya...@midokura.com>
AuthorDate: Mon May 25 23:22:55 2020 +0900

    webclient: Fix http -> https redirection
    
    http -> https redirection is rather common. The old code was
    just broken in that case.
    
    Also, this commit is a step towards https support.
    
    * Switch to netlib_parseurl
    * Fix error propagation in wget_parseheaders
    * Bail out on a redirect to a URL with unsupported scheme
---
 netutils/webclient/Kconfig     |  1 +
 netutils/webclient/webclient.c | 65 ++++++++++++++++++++++++++++++++----------
 2 files changed, 51 insertions(+), 15 deletions(-)

diff --git a/netutils/webclient/Kconfig b/netutils/webclient/Kconfig
index d898495..dfb87f3 100644
--- a/netutils/webclient/Kconfig
+++ b/netutils/webclient/Kconfig
@@ -9,6 +9,7 @@ config NETUTILS_WEBCLIENT
 	depends on NET_TCP
 	select LIBC_NETDB
 	select NET_SOCKOPTS
+	select NETUTILS_NETLIB_GENERICURLPARSER
 	---help---
 		Enable support for the uIP web client.
 
diff --git a/netutils/webclient/webclient.c b/netutils/webclient/webclient.c
index a2aa492..a26ac6e 100644
--- a/netutils/webclient/webclient.c
+++ b/netutils/webclient/webclient.c
@@ -153,6 +153,7 @@ struct wget_s
 #ifdef CONFIG_WEBCLIENT_GETMIMETYPE
   char mimetype[CONFIG_WEBCLIENT_MAXMIMESIZE];
 #endif
+  char scheme[sizeof("https") + 1];
   char hostname[CONFIG_WEBCLIENT_MAXHOSTNAME];
   char filename[CONFIG_WEBCLIENT_MAXFILENAME];
 };
@@ -291,6 +292,40 @@ static inline int wget_parsestatus(struct wget_s *ws)
 }
 
 /****************************************************************************
+ * Name: parseurl
+ ****************************************************************************/
+
+static int parseurl(FAR const char *url, FAR struct wget_s *ws)
+{
+  struct url_s url_s;
+  int ret;
+
+  memset(&url_s, 0, sizeof(url_s));
+  url_s.scheme = ws->scheme;
+  url_s.schemelen = sizeof(ws->scheme);
+  url_s.host = ws->hostname;
+  url_s.hostlen = sizeof(ws->hostname);
+  url_s.path = ws->filename;
+  url_s.pathlen = sizeof(ws->filename);
+  ret = netlib_parseurl(url, &url_s);
+  if (ret == -1)
+    {
+      return ret;
+    }
+
+  if (url_s.port == 0)
+    {
+      ws->port = 80;
+    }
+  else
+    {
+      ws->port = url_s.port;
+    }
+
+  return 0;
+}
+
+/****************************************************************************
  * Name: wget_parseheaders
  ****************************************************************************/
 
@@ -298,6 +333,7 @@ static inline int wget_parseheaders(struct wget_s *ws)
 {
   int offset;
   int ndx;
+  int ret = OK;
 
   offset = ws->offset;
   ndx    = ws->ndx;
@@ -350,17 +386,12 @@ static inline int wget_parseheaders(struct wget_s *ws)
               if (strncasecmp(ws->line, g_httplocation,
                               strlen(g_httplocation)) == 0)
                 {
-                  /* Parse the new HTTP host and filename from the URL.
-                   * Note that the return value is ignored. In the event
-                   * of failure, we retain the current location.
+                  /* Parse the new host and filename from the URL.
                    */
 
-                  netlib_parsehttpurl(ws->line + strlen(g_httplocation),
-                                      &ws->port,
-                                      ws->hostname,
-                                      CONFIG_WEBCLIENT_MAXHOSTNAME,
-                                      ws->filename,
-                                      CONFIG_WEBCLIENT_MAXFILENAME);
+                  ninfo("Redirect to location: '%s'\n",
+                        ws->line + strlen(g_httplocation));
+                  ret = parseurl(ws->line + strlen(g_httplocation), ws);
                   ninfo("New hostname='%s' filename='%s'\n",
                         ws->hostname, ws->filename);
                 }
@@ -383,7 +414,7 @@ static inline int wget_parseheaders(struct wget_s *ws)
 exit:
   ws->offset = ++offset;
   ws->ndx    = ndx;
-  return OK;
+  return ret;
 }
 
 /****************************************************************************
@@ -488,18 +519,15 @@ static int wget_base(FAR const char *url, FAR char *buffer, int buflen,
 
   ws->buffer = buffer;
   ws->buflen = buflen;
-  ws->port   = 80;
 
   /* Parse the hostname (with optional port number) and filename
    * from the URL.
    */
 
-  ret = netlib_parsehttpurl(url, &ws->port,
-                            ws->hostname, CONFIG_WEBCLIENT_MAXHOSTNAME,
-                            ws->filename, CONFIG_WEBCLIENT_MAXFILENAME);
+  ret = parseurl(url, ws);
   if (ret != 0)
     {
-      nwarn("WARNING: Malformed HTTP URL: %s\n", url);
+      nwarn("WARNING: Malformed URL: %s\n", url);
       free(ws);
       errno = -ret;
       return ERROR;
@@ -511,6 +539,13 @@ static int wget_base(FAR const char *url, FAR char *buffer, int buflen,
 
   do
     {
+      if (strcmp(ws->scheme, "http"))
+        {
+          nerr("ERROR: unsupported scheme: %s\n", ws->scheme);
+          free(ws);
+          return ERROR;
+        }
+
       /* Re-initialize portions of the state structure that could have
        * been left from the previous time through the loop and should not
        * persist with the new connection.