webclient: check content-length
While it's better to use a reliable transport like TLS with working close notify, it isn't always possible.
This commit is contained in:
parent
c9bee94bd7
commit
23e0325698
@ -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
|
||||
@ -387,6 +396,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.
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user