2 * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
\r
3 * All rights reserved.
\r
5 * Redistribution and use in source and binary forms, with or without modification,
\r
6 * are permitted provided that the following conditions are met:
\r
8 * 1. Redistributions of source code must retain the above copyright notice,
\r
9 * this list of conditions and the following disclaimer.
\r
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
\r
11 * this list of conditions and the following disclaimer in the documentation
\r
12 * and/or other materials provided with the distribution.
\r
13 * 3. The name of the author may not be used to endorse or promote products
\r
14 * derived from this software without specific prior written permission.
\r
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
\r
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
\r
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
\r
19 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
\r
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
\r
21 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
\r
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
\r
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
\r
24 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
\r
27 * This file is part of the lwIP TCP/IP stack.
\r
29 * Author: Adam Dunkels <adam@sics.se>
\r
33 #include "lwip/debug.h"
\r
34 #include "lwip/stats.h"
\r
36 #include "lwip/tcp.h"
\r
49 /*-----------------------------------------------------------------------------------*/
\r
50 void conn_err(void *arg, err_t err)
\r
52 struct http_state *hs;
\r
57 /*-----------------------------------------------------------------------------------*/
\r
59 close_conn(struct tcp_pcb *pcb, struct http_state *hs)
\r
62 tcp_sent(pcb, NULL);
\r
63 tcp_recv(pcb, NULL);
\r
67 /*-----------------------------------------------------------------------------------*/
\r
69 send_data(struct tcp_pcb *pcb, struct http_state *hs)
\r
74 /* We cannot send more data than space available in the send
\r
76 if (tcp_sndbuf(pcb) < hs->left) {
\r
77 len = tcp_sndbuf(pcb);
\r
83 err = tcp_write(pcb, hs->file, len, 0);
\r
84 if (err == ERR_MEM) {
\r
87 } while (err == ERR_MEM && len > 1);
\r
89 if (err == ERR_OK) {
\r
93 printf("send_data: error %s len %d %d\n", lwip_strerr(err), len, tcp_sndbuf(pcb));*/
\r
96 /*-----------------------------------------------------------------------------------*/
\r
97 err_t http_poll(void *arg, struct tcp_pcb *pcb)
\r
99 struct http_state *hs;
\r
103 /* printf("Polll\n");*/
\r
105 /* printf("Null, close\n");*/
\r
110 if (hs->retries == 4) {
\r
114 send_data(pcb, hs);
\r
119 /*-----------------------------------------------------------------------------------*/
\r
120 err_t http_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
\r
122 struct http_state *hs;
\r
128 if (hs->left > 0) {
\r
129 send_data(pcb, hs);
\r
131 close_conn(pcb, hs);
\r
136 /*-----------------------------------------------------------------------------------*/
\r
137 err_t http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
\r
141 struct fs_file file;
\r
142 struct http_state *hs;
\r
146 if (err == ERR_OK && p != NULL) {
\r
148 /* Inform TCP that we have taken the data. */
\r
149 tcp_recved(pcb, p->tot_len);
\r
151 if (hs->file == NULL) {
\r
154 if (strncmp(data, "GET ", 4) == 0) {
\r
155 for(i = 0; i < 40; i++) {
\r
156 if (((char *)data + 4)[i] == ' ' ||
\r
157 ((char *)data + 4)[i] == '\r' ||
\r
158 ((char *)data + 4)[i] == '\n') {
\r
159 ((char *)data + 4)[i] = 0;
\r
163 if (*(char *)(data + 4) == '/' &&
\r
164 *(char *)(data + 5) == 0) {
\r
165 fs_open("/index.html", &file);
\r
168 if (!fs_open((char *)data + 4, &file)) {
\r
169 fs_open("/404.html", &file);
\r
172 hs->file = file.data;
\r
173 hs->left = file.len;
\r
174 /* printf("data %p len %ld\n", hs->file, hs->left);*/
\r
177 send_data(pcb, hs);
\r
179 /* Tell TCP that we wish be to informed of data that has been
\r
180 successfully sent by a call to the http_sent() function. */
\r
181 tcp_sent(pcb, http_sent);
\r
184 close_conn(pcb, hs);
\r
191 if (err == ERR_OK && p == NULL) {
\r
192 close_conn(pcb, hs);
\r
196 /*-----------------------------------------------------------------------------------*/
\r
197 err_t http_accept(void *arg, struct tcp_pcb *pcb, err_t err)
\r
199 struct http_state *hs;
\r
201 tcp_setprio(pcb, TCP_PRIO_MIN);
\r
203 /* Allocate memory for the structure that holds the state of the
\r
205 hs = mem_malloc(sizeof(struct http_state));
\r
208 // printf("http_accept: Out of memory\n");
\r
212 /* Initialize the structure. */
\r
217 /* Tell TCP that this is the structure we wish to be passed for our
\r
222 /* Tell TCP that we wish to be informed of incoming data by a call
\r
223 to the http_recv() function. */
\r
224 tcp_recv(pcb, http_recv);
\r
226 tcp_err(pcb, conn_err);
\r
228 tcp_poll(pcb, http_poll, 4);
\r
233 /*-----------------------------------------------------------------------------------*/
\r
234 void httpd_init(void)
\r
236 struct tcp_pcb *pcb;
\r
239 tcp_bind(pcb, NULL, 80);
\r
240 pcb = tcp_listen(pcb);
\r
241 tcp_accept(pcb, http_accept);
\r
243 /*-----------------------------------------------------------------------------------*/
\r