These are the examples provided for [[/users/frank26080115/libraries/LPC1700CMSIS_Lib/]] Note, the entire "program" is not compilable!
EMAC/uIP/apps/webclient/webclient.c@0:bf7b9fba3924, 2011-03-20 (annotated)
- Committer:
- frank26080115
- Date:
- Sun Mar 20 05:38:56 2011 +0000
- Revision:
- 0:bf7b9fba3924
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
frank26080115 | 0:bf7b9fba3924 | 1 | /** @addtogroup EMAC_uIP |
frank26080115 | 0:bf7b9fba3924 | 2 | * @{ |
frank26080115 | 0:bf7b9fba3924 | 3 | */ |
frank26080115 | 0:bf7b9fba3924 | 4 | /** |
frank26080115 | 0:bf7b9fba3924 | 5 | * \addtogroup apps |
frank26080115 | 0:bf7b9fba3924 | 6 | * @{ |
frank26080115 | 0:bf7b9fba3924 | 7 | */ |
frank26080115 | 0:bf7b9fba3924 | 8 | |
frank26080115 | 0:bf7b9fba3924 | 9 | /** |
frank26080115 | 0:bf7b9fba3924 | 10 | * \defgroup webclient Web client |
frank26080115 | 0:bf7b9fba3924 | 11 | * @{ |
frank26080115 | 0:bf7b9fba3924 | 12 | * |
frank26080115 | 0:bf7b9fba3924 | 13 | * This example shows a HTTP client that is able to download web pages |
frank26080115 | 0:bf7b9fba3924 | 14 | * and files from web servers. It requires a number of callback |
frank26080115 | 0:bf7b9fba3924 | 15 | * functions to be implemented by the module that utilizes the code: |
frank26080115 | 0:bf7b9fba3924 | 16 | * webclient_datahandler(), webclient_connected(), |
frank26080115 | 0:bf7b9fba3924 | 17 | * webclient_timedout(), webclient_aborted(), webclient_closed(). |
frank26080115 | 0:bf7b9fba3924 | 18 | */ |
frank26080115 | 0:bf7b9fba3924 | 19 | |
frank26080115 | 0:bf7b9fba3924 | 20 | /** |
frank26080115 | 0:bf7b9fba3924 | 21 | * \file |
frank26080115 | 0:bf7b9fba3924 | 22 | * Implementation of the HTTP client. |
frank26080115 | 0:bf7b9fba3924 | 23 | * \author Adam Dunkels <adam@dunkels.com> |
frank26080115 | 0:bf7b9fba3924 | 24 | */ |
frank26080115 | 0:bf7b9fba3924 | 25 | |
frank26080115 | 0:bf7b9fba3924 | 26 | /* |
frank26080115 | 0:bf7b9fba3924 | 27 | * Copyright (c) 2002, Adam Dunkels. |
frank26080115 | 0:bf7b9fba3924 | 28 | * All rights reserved. |
frank26080115 | 0:bf7b9fba3924 | 29 | * |
frank26080115 | 0:bf7b9fba3924 | 30 | * Redistribution and use in source and binary forms, with or without |
frank26080115 | 0:bf7b9fba3924 | 31 | * modification, are permitted provided that the following conditions |
frank26080115 | 0:bf7b9fba3924 | 32 | * are met: |
frank26080115 | 0:bf7b9fba3924 | 33 | * 1. Redistributions of source code must retain the above copyright |
frank26080115 | 0:bf7b9fba3924 | 34 | * notice, this list of conditions and the following disclaimer. |
frank26080115 | 0:bf7b9fba3924 | 35 | * 2. Redistributions in binary form must reproduce the above |
frank26080115 | 0:bf7b9fba3924 | 36 | * copyright notice, this list of conditions and the following |
frank26080115 | 0:bf7b9fba3924 | 37 | * disclaimer in the documentation and/or other materials provided |
frank26080115 | 0:bf7b9fba3924 | 38 | * with the distribution. |
frank26080115 | 0:bf7b9fba3924 | 39 | * 3. The name of the author may not be used to endorse or promote |
frank26080115 | 0:bf7b9fba3924 | 40 | * products derived from this software without specific prior |
frank26080115 | 0:bf7b9fba3924 | 41 | * written permission. |
frank26080115 | 0:bf7b9fba3924 | 42 | * |
frank26080115 | 0:bf7b9fba3924 | 43 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS |
frank26080115 | 0:bf7b9fba3924 | 44 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
frank26080115 | 0:bf7b9fba3924 | 45 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
frank26080115 | 0:bf7b9fba3924 | 46 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
frank26080115 | 0:bf7b9fba3924 | 47 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
frank26080115 | 0:bf7b9fba3924 | 48 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
frank26080115 | 0:bf7b9fba3924 | 49 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
frank26080115 | 0:bf7b9fba3924 | 50 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
frank26080115 | 0:bf7b9fba3924 | 51 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
frank26080115 | 0:bf7b9fba3924 | 52 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
frank26080115 | 0:bf7b9fba3924 | 53 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
frank26080115 | 0:bf7b9fba3924 | 54 | * |
frank26080115 | 0:bf7b9fba3924 | 55 | * This file is part of the uIP TCP/IP stack. |
frank26080115 | 0:bf7b9fba3924 | 56 | * |
frank26080115 | 0:bf7b9fba3924 | 57 | * $Id: webclient.c,v 1.2 2006/06/11 21:46:37 adam Exp $ |
frank26080115 | 0:bf7b9fba3924 | 58 | * |
frank26080115 | 0:bf7b9fba3924 | 59 | */ |
frank26080115 | 0:bf7b9fba3924 | 60 | |
frank26080115 | 0:bf7b9fba3924 | 61 | #include "uip.h" |
frank26080115 | 0:bf7b9fba3924 | 62 | #include "uiplib.h" |
frank26080115 | 0:bf7b9fba3924 | 63 | #include "webclient.h" |
frank26080115 | 0:bf7b9fba3924 | 64 | #include "resolv.h" |
frank26080115 | 0:bf7b9fba3924 | 65 | |
frank26080115 | 0:bf7b9fba3924 | 66 | #include <string.h> |
frank26080115 | 0:bf7b9fba3924 | 67 | |
frank26080115 | 0:bf7b9fba3924 | 68 | #define WEBCLIENT_TIMEOUT 100 |
frank26080115 | 0:bf7b9fba3924 | 69 | |
frank26080115 | 0:bf7b9fba3924 | 70 | #define WEBCLIENT_STATE_STATUSLINE 0 |
frank26080115 | 0:bf7b9fba3924 | 71 | #define WEBCLIENT_STATE_HEADERS 1 |
frank26080115 | 0:bf7b9fba3924 | 72 | #define WEBCLIENT_STATE_DATA 2 |
frank26080115 | 0:bf7b9fba3924 | 73 | #define WEBCLIENT_STATE_CLOSE 3 |
frank26080115 | 0:bf7b9fba3924 | 74 | |
frank26080115 | 0:bf7b9fba3924 | 75 | #define HTTPFLAG_NONE 0 |
frank26080115 | 0:bf7b9fba3924 | 76 | #define HTTPFLAG_OK 1 |
frank26080115 | 0:bf7b9fba3924 | 77 | #define HTTPFLAG_MOVED 2 |
frank26080115 | 0:bf7b9fba3924 | 78 | #define HTTPFLAG_ERROR 3 |
frank26080115 | 0:bf7b9fba3924 | 79 | |
frank26080115 | 0:bf7b9fba3924 | 80 | |
frank26080115 | 0:bf7b9fba3924 | 81 | #define ISO_nl 0x0a |
frank26080115 | 0:bf7b9fba3924 | 82 | #define ISO_cr 0x0d |
frank26080115 | 0:bf7b9fba3924 | 83 | #define ISO_space 0x20 |
frank26080115 | 0:bf7b9fba3924 | 84 | |
frank26080115 | 0:bf7b9fba3924 | 85 | |
frank26080115 | 0:bf7b9fba3924 | 86 | static struct webclient_state s; |
frank26080115 | 0:bf7b9fba3924 | 87 | |
frank26080115 | 0:bf7b9fba3924 | 88 | /*-----------------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 89 | char * |
frank26080115 | 0:bf7b9fba3924 | 90 | webclient_mimetype(void) |
frank26080115 | 0:bf7b9fba3924 | 91 | { |
frank26080115 | 0:bf7b9fba3924 | 92 | return s.mimetype; |
frank26080115 | 0:bf7b9fba3924 | 93 | } |
frank26080115 | 0:bf7b9fba3924 | 94 | /*-----------------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 95 | char * |
frank26080115 | 0:bf7b9fba3924 | 96 | webclient_filename(void) |
frank26080115 | 0:bf7b9fba3924 | 97 | { |
frank26080115 | 0:bf7b9fba3924 | 98 | return s.file; |
frank26080115 | 0:bf7b9fba3924 | 99 | } |
frank26080115 | 0:bf7b9fba3924 | 100 | /*-----------------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 101 | char * |
frank26080115 | 0:bf7b9fba3924 | 102 | webclient_hostname(void) |
frank26080115 | 0:bf7b9fba3924 | 103 | { |
frank26080115 | 0:bf7b9fba3924 | 104 | return s.host; |
frank26080115 | 0:bf7b9fba3924 | 105 | } |
frank26080115 | 0:bf7b9fba3924 | 106 | /*-----------------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 107 | unsigned short |
frank26080115 | 0:bf7b9fba3924 | 108 | webclient_port(void) |
frank26080115 | 0:bf7b9fba3924 | 109 | { |
frank26080115 | 0:bf7b9fba3924 | 110 | return s.port; |
frank26080115 | 0:bf7b9fba3924 | 111 | } |
frank26080115 | 0:bf7b9fba3924 | 112 | /*-----------------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 113 | void |
frank26080115 | 0:bf7b9fba3924 | 114 | webclient_init(void) |
frank26080115 | 0:bf7b9fba3924 | 115 | { |
frank26080115 | 0:bf7b9fba3924 | 116 | |
frank26080115 | 0:bf7b9fba3924 | 117 | } |
frank26080115 | 0:bf7b9fba3924 | 118 | /*-----------------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 119 | static void |
frank26080115 | 0:bf7b9fba3924 | 120 | init_connection(void) |
frank26080115 | 0:bf7b9fba3924 | 121 | { |
frank26080115 | 0:bf7b9fba3924 | 122 | s.state = WEBCLIENT_STATE_STATUSLINE; |
frank26080115 | 0:bf7b9fba3924 | 123 | |
frank26080115 | 0:bf7b9fba3924 | 124 | s.getrequestleft = sizeof(http_get) - 1 + 1 + |
frank26080115 | 0:bf7b9fba3924 | 125 | sizeof(http_10) - 1 + |
frank26080115 | 0:bf7b9fba3924 | 126 | sizeof(http_crnl) - 1 + |
frank26080115 | 0:bf7b9fba3924 | 127 | sizeof(http_host) - 1 + |
frank26080115 | 0:bf7b9fba3924 | 128 | sizeof(http_crnl) - 1 + |
frank26080115 | 0:bf7b9fba3924 | 129 | strlen(http_user_agent_fields) + |
frank26080115 | 0:bf7b9fba3924 | 130 | strlen(s.file) + strlen(s.host); |
frank26080115 | 0:bf7b9fba3924 | 131 | s.getrequestptr = 0; |
frank26080115 | 0:bf7b9fba3924 | 132 | |
frank26080115 | 0:bf7b9fba3924 | 133 | s.httpheaderlineptr = 0; |
frank26080115 | 0:bf7b9fba3924 | 134 | } |
frank26080115 | 0:bf7b9fba3924 | 135 | /*-----------------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 136 | void |
frank26080115 | 0:bf7b9fba3924 | 137 | webclient_close(void) |
frank26080115 | 0:bf7b9fba3924 | 138 | { |
frank26080115 | 0:bf7b9fba3924 | 139 | s.state = WEBCLIENT_STATE_CLOSE; |
frank26080115 | 0:bf7b9fba3924 | 140 | } |
frank26080115 | 0:bf7b9fba3924 | 141 | /*-----------------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 142 | unsigned char |
frank26080115 | 0:bf7b9fba3924 | 143 | webclient_get(char *host, u16_t port, char *file) |
frank26080115 | 0:bf7b9fba3924 | 144 | { |
frank26080115 | 0:bf7b9fba3924 | 145 | struct uip_conn *conn; |
frank26080115 | 0:bf7b9fba3924 | 146 | uip_ipaddr_t *ipaddr; |
frank26080115 | 0:bf7b9fba3924 | 147 | static uip_ipaddr_t addr; |
frank26080115 | 0:bf7b9fba3924 | 148 | |
frank26080115 | 0:bf7b9fba3924 | 149 | /* First check if the host is an IP address. */ |
frank26080115 | 0:bf7b9fba3924 | 150 | ipaddr = &addr; |
frank26080115 | 0:bf7b9fba3924 | 151 | if(uiplib_ipaddrconv(host, (unsigned char *)addr) == 0) { |
frank26080115 | 0:bf7b9fba3924 | 152 | ipaddr = (uip_ipaddr_t *)resolv_lookup(host); |
frank26080115 | 0:bf7b9fba3924 | 153 | |
frank26080115 | 0:bf7b9fba3924 | 154 | if(ipaddr == NULL) { |
frank26080115 | 0:bf7b9fba3924 | 155 | return 0; |
frank26080115 | 0:bf7b9fba3924 | 156 | } |
frank26080115 | 0:bf7b9fba3924 | 157 | } |
frank26080115 | 0:bf7b9fba3924 | 158 | |
frank26080115 | 0:bf7b9fba3924 | 159 | conn = uip_connect(ipaddr, htons(port)); |
frank26080115 | 0:bf7b9fba3924 | 160 | |
frank26080115 | 0:bf7b9fba3924 | 161 | if(conn == NULL) { |
frank26080115 | 0:bf7b9fba3924 | 162 | return 0; |
frank26080115 | 0:bf7b9fba3924 | 163 | } |
frank26080115 | 0:bf7b9fba3924 | 164 | |
frank26080115 | 0:bf7b9fba3924 | 165 | s.port = port; |
frank26080115 | 0:bf7b9fba3924 | 166 | strncpy(s.file, file, sizeof(s.file)); |
frank26080115 | 0:bf7b9fba3924 | 167 | strncpy(s.host, host, sizeof(s.host)); |
frank26080115 | 0:bf7b9fba3924 | 168 | |
frank26080115 | 0:bf7b9fba3924 | 169 | init_connection(); |
frank26080115 | 0:bf7b9fba3924 | 170 | return 1; |
frank26080115 | 0:bf7b9fba3924 | 171 | } |
frank26080115 | 0:bf7b9fba3924 | 172 | /*-----------------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 173 | static unsigned char * |
frank26080115 | 0:bf7b9fba3924 | 174 | copy_string(unsigned char *dest, |
frank26080115 | 0:bf7b9fba3924 | 175 | const unsigned char *src, unsigned char len) |
frank26080115 | 0:bf7b9fba3924 | 176 | { |
frank26080115 | 0:bf7b9fba3924 | 177 | strncpy(dest, src, len); |
frank26080115 | 0:bf7b9fba3924 | 178 | return dest + len; |
frank26080115 | 0:bf7b9fba3924 | 179 | } |
frank26080115 | 0:bf7b9fba3924 | 180 | /*-----------------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 181 | static void |
frank26080115 | 0:bf7b9fba3924 | 182 | senddata(void) |
frank26080115 | 0:bf7b9fba3924 | 183 | { |
frank26080115 | 0:bf7b9fba3924 | 184 | u16_t len; |
frank26080115 | 0:bf7b9fba3924 | 185 | char *getrequest; |
frank26080115 | 0:bf7b9fba3924 | 186 | char *cptr; |
frank26080115 | 0:bf7b9fba3924 | 187 | |
frank26080115 | 0:bf7b9fba3924 | 188 | if(s.getrequestleft > 0) { |
frank26080115 | 0:bf7b9fba3924 | 189 | cptr = getrequest = (char *)uip_appdata; |
frank26080115 | 0:bf7b9fba3924 | 190 | |
frank26080115 | 0:bf7b9fba3924 | 191 | cptr = copy_string(cptr, http_get, sizeof(http_get) - 1); |
frank26080115 | 0:bf7b9fba3924 | 192 | cptr = copy_string(cptr, s.file, strlen(s.file)); |
frank26080115 | 0:bf7b9fba3924 | 193 | *cptr++ = ISO_space; |
frank26080115 | 0:bf7b9fba3924 | 194 | cptr = copy_string(cptr, http_10, sizeof(http_10) - 1); |
frank26080115 | 0:bf7b9fba3924 | 195 | |
frank26080115 | 0:bf7b9fba3924 | 196 | cptr = copy_string(cptr, http_crnl, sizeof(http_crnl) - 1); |
frank26080115 | 0:bf7b9fba3924 | 197 | |
frank26080115 | 0:bf7b9fba3924 | 198 | cptr = copy_string(cptr, http_host, sizeof(http_host) - 1); |
frank26080115 | 0:bf7b9fba3924 | 199 | cptr = copy_string(cptr, s.host, strlen(s.host)); |
frank26080115 | 0:bf7b9fba3924 | 200 | cptr = copy_string(cptr, http_crnl, sizeof(http_crnl) - 1); |
frank26080115 | 0:bf7b9fba3924 | 201 | |
frank26080115 | 0:bf7b9fba3924 | 202 | cptr = copy_string(cptr, http_user_agent_fields, |
frank26080115 | 0:bf7b9fba3924 | 203 | strlen(http_user_agent_fields)); |
frank26080115 | 0:bf7b9fba3924 | 204 | |
frank26080115 | 0:bf7b9fba3924 | 205 | len = s.getrequestleft > uip_mss()? |
frank26080115 | 0:bf7b9fba3924 | 206 | uip_mss(): |
frank26080115 | 0:bf7b9fba3924 | 207 | s.getrequestleft; |
frank26080115 | 0:bf7b9fba3924 | 208 | uip_send(&(getrequest[s.getrequestptr]), len); |
frank26080115 | 0:bf7b9fba3924 | 209 | } |
frank26080115 | 0:bf7b9fba3924 | 210 | } |
frank26080115 | 0:bf7b9fba3924 | 211 | /*-----------------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 212 | static void |
frank26080115 | 0:bf7b9fba3924 | 213 | acked(void) |
frank26080115 | 0:bf7b9fba3924 | 214 | { |
frank26080115 | 0:bf7b9fba3924 | 215 | u16_t len; |
frank26080115 | 0:bf7b9fba3924 | 216 | |
frank26080115 | 0:bf7b9fba3924 | 217 | if(s.getrequestleft > 0) { |
frank26080115 | 0:bf7b9fba3924 | 218 | len = s.getrequestleft > uip_mss()? |
frank26080115 | 0:bf7b9fba3924 | 219 | uip_mss(): |
frank26080115 | 0:bf7b9fba3924 | 220 | s.getrequestleft; |
frank26080115 | 0:bf7b9fba3924 | 221 | s.getrequestleft -= len; |
frank26080115 | 0:bf7b9fba3924 | 222 | s.getrequestptr += len; |
frank26080115 | 0:bf7b9fba3924 | 223 | } |
frank26080115 | 0:bf7b9fba3924 | 224 | } |
frank26080115 | 0:bf7b9fba3924 | 225 | /*-----------------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 226 | static u16_t |
frank26080115 | 0:bf7b9fba3924 | 227 | parse_statusline(u16_t len) |
frank26080115 | 0:bf7b9fba3924 | 228 | { |
frank26080115 | 0:bf7b9fba3924 | 229 | char *cptr; |
frank26080115 | 0:bf7b9fba3924 | 230 | |
frank26080115 | 0:bf7b9fba3924 | 231 | while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline)) { |
frank26080115 | 0:bf7b9fba3924 | 232 | s.httpheaderline[s.httpheaderlineptr] = *(char *)uip_appdata; |
frank26080115 | 0:bf7b9fba3924 | 233 | ++((char *)uip_appdata); |
frank26080115 | 0:bf7b9fba3924 | 234 | --len; |
frank26080115 | 0:bf7b9fba3924 | 235 | if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) { |
frank26080115 | 0:bf7b9fba3924 | 236 | |
frank26080115 | 0:bf7b9fba3924 | 237 | if((strncmp(s.httpheaderline, http_10, |
frank26080115 | 0:bf7b9fba3924 | 238 | sizeof(http_10) - 1) == 0) || |
frank26080115 | 0:bf7b9fba3924 | 239 | (strncmp(s.httpheaderline, http_11, |
frank26080115 | 0:bf7b9fba3924 | 240 | sizeof(http_11) - 1) == 0)) { |
frank26080115 | 0:bf7b9fba3924 | 241 | cptr = &(s.httpheaderline[9]); |
frank26080115 | 0:bf7b9fba3924 | 242 | s.httpflag = HTTPFLAG_NONE; |
frank26080115 | 0:bf7b9fba3924 | 243 | if(strncmp(cptr, http_200, sizeof(http_200) - 1) == 0) { |
frank26080115 | 0:bf7b9fba3924 | 244 | /* 200 OK */ |
frank26080115 | 0:bf7b9fba3924 | 245 | s.httpflag = HTTPFLAG_OK; |
frank26080115 | 0:bf7b9fba3924 | 246 | } else if(strncmp(cptr, http_301, sizeof(http_301) - 1) == 0 || |
frank26080115 | 0:bf7b9fba3924 | 247 | strncmp(cptr, http_302, sizeof(http_302) - 1) == 0) { |
frank26080115 | 0:bf7b9fba3924 | 248 | /* 301 Moved permanently or 302 Found. Location: header line |
frank26080115 | 0:bf7b9fba3924 | 249 | will contain thw new location. */ |
frank26080115 | 0:bf7b9fba3924 | 250 | s.httpflag = HTTPFLAG_MOVED; |
frank26080115 | 0:bf7b9fba3924 | 251 | } else { |
frank26080115 | 0:bf7b9fba3924 | 252 | s.httpheaderline[s.httpheaderlineptr - 1] = 0; |
frank26080115 | 0:bf7b9fba3924 | 253 | } |
frank26080115 | 0:bf7b9fba3924 | 254 | } else { |
frank26080115 | 0:bf7b9fba3924 | 255 | uip_abort(); |
frank26080115 | 0:bf7b9fba3924 | 256 | webclient_aborted(); |
frank26080115 | 0:bf7b9fba3924 | 257 | return 0; |
frank26080115 | 0:bf7b9fba3924 | 258 | } |
frank26080115 | 0:bf7b9fba3924 | 259 | |
frank26080115 | 0:bf7b9fba3924 | 260 | /* We're done parsing the status line, so we reset the pointer |
frank26080115 | 0:bf7b9fba3924 | 261 | and start parsing the HTTP headers.*/ |
frank26080115 | 0:bf7b9fba3924 | 262 | s.httpheaderlineptr = 0; |
frank26080115 | 0:bf7b9fba3924 | 263 | s.state = WEBCLIENT_STATE_HEADERS; |
frank26080115 | 0:bf7b9fba3924 | 264 | break; |
frank26080115 | 0:bf7b9fba3924 | 265 | } else { |
frank26080115 | 0:bf7b9fba3924 | 266 | ++s.httpheaderlineptr; |
frank26080115 | 0:bf7b9fba3924 | 267 | } |
frank26080115 | 0:bf7b9fba3924 | 268 | } |
frank26080115 | 0:bf7b9fba3924 | 269 | return len; |
frank26080115 | 0:bf7b9fba3924 | 270 | } |
frank26080115 | 0:bf7b9fba3924 | 271 | /*-----------------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 272 | static char |
frank26080115 | 0:bf7b9fba3924 | 273 | casecmp(char *str1, const char *str2, char len) |
frank26080115 | 0:bf7b9fba3924 | 274 | { |
frank26080115 | 0:bf7b9fba3924 | 275 | static char c; |
frank26080115 | 0:bf7b9fba3924 | 276 | |
frank26080115 | 0:bf7b9fba3924 | 277 | while(len > 0) { |
frank26080115 | 0:bf7b9fba3924 | 278 | c = *str1; |
frank26080115 | 0:bf7b9fba3924 | 279 | /* Force lower-case characters. */ |
frank26080115 | 0:bf7b9fba3924 | 280 | if(c & 0x40) { |
frank26080115 | 0:bf7b9fba3924 | 281 | c |= 0x20; |
frank26080115 | 0:bf7b9fba3924 | 282 | } |
frank26080115 | 0:bf7b9fba3924 | 283 | if(*str2 != c) { |
frank26080115 | 0:bf7b9fba3924 | 284 | return 1; |
frank26080115 | 0:bf7b9fba3924 | 285 | } |
frank26080115 | 0:bf7b9fba3924 | 286 | ++str1; |
frank26080115 | 0:bf7b9fba3924 | 287 | ++str2; |
frank26080115 | 0:bf7b9fba3924 | 288 | --len; |
frank26080115 | 0:bf7b9fba3924 | 289 | } |
frank26080115 | 0:bf7b9fba3924 | 290 | return 0; |
frank26080115 | 0:bf7b9fba3924 | 291 | } |
frank26080115 | 0:bf7b9fba3924 | 292 | /*-----------------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 293 | static u16_t |
frank26080115 | 0:bf7b9fba3924 | 294 | parse_headers(u16_t len) |
frank26080115 | 0:bf7b9fba3924 | 295 | { |
frank26080115 | 0:bf7b9fba3924 | 296 | char *cptr; |
frank26080115 | 0:bf7b9fba3924 | 297 | static unsigned char i; |
frank26080115 | 0:bf7b9fba3924 | 298 | |
frank26080115 | 0:bf7b9fba3924 | 299 | while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline)) { |
frank26080115 | 0:bf7b9fba3924 | 300 | s.httpheaderline[s.httpheaderlineptr] = *(char *)uip_appdata; |
frank26080115 | 0:bf7b9fba3924 | 301 | ++((char *)uip_appdata); |
frank26080115 | 0:bf7b9fba3924 | 302 | --len; |
frank26080115 | 0:bf7b9fba3924 | 303 | if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) { |
frank26080115 | 0:bf7b9fba3924 | 304 | /* We have an entire HTTP header line in s.httpheaderline, so |
frank26080115 | 0:bf7b9fba3924 | 305 | we parse it. */ |
frank26080115 | 0:bf7b9fba3924 | 306 | if(s.httpheaderline[0] == ISO_cr) { |
frank26080115 | 0:bf7b9fba3924 | 307 | /* This was the last header line (i.e., and empty "\r\n"), so |
frank26080115 | 0:bf7b9fba3924 | 308 | we are done with the headers and proceed with the actual |
frank26080115 | 0:bf7b9fba3924 | 309 | data. */ |
frank26080115 | 0:bf7b9fba3924 | 310 | s.state = WEBCLIENT_STATE_DATA; |
frank26080115 | 0:bf7b9fba3924 | 311 | return len; |
frank26080115 | 0:bf7b9fba3924 | 312 | } |
frank26080115 | 0:bf7b9fba3924 | 313 | |
frank26080115 | 0:bf7b9fba3924 | 314 | s.httpheaderline[s.httpheaderlineptr - 1] = 0; |
frank26080115 | 0:bf7b9fba3924 | 315 | /* Check for specific HTTP header fields. */ |
frank26080115 | 0:bf7b9fba3924 | 316 | if(casecmp(s.httpheaderline, http_content_type, |
frank26080115 | 0:bf7b9fba3924 | 317 | sizeof(http_content_type) - 1) == 0) { |
frank26080115 | 0:bf7b9fba3924 | 318 | /* Found Content-type field. */ |
frank26080115 | 0:bf7b9fba3924 | 319 | cptr = strchr(s.httpheaderline, ';'); |
frank26080115 | 0:bf7b9fba3924 | 320 | if(cptr != NULL) { |
frank26080115 | 0:bf7b9fba3924 | 321 | *cptr = 0; |
frank26080115 | 0:bf7b9fba3924 | 322 | } |
frank26080115 | 0:bf7b9fba3924 | 323 | strncpy(s.mimetype, s.httpheaderline + |
frank26080115 | 0:bf7b9fba3924 | 324 | sizeof(http_content_type) - 1, sizeof(s.mimetype)); |
frank26080115 | 0:bf7b9fba3924 | 325 | } else if(casecmp(s.httpheaderline, http_location, |
frank26080115 | 0:bf7b9fba3924 | 326 | sizeof(http_location) - 1) == 0) { |
frank26080115 | 0:bf7b9fba3924 | 327 | cptr = s.httpheaderline + |
frank26080115 | 0:bf7b9fba3924 | 328 | sizeof(http_location) - 1; |
frank26080115 | 0:bf7b9fba3924 | 329 | |
frank26080115 | 0:bf7b9fba3924 | 330 | if(strncmp(cptr, http_http, 7) == 0) { |
frank26080115 | 0:bf7b9fba3924 | 331 | cptr += 7; |
frank26080115 | 0:bf7b9fba3924 | 332 | for(i = 0; i < s.httpheaderlineptr - 7; ++i) { |
frank26080115 | 0:bf7b9fba3924 | 333 | if(*cptr == 0 || |
frank26080115 | 0:bf7b9fba3924 | 334 | *cptr == '/' || |
frank26080115 | 0:bf7b9fba3924 | 335 | *cptr == ' ' || |
frank26080115 | 0:bf7b9fba3924 | 336 | *cptr == ':') { |
frank26080115 | 0:bf7b9fba3924 | 337 | s.host[i] = 0; |
frank26080115 | 0:bf7b9fba3924 | 338 | break; |
frank26080115 | 0:bf7b9fba3924 | 339 | } |
frank26080115 | 0:bf7b9fba3924 | 340 | s.host[i] = *cptr; |
frank26080115 | 0:bf7b9fba3924 | 341 | ++cptr; |
frank26080115 | 0:bf7b9fba3924 | 342 | } |
frank26080115 | 0:bf7b9fba3924 | 343 | } |
frank26080115 | 0:bf7b9fba3924 | 344 | strncpy(s.file, cptr, sizeof(s.file)); |
frank26080115 | 0:bf7b9fba3924 | 345 | /* s.file[s.httpheaderlineptr - i] = 0;*/ |
frank26080115 | 0:bf7b9fba3924 | 346 | } |
frank26080115 | 0:bf7b9fba3924 | 347 | |
frank26080115 | 0:bf7b9fba3924 | 348 | |
frank26080115 | 0:bf7b9fba3924 | 349 | /* We're done parsing, so we reset the pointer and start the |
frank26080115 | 0:bf7b9fba3924 | 350 | next line. */ |
frank26080115 | 0:bf7b9fba3924 | 351 | s.httpheaderlineptr = 0; |
frank26080115 | 0:bf7b9fba3924 | 352 | } else { |
frank26080115 | 0:bf7b9fba3924 | 353 | ++s.httpheaderlineptr; |
frank26080115 | 0:bf7b9fba3924 | 354 | } |
frank26080115 | 0:bf7b9fba3924 | 355 | } |
frank26080115 | 0:bf7b9fba3924 | 356 | return len; |
frank26080115 | 0:bf7b9fba3924 | 357 | } |
frank26080115 | 0:bf7b9fba3924 | 358 | /*-----------------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 359 | static void |
frank26080115 | 0:bf7b9fba3924 | 360 | newdata(void) |
frank26080115 | 0:bf7b9fba3924 | 361 | { |
frank26080115 | 0:bf7b9fba3924 | 362 | u16_t len; |
frank26080115 | 0:bf7b9fba3924 | 363 | |
frank26080115 | 0:bf7b9fba3924 | 364 | len = uip_datalen(); |
frank26080115 | 0:bf7b9fba3924 | 365 | |
frank26080115 | 0:bf7b9fba3924 | 366 | if(s.state == WEBCLIENT_STATE_STATUSLINE) { |
frank26080115 | 0:bf7b9fba3924 | 367 | len = parse_statusline(len); |
frank26080115 | 0:bf7b9fba3924 | 368 | } |
frank26080115 | 0:bf7b9fba3924 | 369 | |
frank26080115 | 0:bf7b9fba3924 | 370 | if(s.state == WEBCLIENT_STATE_HEADERS && len > 0) { |
frank26080115 | 0:bf7b9fba3924 | 371 | len = parse_headers(len); |
frank26080115 | 0:bf7b9fba3924 | 372 | } |
frank26080115 | 0:bf7b9fba3924 | 373 | |
frank26080115 | 0:bf7b9fba3924 | 374 | if(len > 0 && s.state == WEBCLIENT_STATE_DATA && |
frank26080115 | 0:bf7b9fba3924 | 375 | s.httpflag != HTTPFLAG_MOVED) { |
frank26080115 | 0:bf7b9fba3924 | 376 | webclient_datahandler((char *)uip_appdata, len); |
frank26080115 | 0:bf7b9fba3924 | 377 | } |
frank26080115 | 0:bf7b9fba3924 | 378 | } |
frank26080115 | 0:bf7b9fba3924 | 379 | /*-----------------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 380 | void |
frank26080115 | 0:bf7b9fba3924 | 381 | webclient_appcall(void) |
frank26080115 | 0:bf7b9fba3924 | 382 | { |
frank26080115 | 0:bf7b9fba3924 | 383 | if(uip_connected()) { |
frank26080115 | 0:bf7b9fba3924 | 384 | s.timer = 0; |
frank26080115 | 0:bf7b9fba3924 | 385 | s.state = WEBCLIENT_STATE_STATUSLINE; |
frank26080115 | 0:bf7b9fba3924 | 386 | senddata(); |
frank26080115 | 0:bf7b9fba3924 | 387 | webclient_connected(); |
frank26080115 | 0:bf7b9fba3924 | 388 | return; |
frank26080115 | 0:bf7b9fba3924 | 389 | } |
frank26080115 | 0:bf7b9fba3924 | 390 | |
frank26080115 | 0:bf7b9fba3924 | 391 | if(s.state == WEBCLIENT_STATE_CLOSE) { |
frank26080115 | 0:bf7b9fba3924 | 392 | webclient_closed(); |
frank26080115 | 0:bf7b9fba3924 | 393 | uip_abort(); |
frank26080115 | 0:bf7b9fba3924 | 394 | return; |
frank26080115 | 0:bf7b9fba3924 | 395 | } |
frank26080115 | 0:bf7b9fba3924 | 396 | |
frank26080115 | 0:bf7b9fba3924 | 397 | if(uip_aborted()) { |
frank26080115 | 0:bf7b9fba3924 | 398 | webclient_aborted(); |
frank26080115 | 0:bf7b9fba3924 | 399 | } |
frank26080115 | 0:bf7b9fba3924 | 400 | if(uip_timedout()) { |
frank26080115 | 0:bf7b9fba3924 | 401 | webclient_timedout(); |
frank26080115 | 0:bf7b9fba3924 | 402 | } |
frank26080115 | 0:bf7b9fba3924 | 403 | |
frank26080115 | 0:bf7b9fba3924 | 404 | |
frank26080115 | 0:bf7b9fba3924 | 405 | if(uip_acked()) { |
frank26080115 | 0:bf7b9fba3924 | 406 | s.timer = 0; |
frank26080115 | 0:bf7b9fba3924 | 407 | acked(); |
frank26080115 | 0:bf7b9fba3924 | 408 | } |
frank26080115 | 0:bf7b9fba3924 | 409 | if(uip_newdata()) { |
frank26080115 | 0:bf7b9fba3924 | 410 | s.timer = 0; |
frank26080115 | 0:bf7b9fba3924 | 411 | newdata(); |
frank26080115 | 0:bf7b9fba3924 | 412 | } |
frank26080115 | 0:bf7b9fba3924 | 413 | if(uip_rexmit() || |
frank26080115 | 0:bf7b9fba3924 | 414 | uip_newdata() || |
frank26080115 | 0:bf7b9fba3924 | 415 | uip_acked()) { |
frank26080115 | 0:bf7b9fba3924 | 416 | senddata(); |
frank26080115 | 0:bf7b9fba3924 | 417 | } else if(uip_poll()) { |
frank26080115 | 0:bf7b9fba3924 | 418 | ++s.timer; |
frank26080115 | 0:bf7b9fba3924 | 419 | if(s.timer == WEBCLIENT_TIMEOUT) { |
frank26080115 | 0:bf7b9fba3924 | 420 | webclient_timedout(); |
frank26080115 | 0:bf7b9fba3924 | 421 | uip_abort(); |
frank26080115 | 0:bf7b9fba3924 | 422 | return; |
frank26080115 | 0:bf7b9fba3924 | 423 | } |
frank26080115 | 0:bf7b9fba3924 | 424 | /* senddata();*/ |
frank26080115 | 0:bf7b9fba3924 | 425 | } |
frank26080115 | 0:bf7b9fba3924 | 426 | |
frank26080115 | 0:bf7b9fba3924 | 427 | if(uip_closed()) { |
frank26080115 | 0:bf7b9fba3924 | 428 | if(s.httpflag != HTTPFLAG_MOVED) { |
frank26080115 | 0:bf7b9fba3924 | 429 | /* Send NULL data to signal EOF. */ |
frank26080115 | 0:bf7b9fba3924 | 430 | webclient_datahandler(NULL, 0); |
frank26080115 | 0:bf7b9fba3924 | 431 | } else { |
frank26080115 | 0:bf7b9fba3924 | 432 | if(resolv_lookup(s.host) == NULL) { |
frank26080115 | 0:bf7b9fba3924 | 433 | resolv_query(s.host); |
frank26080115 | 0:bf7b9fba3924 | 434 | } |
frank26080115 | 0:bf7b9fba3924 | 435 | webclient_get(s.host, s.port, s.file); |
frank26080115 | 0:bf7b9fba3924 | 436 | } |
frank26080115 | 0:bf7b9fba3924 | 437 | } |
frank26080115 | 0:bf7b9fba3924 | 438 | } |
frank26080115 | 0:bf7b9fba3924 | 439 | /*-----------------------------------------------------------------------------------*/ |
frank26080115 | 0:bf7b9fba3924 | 440 | |
frank26080115 | 0:bf7b9fba3924 | 441 | /** @} */ |
frank26080115 | 0:bf7b9fba3924 | 442 | /** @} */ |
frank26080115 | 0:bf7b9fba3924 | 443 | /** @} */ |