summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2009-03-28 16:30:39 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2009-03-28 16:30:39 +0000
commitb37885ca468f333484a722f387a7e15193a1b561 (patch)
tree3411e813ba52438dfd7484b3a698da400b16da49
parente0fdc9c8c430448845bcccc3dcbb34048dbe5cf1 (diff)
downloadnuttx-b37885ca468f333484a722f387a7e15193a1b561.tar.gz
nuttx-b37885ca468f333484a722f387a7e15193a1b561.tar.bz2
nuttx-b37885ca468f333484a722f387a7e15193a1b561.zip
Numerous fixes; seems to handle redirection pretty well now
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1655 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--nuttx/netutils/webclient/webclient.c107
1 files changed, 66 insertions, 41 deletions
diff --git a/nuttx/netutils/webclient/webclient.c b/nuttx/netutils/webclient/webclient.c
index 823863a51..2a2e2ddf8 100644
--- a/nuttx/netutils/webclient/webclient.c
+++ b/nuttx/netutils/webclient/webclient.c
@@ -67,6 +67,7 @@
#endif
#include <netinet/in.h>
+#include <net/uip/uip-lib.h>
#include <net/uip/webclient.h>
/****************************************************************************
@@ -95,9 +96,13 @@
struct wget_s
{
+ /* Internal status */
+
ubyte state;
ubyte httpstatus;
+ uint16 port; /* The port number to use in the connection */
+
/* These describe the just-received buffer of data */
FAR char *buffer; /* user-provided buffer */
@@ -128,13 +133,11 @@ static const char g_httpcontenttype[] = "content-type: ";
#endif
static const char g_httphost[] = "host: ";
static const char g_httplocation[] = "location: ";
-
static const char g_httpget[] = "GET ";
-static const char g_httphttp[] = "http://";
static const char g_httpuseragentfields[] =
"Connection: close\r\n"
- "User-Agent: uIP/1.0 (; http://www.sics.se/~adam/uip/)\r\n\r\n";
+ "User-Agent: NuttX/0.4.x (; http://www.nuttx.org/)\r\n\r\n";
static const char g_http200[] = "200 ";
static const char g_http301[] = "301 ";
@@ -289,7 +292,6 @@ static inline int wget_parseheaders(struct wget_s *ws)
{
int offset;
int ndx;
- int i;
offset = ws->offset;
ndx = ws->ndx;
@@ -338,36 +340,14 @@ static inline int wget_parseheaders(struct wget_s *ws)
#endif
if (strncasecmp(ws->line, g_httplocation, strlen(g_httplocation)) == 0)
{
- /* Save a pointer to the location */
-
- char *dest = ws->line + strlen(g_httplocation);
-
- /* Concatenate the hostname */
+ /* 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.
+ */
- if (strncmp(dest, g_httphttp, strlen(g_httphttp)) == 0)
- {
- for(i = 0, dest += 7; i < ws->ndx - 7; i++, dest++)
- {
- if (*dest == 0 || *dest == '/' || *dest == ' ' || *dest == ':')
- {
- ws->hostname[i] = 0;
- break;
- }
- else if (i < CONFIG_WEBCLIENT_MAXHOSTNAME-1)
- {
- ws->hostname[i] = *dest;
- }
- }
- }
-
- /* Copy the location */
-
- strncpy(ws->filename, dest, CONFIG_WEBCLIENT_MAXFILENAME-1);
-
- /* Make sure that everything is NULL terminated */
-
- ws->hostname[CONFIG_WEBCLIENT_MAXHOSTNAME-1] = '\0';
- ws->filename[CONFIG_WEBCLIENT_MAXFILENAME-1] = '\0';
+ (void)uip_parsehttpurl(ws->line + strlen(g_httplocation), &ws->port,
+ ws->hostname, CONFIG_WEBCLIENT_MAXHOSTNAME,
+ ws->filename, CONFIG_WEBCLIENT_MAXFILENAME);
nvdbg("New hostname='%s' filename='%s'\n", ws->hostname, ws->filename);
}
}
@@ -397,11 +377,34 @@ exit:
/****************************************************************************
* Name: wget
+ *
+ * Description:
+ * Obtain the requested file from an HTTP server using the GET method.
+ *
+ * Note: If the function is passed a host name, it must already be in
+ * the resolver cache in order for the function to connect to the web
+ * server. It is therefore up to the calling module to implement the
+ * resolver calls and the signal handler used for reporting a resolv
+ * query answer.
+ *
+ * Input Parameters
+ * url - A pointer to a string containing either the full URL to
+ * the file to get (e.g., http://www.nutt.org/index.html, or
+ * http://192.168.23.1:80/index.html).
+ * buffer - A user provided buffer to receive the file data (also
+ * used for the outgoing GET request
+ * buflen - The size of the user provided buffer
+ * callback - As data is obtained from the host, this function is
+ * to dispose of each block of file data as it is received.
+ *
+ * Returned Value:
+ * 0: if the GET operation completed successfully;
+ * -1: On a failure with errno set appropriately
+ *
****************************************************************************/
-int wget(uint16 port,
- FAR const char *hostname, FAR const char *filename,
- FAR char *buffer, int buflen, wget_callback_t callback)
+int wget(FAR const char *url, FAR char *buffer, int buflen,
+ wget_callback_t callback)
{
struct sockaddr_in server;
struct wget_s ws;
@@ -416,13 +419,35 @@ int wget(uint16 port,
memset(&ws, 0, sizeof(struct wget_s));
ws.buffer = buffer;
ws.buflen = buflen;
- strncpy(ws.hostname, hostname, CONFIG_WEBCLIENT_MAXHOSTNAME);
- strncpy(ws.filename, filename, CONFIG_WEBCLIENT_MAXFILENAME);
+ ws.port = 80;
+
+ /* Parse the hostname (with optional port number) and filename from the URL */
+
+ ret = uip_parsehttpurl(url, &ws.port,
+ ws.hostname, CONFIG_WEBCLIENT_MAXHOSTNAME,
+ ws.filename, CONFIG_WEBCLIENT_MAXFILENAME);
+ if (ret != 0)
+ {
+ ndbg("Malformed HTTP URL: %s\n", url);
+ errno = -ret;
+ return ERROR;
+ }
+ nvdbg("hostname='%s' filename='%s'\n", ws.hostname, ws.filename);
/* The following sequence may repeat indefinitely if we are redirected */
do
{
+ /* 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.
+ */
+
+ ws.httpstatus = HTTPSTATUS_NONE;
+ ws.offset = 0;
+ ws.datend = 0;
+ ws.ndx = 0;
+
/* Create a socket */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
@@ -437,7 +462,7 @@ int wget(uint16 port,
/* Get the server adddress from the host name */
server.sin_family = AF_INET;
- server.sin_port = htons(port);
+ server.sin_port = htons(ws.port);
ret = wget_resolvehost(ws.hostname, &server.sin_addr.s_addr);
if (ret < 0)
{
@@ -464,12 +489,12 @@ int wget(uint16 port,
dest = ws.buffer;
dest = wget_strcpy(dest, g_httpget);
- dest = wget_strcpy(dest, filename);
+ dest = wget_strcpy(dest, ws.filename);
*dest++ = ISO_space;
dest = wget_strcpy(dest, g_http10);
dest = wget_strcpy(dest, g_httpcrnl);
dest = wget_strcpy(dest, g_httphost);
- dest = wget_strcpy(dest, hostname);
+ dest = wget_strcpy(dest, ws.hostname);
dest = wget_strcpy(dest, g_httpcrnl);
dest = wget_strcpy(dest, g_httpuseragentfields);
len = dest - buffer;