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 <strings.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
@ -171,6 +172,10 @@ struct conn_s
|
|||||||
struct webclient_tls_connection *tls_conn;
|
struct webclient_tls_connection *tls_conn;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* flags for wget_s::internal_flags */
|
||||||
|
|
||||||
|
#define WGET_FLAG_GOT_CONTENT_LENGTH 1
|
||||||
|
|
||||||
struct wget_s
|
struct wget_s
|
||||||
{
|
{
|
||||||
/* Internal status */
|
/* Internal status */
|
||||||
@ -193,6 +198,10 @@ struct wget_s
|
|||||||
int ndx;
|
int ndx;
|
||||||
bool skip_to_next_line;
|
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
|
#ifdef CONFIG_WEBCLIENT_GETMIMETYPE
|
||||||
char mimetype[CONFIG_WEBCLIENT_MAXMIMESIZE];
|
char mimetype[CONFIG_WEBCLIENT_MAXMIMESIZE];
|
||||||
#endif
|
#endif
|
||||||
@ -387,6 +396,38 @@ static char *wget_urlencode_strcpy(char *dest, const char *src)
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
* Name: wget_parsestatus
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -669,6 +710,25 @@ static inline int wget_parseheaders(struct webclient_context *ctx,
|
|||||||
ws->hostname, ws->filename);
|
ws->hostname, ws->filename);
|
||||||
found = true;
|
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)
|
if (found && !got_nl)
|
||||||
@ -1209,6 +1269,17 @@ int webclient_perform(FAR struct webclient_context *ctx)
|
|||||||
goto errout_with_errno;
|
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");
|
ninfo("Connection lost\n");
|
||||||
ws->state = WEBCLIENT_STATE_CLOSE;
|
ws->state = WEBCLIENT_STATE_CLOSE;
|
||||||
ws->redirected = 0;
|
ws->redirected = 0;
|
||||||
@ -1244,6 +1315,11 @@ int webclient_perform(FAR struct webclient_context *ctx)
|
|||||||
{
|
{
|
||||||
if (ws->httpstatus != HTTPSTATUS_MOVED)
|
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
|
/* Let the client decide what to do with the
|
||||||
* received file.
|
* received file.
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user