summaryrefslogtreecommitdiff
path: root/nuttx/netutils/webclient
diff options
context:
space:
mode:
Diffstat (limited to 'nuttx/netutils/webclient')
-rw-r--r--nuttx/netutils/webclient/Make.defs37
-rwxr-xr-xnuttx/netutils/webclient/makestrings40
-rw-r--r--nuttx/netutils/webclient/webclient-strings31
-rw-r--r--nuttx/netutils/webclient/webclient-strings.c93
-rw-r--r--nuttx/netutils/webclient/webclient-strings.h31
-rw-r--r--nuttx/netutils/webclient/webclient.c450
-rw-r--r--nuttx/netutils/webclient/webclient.h214
7 files changed, 896 insertions, 0 deletions
diff --git a/nuttx/netutils/webclient/Make.defs b/nuttx/netutils/webclient/Make.defs
new file mode 100644
index 000000000..a5bffd45a
--- /dev/null
+++ b/nuttx/netutils/webclient/Make.defs
@@ -0,0 +1,37 @@
+############################################################################
+# Make.defs
+#
+# Copyright (C) 2007 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+WEBCLIENT_ASRCS =
+WEBCLIENT_CSRCS = webclient-strings.c webclient.c
diff --git a/nuttx/netutils/webclient/makestrings b/nuttx/netutils/webclient/makestrings
new file mode 100755
index 000000000..6dec075dd
--- /dev/null
+++ b/nuttx/netutils/webclient/makestrings
@@ -0,0 +1,40 @@
+#!/usr/bin/perl
+
+
+sub stringify {
+ my $name = shift(@_);
+ open(OUTPUTC, "> $name.c");
+ open(OUTPUTH, "> $name.h");
+
+ open(FILE, "$name");
+
+ while(<FILE>) {
+ if(/(.+) "(.+)"/) {
+ $var = $1;
+ $data = $2;
+
+ $datan = $data;
+ $datan =~ s/\\r/\r/g;
+ $datan =~ s/\\n/\n/g;
+ $datan =~ s/\\01/\01/g;
+ $datan =~ s/\\0/\0/g;
+
+ printf(OUTPUTC "const char $var\[%d] = \n", length($datan) + 1);
+ printf(OUTPUTC "/* \"$data\" */\n");
+ printf(OUTPUTC "{");
+ for($j = 0; $j < length($datan); $j++) {
+ printf(OUTPUTC "%#02x, ", unpack("C", substr($datan, $j, 1)));
+ }
+ printf(OUTPUTC "0 };\n");
+
+ printf(OUTPUTH "extern const char $var\[%d];\n", length($datan) + 1);
+
+ }
+ }
+ close(OUTPUTC);
+ close(OUTPUTH);
+}
+stringify("webclient-strings");
+
+exit 0;
+
diff --git a/nuttx/netutils/webclient/webclient-strings b/nuttx/netutils/webclient/webclient-strings
new file mode 100644
index 000000000..a33139723
--- /dev/null
+++ b/nuttx/netutils/webclient/webclient-strings
@@ -0,0 +1,31 @@
+http_http "http://"
+http_200 "200 "
+http_301 "301 "
+http_302 "302 "
+http_get "GET "
+http_10 "HTTP/1.0"
+http_11 "HTTP/1.1"
+http_content_type "content-type: "
+http_texthtml "text/html"
+http_location "location: "
+http_host "host: "
+http_crnl "\r\n"
+http_index_html "/index.html"
+http_404_html "/404.html"
+http_content_type_html "Content-type: text/html\r\n\r\n"
+http_content_type_css "Content-type: text/css\r\n\r\n"
+http_content_type_text "Content-type: text/text\r\n\r\n"
+http_content_type_png "Content-type: image/png\r\n\r\n"
+http_content_type_gif "Content-type: image/gif\r\n\r\n"
+http_content_type_jpg "Content-type: image/jpeg\r\n\r\n"
+http_content_type_binary "Content-type: application/octet-stream\r\n\r\n"
+http_html ".html"
+http_shtml ".shtml"
+http_htm ".htm"
+http_css ".css"
+http_png ".png"
+http_gif ".gif"
+http_jpg ".jpg"
+http_text ".text"
+http_txt ".txt"
+http_user_agent_fields "Connection: close\r\nUser-Agent: uIP/1.0 (; http://www.sics.se/~adam/uip/)\r\n\r\n"
diff --git a/nuttx/netutils/webclient/webclient-strings.c b/nuttx/netutils/webclient/webclient-strings.c
new file mode 100644
index 000000000..94723308e
--- /dev/null
+++ b/nuttx/netutils/webclient/webclient-strings.c
@@ -0,0 +1,93 @@
+const char http_http[8] =
+/* "http://" */
+{0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0 };
+const char http_200[5] =
+/* "200 " */
+{0x32, 0x30, 0x30, 0x20, 0 };
+const char http_301[5] =
+/* "301 " */
+{0x33, 0x30, 0x31, 0x20, 0 };
+const char http_302[5] =
+/* "302 " */
+{0x33, 0x30, 0x32, 0x20, 0 };
+const char http_get[5] =
+/* "GET " */
+{0x47, 0x45, 0x54, 0x20, 0 };
+const char http_10[9] =
+/* "HTTP/1.0" */
+{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0 };
+const char http_11[9] =
+/* "HTTP/1.1" */
+{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0 };
+const char http_content_type[15] =
+/* "content-type: " */
+{0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0 };
+const char http_texthtml[10] =
+/* "text/html" */
+{0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0 };
+const char http_location[11] =
+/* "location: " */
+{0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0 };
+const char http_host[7] =
+/* "host: " */
+{0x68, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0 };
+const char http_crnl[3] =
+/* "\r\n" */
+{0xd, 0xa, 0 };
+const char http_index_html[12] =
+/* "/index.html" */
+{0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0 };
+const char http_404_html[10] =
+/* "/404.html" */
+{0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0 };
+const char http_content_type_html[28] =
+/* "Content-type: text/html\r\n\r\n" */
+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 0xd, 0xa, 0 };
+const char http_content_type_css [27] =
+/* "Content-type: text/css\r\n\r\n" */
+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0xd, 0xa, 0xd, 0xa, 0 };
+const char http_content_type_text[28] =
+/* "Content-type: text/text\r\n\r\n" */
+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x74, 0x65, 0x78, 0x74, 0xd, 0xa, 0xd, 0xa, 0 };
+const char http_content_type_png [28] =
+/* "Content-type: image/png\r\n\r\n" */
+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0xd, 0xa, 0xd, 0xa, 0 };
+const char http_content_type_gif [28] =
+/* "Content-type: image/gif\r\n\r\n" */
+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0xd, 0xa, 0xd, 0xa, 0 };
+const char http_content_type_jpg [29] =
+/* "Content-type: image/jpeg\r\n\r\n" */
+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x65, 0x67, 0xd, 0xa, 0xd, 0xa, 0 };
+const char http_content_type_binary[43] =
+/* "Content-type: application/octet-stream\r\n\r\n" */
+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xd, 0xa, 0xd, 0xa, 0 };
+const char http_html[6] =
+/* ".html" */
+{0x2e, 0x68, 0x74, 0x6d, 0x6c, 0 };
+const char http_shtml[7] =
+/* ".shtml" */
+{0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0 };
+const char http_htm[5] =
+/* ".htm" */
+{0x2e, 0x68, 0x74, 0x6d, 0 };
+const char http_css[5] =
+/* ".css" */
+{0x2e, 0x63, 0x73, 0x73, 0 };
+const char http_png[5] =
+/* ".png" */
+{0x2e, 0x70, 0x6e, 0x67, 0 };
+const char http_gif[5] =
+/* ".gif" */
+{0x2e, 0x67, 0x69, 0x66, 0 };
+const char http_jpg[5] =
+/* ".jpg" */
+{0x2e, 0x6a, 0x70, 0x67, 0 };
+const char http_text[6] =
+/* ".text" */
+{0x2e, 0x74, 0x65, 0x78, 0x74, 0 };
+const char http_txt[5] =
+/* ".txt" */
+{0x2e, 0x74, 0x78, 0x74, 0 };
+const char http_user_agent_fields[77] =
+/* "Connection: close\r\nUser-Agent: uIP/1.0 (; http://www.sics.se/~adam/uip/)\r\n\r\n" */
+{0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x28, 0x3b, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x2f, 0x7e, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x75, 0x69, 0x70, 0x2f, 0x29, 0xd, 0xa, 0xd, 0xa, 0 };
diff --git a/nuttx/netutils/webclient/webclient-strings.h b/nuttx/netutils/webclient/webclient-strings.h
new file mode 100644
index 000000000..9e3ec9347
--- /dev/null
+++ b/nuttx/netutils/webclient/webclient-strings.h
@@ -0,0 +1,31 @@
+extern const char http_http[8];
+extern const char http_200[5];
+extern const char http_301[5];
+extern const char http_302[5];
+extern const char http_get[5];
+extern const char http_10[9];
+extern const char http_11[9];
+extern const char http_content_type[15];
+extern const char http_texthtml[10];
+extern const char http_location[11];
+extern const char http_host[7];
+extern const char http_crnl[3];
+extern const char http_index_html[12];
+extern const char http_404_html[10];
+extern const char http_content_type_html[28];
+extern const char http_content_type_css [27];
+extern const char http_content_type_text[28];
+extern const char http_content_type_png [28];
+extern const char http_content_type_gif [28];
+extern const char http_content_type_jpg [29];
+extern const char http_content_type_binary[43];
+extern const char http_html[6];
+extern const char http_shtml[7];
+extern const char http_htm[5];
+extern const char http_css[5];
+extern const char http_png[5];
+extern const char http_gif[5];
+extern const char http_jpg[5];
+extern const char http_text[6];
+extern const char http_txt[5];
+extern const char http_user_agent_fields[77];
diff --git a/nuttx/netutils/webclient/webclient.c b/nuttx/netutils/webclient/webclient.c
new file mode 100644
index 000000000..30718e723
--- /dev/null
+++ b/nuttx/netutils/webclient/webclient.c
@@ -0,0 +1,450 @@
+/* webclient.c
+ * Implementation of the HTTP client.
+ * Author: Adam Dunkels <adam@dunkels.com>
+ *
+ * This example shows a HTTP client that is able to download web pages
+ * and files from web servers. It requires a number of callback
+ * functions to be implemented by the module that utilizes the code:
+ * webclient_datahandler(), webclient_connected(),
+ * webclient_timedout(), webclient_aborted(), webclient_closed().
+ *
+ * Copyright (c) 2002, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack.
+ *
+ * $Id: webclient.c,v 1.1.1.1 2007-08-26 23:07:05 patacongo Exp $
+ *
+ */
+
+#include <sys/types.h>
+#include <string.h>
+
+#include <net/uip/uip.h>
+#include <net/uip/resolv.h>
+
+#include "uiplib/uiplib.h"
+#include "webclient.h"
+
+#define WEBCLIENT_TIMEOUT 100
+
+#define WEBCLIENT_STATE_STATUSLINE 0
+#define WEBCLIENT_STATE_HEADERS 1
+#define WEBCLIENT_STATE_DATA 2
+#define WEBCLIENT_STATE_CLOSE 3
+
+#define HTTPFLAG_NONE 0
+#define HTTPFLAG_OK 1
+#define HTTPFLAG_MOVED 2
+#define HTTPFLAG_ERROR 3
+
+
+#define ISO_nl 0x0a
+#define ISO_cr 0x0d
+#define ISO_space 0x20
+
+
+static struct webclient_state s;
+
+char *webclient_mimetype(void)
+{
+ return s.mimetype;
+}
+
+char *webclient_filename(void)
+{
+ return s.file;
+}
+
+char *webclient_hostname(void)
+{
+ return s.host;
+}
+
+unsigned shortwebclient_port(void)
+{
+ return s.port;
+}
+
+void webclient_init(void)
+{
+}
+
+static void init_connection(void)
+{
+ s.state = WEBCLIENT_STATE_STATUSLINE;
+
+ s.getrequestleft = sizeof(http_get) - 1 + 1 +
+ sizeof(http_10) - 1 +
+ sizeof(http_crnl) - 1 +
+ sizeof(http_host) - 1 +
+ sizeof(http_crnl) - 1 +
+ strlen(http_user_agent_fields) +
+ strlen(s.file) + strlen(s.host);
+ s.getrequestptr = 0;
+
+ s.httpheaderlineptr = 0;
+}
+
+void webclient_close(void)
+{
+ s.state = WEBCLIENT_STATE_CLOSE;
+}
+
+unsigned char webclient_get(char *host, uint16 port, char *file)
+{
+ struct uip_conn *conn;
+ uip_ipaddr_t *ipaddr;
+ static uip_ipaddr_t addr;
+
+ /* First check if the host is an IP address. */
+ ipaddr = &addr;
+ if (uiplib_ipaddrconv(host, (unsigned char *)addr) == 0) {
+ ipaddr = (uip_ipaddr_t *)resolv_lookup(host);
+
+ if (ipaddr == NULL) {
+ return 0;
+ }
+ }
+
+ conn = uip_connect(ipaddr, htons(port));
+
+ if (conn == NULL) {
+ return 0;
+ }
+
+ s.port = port;
+ strncpy(s.file, file, sizeof(s.file));
+ strncpy(s.host, host, sizeof(s.host));
+
+ init_connection();
+ return 1;
+}
+
+static char *copy_string(char *dest, const char *src, int len)
+{
+ strncpy(dest, src, len);
+ return dest + len;
+}
+
+static void senddata(void)
+{
+ uint16 len;
+ char *getrequest;
+ char *cptr;
+
+ if (s.getrequestleft > 0) {
+ cptr = getrequest = (char *)uip_appdata;
+
+ cptr = copy_string(cptr, http_get, sizeof(http_get) - 1);
+ cptr = copy_string(cptr, s.file, strlen(s.file));
+ *cptr++ = ISO_space;
+ cptr = copy_string(cptr, http_10, sizeof(http_10) - 1);
+
+ cptr = copy_string(cptr, http_crnl, sizeof(http_crnl) - 1);
+
+ cptr = copy_string(cptr, http_host, sizeof(http_host) - 1);
+ cptr = copy_string(cptr, s.host, strlen(s.host));
+ cptr = copy_string(cptr, http_crnl, sizeof(http_crnl) - 1);
+
+ cptr = copy_string(cptr, http_user_agent_fields,
+ strlen(http_user_agent_fields));
+
+ len = s.getrequestleft > uip_mss()?
+ uip_mss():
+ s.getrequestleft;
+ uip_send(&(getrequest[s.getrequestptr]), len);
+ }
+}
+
+static void acked(void)
+{
+ uint16 len;
+
+ if (s.getrequestleft > 0) {
+ len = s.getrequestleft > uip_mss()?
+ uip_mss():
+ s.getrequestleft;
+ s.getrequestleft -= len;
+ s.getrequestptr += len;
+ }
+}
+
+static uint16 parse_statusline(uint16 len)
+{
+ char *cptr;
+
+ while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline))
+ {
+ char *pappdata = (char*)uip_appdata;
+ s.httpheaderline[s.httpheaderlineptr] = *pappdata++;
+ uip_appdata = (void*)pappdata;
+ len--;
+
+ if (s.httpheaderline[s.httpheaderlineptr] == ISO_nl)
+ {
+ if ((strncmp(s.httpheaderline, http_10, sizeof(http_10) - 1) == 0) ||
+ (strncmp(s.httpheaderline, http_11, sizeof(http_11) - 1) == 0))
+ {
+ cptr = &(s.httpheaderline[9]);
+ s.httpflag = HTTPFLAG_NONE;
+ if (strncmp(cptr, http_200, sizeof(http_200) - 1) == 0)
+ {
+ /* 200 OK */
+ s.httpflag = HTTPFLAG_OK;
+ }
+ else if (strncmp(cptr, http_301, sizeof(http_301) - 1) == 0 ||
+ strncmp(cptr, http_302, sizeof(http_302) - 1) == 0)
+ {
+ /* 301 Moved permanently or 302 Found. Location: header line
+ * will contain thw new location.
+ */
+
+ s.httpflag = HTTPFLAG_MOVED;
+ }
+ else
+ {
+ s.httpheaderline[s.httpheaderlineptr - 1] = 0;
+ }
+ }
+ else
+ {
+ uip_abort();
+ webclient_aborted();
+ return 0;
+ }
+
+ /* We're done parsing the status line, so we reset the pointer
+ * and start parsing the HTTP headers.
+ */
+
+ s.httpheaderlineptr = 0;
+ s.state = WEBCLIENT_STATE_HEADERS;
+ break;
+ }
+ else
+ {
+ ++s.httpheaderlineptr;
+ }
+ }
+ return len;
+}
+
+static char casecmp(char *str1, const char *str2, char len)
+{
+ static char c;
+
+ while(len > 0) {
+ c = *str1;
+ /* Force lower-case characters. */
+ if (c & 0x40) {
+ c |= 0x20;
+ }
+ if (*str2 != c) {
+ return 1;
+ }
+ ++str1;
+ ++str2;
+ --len;
+ }
+ return 0;
+}
+
+static uint16 parse_headers(uint16 len)
+{
+ char *cptr;
+ static unsigned char i;
+
+ while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline))
+ {
+ char *pappdata = (char*)uip_appdata;
+ s.httpheaderline[s.httpheaderlineptr] = *pappdata++;
+ uip_appdata = (void*)pappdata;
+ len--;
+
+ if (s.httpheaderline[s.httpheaderlineptr] == ISO_nl)
+ {
+ /* We have an entire HTTP header line in s.httpheaderline, so
+ * we parse it.
+ */
+
+ if (s.httpheaderline[0] == ISO_cr)
+ {
+ /* This was the last header line (i.e., and empty "\r\n"), so
+ * we are done with the headers and proceed with the actual
+ * data.
+ */
+
+ s.state = WEBCLIENT_STATE_DATA;
+ return len;
+ }
+
+ s.httpheaderline[s.httpheaderlineptr - 1] = 0;
+
+ /* Check for specific HTTP header fields. */
+ if (casecmp(s.httpheaderline, http_content_type, sizeof(http_content_type) - 1) == 0)
+ {
+ /* Found Content-type field. */
+ cptr = strchr(s.httpheaderline, ';');
+ if (cptr != NULL)
+ {
+ *cptr = 0;
+ }
+ strncpy(s.mimetype, s.httpheaderline + sizeof(http_content_type) - 1, sizeof(s.mimetype));
+ }
+ else if (casecmp(s.httpheaderline, http_location, sizeof(http_location) - 1) == 0)
+ {
+ cptr = s.httpheaderline + sizeof(http_location) - 1;
+
+ if (strncmp(cptr, http_http, 7) == 0)
+ {
+ cptr += 7;
+ for(i = 0; i < s.httpheaderlineptr - 7; ++i)
+ {
+ if (*cptr == 0 || *cptr == '/' || *cptr == ' ' || *cptr == ':')
+ {
+ s.host[i] = 0;
+ break;
+ }
+ s.host[i] = *cptr;
+ ++cptr;
+ }
+ }
+ strncpy(s.file, cptr, sizeof(s.file));
+ }
+
+ /* We're done parsing, so we reset the pointer and start the
+ * next line.
+ */
+
+ s.httpheaderlineptr = 0;
+ }
+ else
+ {
+ ++s.httpheaderlineptr;
+ }
+ }
+ return len;
+}
+
+static void newdata(void)
+{
+ uint16 len;
+
+ len = uip_datalen();
+
+ if (s.state == WEBCLIENT_STATE_STATUSLINE) {
+ len = parse_statusline(len);
+ }
+
+ if (s.state == WEBCLIENT_STATE_HEADERS && len > 0) {
+ len = parse_headers(len);
+ }
+
+ if (len > 0 && s.state == WEBCLIENT_STATE_DATA &&
+ s.httpflag != HTTPFLAG_MOVED) {
+ webclient_datahandler((char *)uip_appdata, len);
+ }
+}
+
+/* This function is called by the UIP interrupt handling logic whenevent an
+ * event of interest occurs.
+ */
+
+void uip_interrupt_event(void)
+{
+ if (uip_connected())
+ {
+ s.timer = 0;
+ s.state = WEBCLIENT_STATE_STATUSLINE;
+ senddata();
+ webclient_connected();
+ return;
+ }
+
+ if (s.state == WEBCLIENT_STATE_CLOSE)
+ {
+ webclient_closed();
+ uip_abort();
+ return;
+ }
+
+ if (uip_aborted())
+ {
+ webclient_aborted();
+ }
+
+ if (uip_timedout())
+ {
+ webclient_timedout();
+ }
+
+ if (uip_acked())
+ {
+ s.timer = 0;
+ acked();
+ }
+
+ if (uip_newdata())
+ {
+ s.timer = 0;
+ newdata();
+ }
+
+ if (uip_rexmit() || uip_newdata() || uip_acked())
+ {
+ senddata();
+ }
+ else if (uip_poll())
+ {
+ ++s.timer;
+ if (s.timer == WEBCLIENT_TIMEOUT)
+ {
+ webclient_timedout();
+ uip_abort();
+ return;
+ }
+ }
+
+ if (uip_closed())
+ {
+ if (s.httpflag != HTTPFLAG_MOVED)
+ {
+ /* Send NULL data to signal EOF. */
+ webclient_datahandler(NULL, 0);
+ }
+ else
+ {
+ if (resolv_lookup(s.host) == NULL)
+ {
+ resolv_query(s.host);
+ }
+ webclient_get(s.host, s.port, s.file);
+ }
+ }
+}
diff --git a/nuttx/netutils/webclient/webclient.h b/nuttx/netutils/webclient/webclient.h
new file mode 100644
index 000000000..c6559e3f0
--- /dev/null
+++ b/nuttx/netutils/webclient/webclient.h
@@ -0,0 +1,214 @@
+/**
+ * webclient.h
+ * Header file for the HTTP client.
+ * Author: Adam Dunkels <adam@dunkels.com>
+ *
+ * Copyright (c) 2002, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack.
+ *
+ * $Id: webclient.h,v 1.1.1.1 2007-08-26 23:07:04 patacongo Exp $
+ *
+ */
+#ifndef __WEBCLIENT_H__
+#define __WEBCLIENT_H__
+
+#include <sys/types.h>
+#include <net/uip/uipopt.h>
+
+#include "webclient-strings.h"
+
+#define WEBCLIENT_CONF_MAX_URLLEN 100
+
+struct webclient_state {
+ uint8 timer;
+ uint8 state;
+ uint8 httpflag;
+
+ uint16 port;
+ char host[40];
+ char file[WEBCLIENT_CONF_MAX_URLLEN];
+ uint16 getrequestptr;
+ uint16 getrequestleft;
+
+ char httpheaderline[200];
+ uint16 httpheaderlineptr;
+
+ char mimetype[32];
+};
+
+/**
+ * Callback function that is called from the webclient code when HTTP
+ * data has been received.
+ *
+ * This function must be implemented by the module that uses the
+ * webclient code. The function is called from the webclient module
+ * when HTTP data has been received. The function is not called when
+ * HTTP headers are received, only for the actual data.
+ *
+ * \note This function is called many times, repetedly, when data is
+ * being received, and not once when all data has been received.
+ *
+ * \param data A pointer to the data that has been received.
+ * \param len The length of the data that has been received.
+ */
+void webclient_datahandler(char *data, uint16 len);
+
+/**
+ * Callback function that is called from the webclient code when the
+ * HTTP connection has been connected to the web server.
+ *
+ * This function must be implemented by the module that uses the
+ * webclient code.
+ */
+void webclient_connected(void);
+
+/**
+ * Callback function that is called from the webclient code if the
+ * HTTP connection to the web server has timed out.
+ *
+ * This function must be implemented by the module that uses the
+ * webclient code.
+ */
+void webclient_timedout(void);
+
+/**
+ * Callback function that is called from the webclient code if the
+ * HTTP connection to the web server has been aborted by the web
+ * server.
+ *
+ * This function must be implemented by the module that uses the
+ * webclient code.
+ */
+void webclient_aborted(void);
+
+/**
+ * Callback function that is called from the webclient code when the
+ * HTTP connection to the web server has been closed.
+ *
+ * This function must be implemented by the module that uses the
+ * webclient code.
+ */
+void webclient_closed(void);
+
+/**
+ * Initialize the webclient module.
+ */
+void webclient_init(void);
+
+/**
+ * Open an HTTP connection to a web server and ask for a file using
+ * the GET method.
+ *
+ * This function opens an HTTP connection to the specified web server
+ * and requests the specified file using the GET method. When the HTTP
+ * connection has been connected, the webclient_connected() callback
+ * function is called and when the HTTP data arrives the
+ * webclient_datahandler() callback function is called.
+ *
+ * The callback function webclient_timedout() is called if the web
+ * server could not be contacted, and the webclient_aborted() callback
+ * function is called if the HTTP connection is aborted by the web
+ * server.
+ *
+ * When the HTTP request has been completed and the HTTP connection is
+ * closed, the webclient_closed() callback function will be called.
+ *
+ * \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.
+ *
+ * \param host A pointer to a string containing either a host name or
+ * a numerical IP address in dotted decimal notation (e.g., 192.168.23.1).
+ *
+ * \param port The port number to which to connect, in host byte order.
+ *
+ * \param file A pointer to the name of the file to get.
+ *
+ * \retval 0 if the host name could not be found in the cache, or
+ * if a TCP connection could not be created.
+ *
+ * \retval 1 if the connection was initiated.
+ */
+unsigned char webclient_get(char *host, uint16 port, char *file);
+
+/**
+ * Close the currently open HTTP connection.
+ */
+void webclient_close(void);
+
+/**
+ * Obtain the MIME type of the current HTTP data stream.
+ *
+ * \return A pointer to a string contaning the MIME type. The string
+ * may be empty if no MIME type was reported by the web server.
+ */
+char *webclient_mimetype(void);
+
+/**
+ * Obtain the filename of the current HTTP data stream.
+ *
+ * The filename of an HTTP request may be changed by the web server,
+ * and may therefore not be the same as when the original GET request
+ * was made with webclient_get(). This function is used for obtaining
+ * the current filename.
+ *
+ * \return A pointer to the current filename.
+ */
+char *webclient_filename(void);
+
+/**
+ * Obtain the hostname of the current HTTP data stream.
+ *
+ * The hostname of the web server of an HTTP request may be changed
+ * by the web server, and may therefore not be the same as when the
+ * original GET request was made with webclient_get(). This function
+ * is used for obtaining the current hostname.
+ *
+ * \return A pointer to the current hostname.
+ */
+char *webclient_hostname(void);
+
+/**
+ * Obtain the port number of the current HTTP data stream.
+ *
+ * The port number of an HTTP request may be changed by the web
+ * server, and may therefore not be the same as when the original GET
+ * request was made with webclient_get(). This function is used for
+ * obtaining the current port number.
+ *
+ * \return The port number of the current HTTP data stream, in host byte order.
+ */
+unsigned short webclient_port(void);
+
+#endif /* __WEBCLIENT_H__ */
+
+/** @} */