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 2021/08/16 16:48:43 UTC

[incubator-nuttx-apps] branch master updated: webclient: check content-length

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 23e0325  webclient: check content-length
23e0325 is described below

commit 23e0325698e8e9569c55a6c0f4f42e27c3bd014f
Author: YAMAMOTO Takashi <ya...@midokura.com>
AuthorDate: Wed Aug 11 13:10:39 2021 +0900

    webclient: check content-length
    
    While it's better to use a reliable transport like
    TLS with working close notify, it isn't always possible.
---
 netutils/webclient/webclient.c | 76 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/netutils/webclient/webclient.c b/netutils/webclient/webclient.c
index 5ac8d51..bc5eb38 100644
--- a/netutils/webclient/webclient.c
+++ b/netutils/webclient/webclient.c
@@ -66,6 +66,7 @@
 #include <strings.h>
 #include <stdlib.h>
 #include <errno.h>
+#include <inttypes.h>
 
 #include <arpa/inet.h>
 #include <netinet/in.h>
@@ -171,6 +172,10 @@ struct conn_s
   struct webclient_tls_connection *tls_conn;
 };
 
+/* flags for wget_s::internal_flags */
+
+#define	WGET_FLAG_GOT_CONTENT_LENGTH	1
+
 struct wget_s
 {
   /* Internal status */
@@ -193,6 +198,10 @@ struct wget_s
   int  ndx;
   bool skip_to_next_line;
 
+  unsigned int internal_flags; /* OR'ed WGET_FLAG_xxx */
+  uintmax_t expected_resp_body_len;
+  uintmax_t received_body_len;
+
 #ifdef CONFIG_WEBCLIENT_GETMIMETYPE
   char mimetype[CONFIG_WEBCLIENT_MAXMIMESIZE];
 #endif
@@ -388,6 +397,38 @@ static char *wget_urlencode_strcpy(char *dest, const char *src)
 #endif
 
 /****************************************************************************
+ * Name: wget_parseint
+ ****************************************************************************/
+
+static int wget_parseint(const char *cp, uintmax_t *resultp)
+{
+  char *ep;
+  uintmax_t val;
+
+  errno = 0;
+  val = strtoumax(cp, &ep, 10);
+  if (cp == ep)
+    {
+      return -EINVAL; /* not a number */
+    }
+
+  if (*ep != '\0')
+    {
+      return -EINVAL; /* not a number */
+    }
+
+  if (errno != 0)
+    {
+      DEBUGASSERT(errno == ERANGE);
+      DEBUGASSERT(val == UINTMAX_MAX);
+      return -errno;
+    }
+
+  *resultp = val;
+  return 0;
+}
+
+/****************************************************************************
  * Name: wget_parsestatus
  ****************************************************************************/
 
@@ -669,6 +710,25 @@ static inline int wget_parseheaders(struct webclient_context *ctx,
                         ws->hostname, ws->filename);
                   found = true;
                 }
+              else if (strncasecmp(ws->line, g_httpcontsize,
+                                   strlen(g_httpcontsize)) == 0)
+                {
+                  found = true;
+                  if (got_nl)
+                    {
+                      ret = wget_parseint(ws->line + strlen(g_httpcontsize),
+                                          &ws->expected_resp_body_len);
+                      if (ret != 0)
+                        {
+                          goto exit;
+                        }
+
+                      ws->internal_flags |=
+                          WGET_FLAG_GOT_CONTENT_LENGTH;
+                      ninfo("Content-Length %ju\n",
+                            ws->expected_resp_body_len);
+                    }
+                }
             }
 
           if (found && !got_nl)
@@ -1209,6 +1269,17 @@ int webclient_perform(FAR struct webclient_context *ctx)
                       goto errout_with_errno;
                     }
 
+                  if ((ws->internal_flags &
+                       WGET_FLAG_GOT_CONTENT_LENGTH) != 0 &&
+                      ws->expected_resp_body_len != ws->received_body_len)
+                    {
+                      nerr("Unexpected response body length: %ju != %ju\n",
+                           ws->expected_resp_body_len,
+                           ws->received_body_len);
+                      ret = -EPROTO;
+                      goto errout_with_errno;
+                    }
+
                   ninfo("Connection lost\n");
                   ws->state = WEBCLIENT_STATE_CLOSE;
                   ws->redirected = 0;
@@ -1244,6 +1315,11 @@ int webclient_perform(FAR struct webclient_context *ctx)
                 {
                   if (ws->httpstatus != HTTPSTATUS_MOVED)
                     {
+                      ninfo("Processing resp body %ju - %ju\n",
+                            ws->received_body_len,
+                            ws->received_body_len + ws->datend - ws->offset);
+                      ws->received_body_len += ws->datend - ws->offset;
+
                       /* Let the client decide what to do with the
                        * received file.
                        */