diff --git a/apps/webserver-nano/Makefile.webserver-nano b/apps/webserver-nano/Makefile.webserver-nano new file mode 100644 index 000000000..1929865ec --- /dev/null +++ b/apps/webserver-nano/Makefile.webserver-nano @@ -0,0 +1,2 @@ +webserver-nano_src = webserver-nogui.c httpd.c psock.c memb.c httpd-fs.c httpd-cgi.c +webserver-nano_dsc = webserver-dsc.c diff --git a/apps/webserver-nano/httpd-cfs.c b/apps/webserver-nano/httpd-cfs.c new file mode 100644 index 000000000..fb6fb56b3 --- /dev/null +++ b/apps/webserver-nano/httpd-cfs.c @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2004, 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. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: httpd-cfs.c,v 1.26 2011/01/25 20:13:41 oliverschmidt Exp $ + */ + +#include +#ifndef HAVE_SNPRINTF +int snprintf(char *str, size_t size, const char *format, ...); +#endif /* HAVE_SNPRINTF */ +#include + +#include "contiki-net.h" + +#include "webserver.h" +#include "cfs/cfs.h" +#include "lib/petsciiconv.h" +#include "http-strings.h" +#include "urlconv.h" + +#include "httpd-cfs.h" + +#ifndef WEBSERVER_CONF_CFS_CONNS +#define CONNS UIP_CONNS +#else /* WEBSERVER_CONF_CFS_CONNS */ +#define CONNS WEBSERVER_CONF_CFS_CONNS +#endif /* WEBSERVER_CONF_CFS_CONNS */ + +#ifndef WEBSERVER_CONF_CFS_URLCONV +#define URLCONV 1 +#else /* WEBSERVER_CONF_CFS_URLCONV */ +#define URLCONV WEBSERVER_CONF_CFS_URLCONV +#endif /* WEBSERVER_CONF_CFS_URLCONV */ + +#define STATE_WAITING 0 +#define STATE_OUTPUT 1 + +#define SEND_STRING(s, str) PSOCK_SEND(s, (uint8_t *)str, strlen(str)) +MEMB(conns, struct httpd_state, CONNS); + +#define ISO_nl 0x0a +#define ISO_space 0x20 +#define ISO_period 0x2e +#define ISO_slash 0x2f + +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(send_file(struct httpd_state *s)) +{ + PSOCK_BEGIN(&s->sout); + + do { + /* Read data from file system into buffer */ + s->len = cfs_read(s->fd, s->outputbuf, sizeof(s->outputbuf)); + + /* If there is data in the buffer, send it */ + if(s->len > 0) { + PSOCK_SEND(&s->sout, (uint8_t *)s->outputbuf, s->len); + } else { + break; + } + } while(s->len > 0); + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(send_string(struct httpd_state *s, const char *str)) +{ + PSOCK_BEGIN(&s->sout); + + SEND_STRING(&s->sout, str); + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(send_headers(struct httpd_state *s, const char *statushdr)) +{ + const char *ptr; + + PSOCK_BEGIN(&s->sout); + + SEND_STRING(&s->sout, statushdr); + + ptr = strrchr(s->filename, ISO_period); + if(ptr == NULL) { + ptr = http_content_type_plain; + } else if(strcmp(http_htm, ptr) == 0) { + ptr = http_content_type_html; + } else if(strcmp(http_css, ptr) == 0) { + ptr = http_content_type_css; + } else if(strcmp(http_png, ptr) == 0) { + ptr = http_content_type_png; + } else if(strcmp(http_gif, ptr) == 0) { + ptr = http_content_type_gif; + } else if(strcmp(http_jpg, ptr) == 0) { + ptr = http_content_type_jpg; + } else { + ptr = http_content_type_binary; + } + SEND_STRING(&s->sout, ptr); + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(handle_output(struct httpd_state *s)) +{ + PT_BEGIN(&s->outputpt); + + petsciiconv_topetscii(s->filename, sizeof(s->filename)); + s->fd = cfs_open(&s->filename[1], CFS_READ); + petsciiconv_toascii(s->filename, sizeof(s->filename)); + if(s->fd < 0) { + strcpy(s->filename, "/notfound.htm"); + s->fd = cfs_open(&s->filename[1], CFS_READ); + petsciiconv_toascii(s->filename, sizeof(s->filename)); + PT_WAIT_THREAD(&s->outputpt, + send_headers(s, http_header_404)); + if(s->fd < 0) { + PT_WAIT_THREAD(&s->outputpt, + send_string(s, "not found")); + uip_close(); + webserver_log_file(&uip_conn->ripaddr, "404 (no notfound.htm)"); + PT_EXIT(&s->outputpt); + } + webserver_log_file(&uip_conn->ripaddr, "404 - notfound.htm"); + } else { + PT_WAIT_THREAD(&s->outputpt, + send_headers(s, http_header_200)); + } + PT_WAIT_THREAD(&s->outputpt, send_file(s)); + cfs_close(s->fd); + s->fd = -1; + PSOCK_CLOSE(&s->sout); + PT_END(&s->outputpt); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(handle_input(struct httpd_state *s)) +{ + PSOCK_BEGIN(&s->sin); + + PSOCK_READTO(&s->sin, ISO_space); + + if(strncmp(s->inputbuf, http_get, 4) != 0) { + PSOCK_CLOSE_EXIT(&s->sin); + } + PSOCK_READTO(&s->sin, ISO_space); + + if(s->inputbuf[0] != ISO_slash) { + PSOCK_CLOSE_EXIT(&s->sin); + } + +#if URLCONV + s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0; + urlconv_tofilename(s->filename, s->inputbuf, sizeof(s->filename)); +#else /* URLCONV */ + if(s->inputbuf[1] == ISO_space) { + strncpy(s->filename, http_index_htm, sizeof(s->filename)); + } else { + s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0; + strncpy(s->filename, s->inputbuf, sizeof(s->filename)); + } +#endif /* URLCONV */ + + petsciiconv_topetscii(s->filename, sizeof(s->filename)); + webserver_log_file(&uip_conn->ripaddr, s->filename); + petsciiconv_toascii(s->filename, sizeof(s->filename)); + s->state = STATE_OUTPUT; + + while(1) { + PSOCK_READTO(&s->sin, ISO_nl); + + if(strncmp(s->inputbuf, http_referer, 8) == 0) { + s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0; + petsciiconv_topetscii(s->inputbuf, PSOCK_DATALEN(&s->sin) - 2); + webserver_log(s->inputbuf); + } + } + + PSOCK_END(&s->sin); +} +/*---------------------------------------------------------------------------*/ +static void +handle_connection(struct httpd_state *s) +{ + handle_input(s); + if(s->state == STATE_OUTPUT) { + handle_output(s); + } +} +/*---------------------------------------------------------------------------*/ +void +httpd_appcall(void *state) +{ + struct httpd_state *s = (struct httpd_state *)state; + + if(uip_closed() || uip_aborted() || uip_timedout()) { + if(s != NULL) { + if(s->fd >= 0) { + cfs_close(s->fd); + s->fd = -1; + } + memb_free(&conns, s); + } + } else if(uip_connected()) { + s = (struct httpd_state *)memb_alloc(&conns); + if(s == NULL) { + uip_abort(); + webserver_log_file(&uip_conn->ripaddr, "reset (no memory block)"); + return; + } + tcp_markconn(uip_conn, s); + PSOCK_INIT(&s->sin, (uint8_t *)s->inputbuf, sizeof(s->inputbuf) - 1); + PSOCK_INIT(&s->sout, (uint8_t *)s->inputbuf, sizeof(s->inputbuf) - 1); + PT_INIT(&s->outputpt); + s->fd = -1; + s->state = STATE_WAITING; + timer_set(&s->timer, CLOCK_SECOND * 10); + handle_connection(s); + } else if(s != NULL) { + if(uip_poll()) { + if(timer_expired(&s->timer)) { + uip_abort(); + if(s->fd >= 0) { + cfs_close(s->fd); + s->fd = -1; + } + memb_free(&conns, s); + webserver_log_file(&uip_conn->ripaddr, "reset (timeout)"); + } + } else { + timer_restart(&s->timer); + } + handle_connection(s); + } else { + uip_abort(); + } +} +/*---------------------------------------------------------------------------*/ +void +httpd_init(void) +{ + tcp_listen(UIP_HTONS(80)); + memb_init(&conns); +#if URLCONV + urlconv_init(); +#endif /* URLCONV */ +} +/*---------------------------------------------------------------------------*/ diff --git a/apps/webserver-nano/httpd-cfs.h b/apps/webserver-nano/httpd-cfs.h new file mode 100644 index 000000000..8f8fc1203 --- /dev/null +++ b/apps/webserver-nano/httpd-cfs.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2001, 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: httpd-cfs.h,v 1.3 2010/04/11 20:10:12 oliverschmidt Exp $ + * + */ + +#ifndef __HTTPD_CFS_H__ +#define __HTTPD_CFS_H__ + +#include "contiki-net.h" + +#ifndef WEBSERVER_CONF_CFS_PATHLEN +#define HTTPD_PATHLEN 80 +#else /* WEBSERVER_CONF_CFS_CONNS */ +#define HTTPD_PATHLEN WEBSERVER_CONF_CFS_PATHLEN +#endif /* WEBSERVER_CONF_CFS_CONNS */ + +struct httpd_state { + struct timer timer; + struct psock sin, sout; + struct pt outputpt; + char inputbuf[HTTPD_PATHLEN + 30]; + char outputbuf[UIP_TCP_MSS]; + char filename[HTTPD_PATHLEN]; + char state; + int fd; + int len; +}; + + +void httpd_init(void); +void httpd_appcall(void *state); + +#endif /* __HTTPD_CFS_H__ */ diff --git a/apps/webserver-nano/httpd-cgi.c b/apps/webserver-nano/httpd-cgi.c new file mode 100644 index 000000000..b28e8cffe --- /dev/null +++ b/apps/webserver-nano/httpd-cgi.c @@ -0,0 +1,880 @@ +/* + * Copyright (c) 2001, 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. + * + * + */ +/* Line endings in git repository are LF instead of CR-LF ? */ +/* + * This file includes functions that are called by the web server + * scripts. The functions takes no argument, and the return value is + * interpreted as follows. A zero means that the function did not + * complete and should be invoked for the next packet as well. A + * non-zero value indicates that the function has completed and that + * the web server should move along to the next script line. + * + */ + +#include +#include + +#include "contiki-net.h" +#include "httpd.h" +#include "httpd-cgi.h" +#include "httpd-fs.h" +#include "httpd-fsdata.h" +#include "lib/petsciiconv.h" + +#include "sensors.h" + +/* RADIOSTATS must also be set in clock.c and the radio driver */ +#if RF230BB +#define RADIOSTATS 1 +#endif + +#if WEBSERVER_CONF_CGI +static struct httpd_cgi_call *calls = NULL; +/*cgi function names*/ +#if WEBSERVER_CONF_HEADER +static const char hdr_name[] HTTPD_STRING_ATTR = "header"; +#endif +#if WEBSERVER_CONF_FILESTATS +static const char file_name[] HTTPD_STRING_ATTR = "file-stats"; +#endif +#if WEBSERVER_CONF_TCPSTATS +static const char tcp_name[] HTTPD_STRING_ATTR = "tcp-connections"; +#endif +#if WEBSERVER_CONF_PROCESSES +static const char proc_name[] HTTPD_STRING_ATTR = "processes"; +#endif +#if WEBSERVER_CONF_SENSORS +static const char sensor_name[] HTTPD_STRING_ATTR = "sensors"; +#endif +#if WEBSERVER_CONF_ADDRESSES +static const char adrs_name[] HTTPD_STRING_ATTR = "addresses"; +#endif +#if WEBSERVER_CONF_NEIGHBORS +static const char nbrs_name[] HTTPD_STRING_ATTR = "neighbors"; +#endif +#if WEBSERVER_CONF_ROUTES +static const char rtes_name[] HTTPD_STRING_ATTR = "routes"; +#endif +#if WEBSERVER_CONF_TICTACTOE +static const char tictac_name[] HTTPD_STRING_ATTR = "tictac"; +#endif + +/*Process states for processes cgi*/ +#endif +#if WEBSERVER_CONF_PROCESSES || WEBSERVER_CONF_TCPSTATS +static const char closed[] HTTPD_STRING_ATTR = "CLOSED"; +static const char syn_rcvd[] HTTPD_STRING_ATTR = "SYN-RCVD"; +static const char syn_sent[] HTTPD_STRING_ATTR = "SYN-SENT"; +static const char established[] HTTPD_STRING_ATTR = "ESTABLISHED"; +static const char fin_wait_1[] HTTPD_STRING_ATTR = "FIN-WAIT-1"; +static const char fin_wait_2[] HTTPD_STRING_ATTR = "FIN-WAIT-2"; +static const char closing[] HTTPD_STRING_ATTR = "CLOSING"; +static const char time_wait[] HTTPD_STRING_ATTR = "TIME-WAIT"; +static const char last_ack[] HTTPD_STRING_ATTR = "LAST-ACK"; +static const char none[] HTTPD_STRING_ATTR = "NONE"; +static const char running[] HTTPD_STRING_ATTR = "RUNNING"; +static const char called[] HTTPD_STRING_ATTR = "CALLED"; +static const char *states[] = { + closed, + syn_rcvd, + syn_sent, + established, + fin_wait_1, + fin_wait_2, + closing, + time_wait, + last_ack, + none, + running, + called}; +#endif + +#if WEBSERVER_CONF_SENSORS + static char sensor_temperature[14]="Not Available"; + static char sensor_extvoltage[14]="Not Available"; + static unsigned long last_tempupdate;//,last_extvoltageupdate; +// extern unsigned long seconds, sleepseconds; +#if RADIOSTATS + extern unsigned long radioontime; + static unsigned long savedradioontime; + extern uint8_t RF230_radio_on, rf230_last_rssi; + extern uint16_t RF230_sendpackets,RF230_receivepackets,RF230_sendfail,RF230_receivefail; +#endif +#endif + +#if 0 +void +web_set_temp(char *s) +{ + strcpy(sensor_temperature, s); +// printf_P(PSTR("got temp")); + last_tempupdate=seconds; +} +void +web_set_voltage(char *s) +{ + strcpy(sensor_extvoltage, s); +// printf_P(PSTR("got volts")); + last_extvoltageupdate=seconds; +} +#endif + +#if WEBSERVER_CONF_CGI +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(nullfunction(struct httpd_state *s, char *ptr)) +{ + PSOCK_BEGIN(&s->sout); + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +httpd_cgifunction +httpd_cgi(char *name) +{ + struct httpd_cgi_call *f; + + /* Find the matching name in the table, return the function. */ + for(f = calls; f != NULL; f = f->next) { + if(httpd_strncmp(name, f->name, httpd_strlen(f->name)) == 0) { + return f->function; + } + } + return nullfunction; +} +#if WEBSERVER_CONF_HEADER +/*---------------------------------------------------------------------------*/ +static unsigned short +generate_header(void *arg) +{ + unsigned short numprinted=0; +#if WEBSERVER_CONF_HEADER_W3C + static const char httpd_cgi_headerw[] HTTPD_STRING_ATTR = ""; + numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_headerw); +#endif +#if WEBSERVER_CONF_HEADER_ICON + static const char httpd_cgi_header1[] HTTPD_STRING_ATTR = "Contiki-nano"; +#else + static const char httpd_cgi_header1[] HTTPD_STRING_ATTR = "Contiki-nano"; +#endif + numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_header1); + +#if WEBSERVER_CONF_HEADER_MENU + static const char httpd_cgi_headerm1[] HTTPD_STRING_ATTR = "
Front page";
+  numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_headerm1);
+#if WEBSERVER_CONF_SENSORS
+  static const char httpd_cgi_headerm2[] HTTPD_STRING_ATTR = "|Status";
+  numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_headerm2);
+#endif
+#if WEBSERVER_CONF_TCPSTATS
+  static const char httpd_cgi_headerm3[] HTTPD_STRING_ATTR = "|Network connections";
+  numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_headerm3);
+#endif
+#if WEBSERVER_CONF_PROCESSES
+  static const char httpd_cgi_headerm4[] HTTPD_STRING_ATTR = "|System processes";
+  numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_headerm4);
+#endif
+#if WEBSERVER_CONF_FILESTATS
+  static const char httpd_cgi_headerm5[] HTTPD_STRING_ATTR = "|File statistics";
+  numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_headerm5);
+#endif
+#if WEBSERVER_CONF_TICTACTOE
+  static const char httpd_cgi_headerm6[] HTTPD_STRING_ATTR = "|TicTacToe";
+  numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_headerm6);
+#endif
+  static const char httpd_cgi_headerme[] HTTPD_STRING_ATTR = "
"; + numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_headerme); +#endif /* WEBSERVER_CONF_MENU */ + return numprinted; +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(header(struct httpd_state *s, char *ptr)) +{ + + PSOCK_BEGIN(&s->sout); + + PSOCK_GENERATOR_SEND(&s->sout, generate_header, (void *) ptr); + + PSOCK_END(&s->sout); +} +#endif /* WEBSERVER_CONF_HEADER */ + +#if WEBSERVER_CONF_FILESTATS +static char *thisfilename; //todo move to s->ptr +/*---------------------------------------------------------------------------*/ +static unsigned short +generate_file_stats(void *arg) +{ + static const char httpd_cgi_filestat1[] HTTPD_STRING_ATTR = "



This page has been sent %u times"; + static const char httpd_cgi_filestat2[] HTTPD_STRING_ATTR = "%s%d"; + static const char httpd_cgi_filestat3[] HTTPD_STRING_ATTR = "%5u"; + char tmp[20]; + struct httpd_fsdata_file_noconst *f,fram; + u16_t i; + unsigned short numprinted; + /* Transfer arg from whichever flash that contains the html file to RAM */ + httpd_fs_cpy(&tmp, (char *)arg, 20); + + /* Count for this page, with common page footer */ + if (tmp[0]=='.') { + numprinted=httpd_snprintf((char *)uip_appdata, uip_mss(), httpd_cgi_filestat1, httpd_fs_open(thisfilename, 0)); + + /* Count for all files */ + /* Note buffer will overflow if there are too many files! */ + } else if (tmp[0]=='*') { + i=0;numprinted=0; + for(f = (struct httpd_fsdata_file_noconst *)httpd_fs_get_root(); + f != NULL; + f = (struct httpd_fsdata_file_noconst *)fram.next) { + + /* Get the linked list file entry into RAM from from wherever it is*/ + httpd_memcpy(&fram,f,sizeof(fram)); + /* Get the file name from whatever memory it is in */ + httpd_fs_cpy(&tmp, fram.name, sizeof(tmp)); +#if WEBSERVER_CONF_FILESTATS==2 + numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_filestat2, tmp, tmp, f->count); +#else + numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_filestat2, tmp, tmp, httpd_filecount[i]); +#endif + i++; + } + + /* Count for specified file */ + } else { + numprinted=httpd_snprintf((char *)uip_appdata, uip_mss(), httpd_cgi_filestat3, httpd_fs_open(tmp, 0)); + } + return numprinted; +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(file_stats(struct httpd_state *s, char *ptr)) +{ + + PSOCK_BEGIN(&s->sout); +//printf("s->filename is %c%c%c%c%c%c",s->filename[0],s->filename[1],s->filename[2],s->filename[3],s->filename[4],s->filename[5]); +//printf("s->filename string is %s",s->filename); + thisfilename=&s->filename[0]; //temporary way to pass filename to generate_file_stats + +// printf("thisfilename is %s",thisfilename); //minimal net wants this + + PSOCK_GENERATOR_SEND(&s->sout, generate_file_stats, (void *) ptr); + + PSOCK_END(&s->sout); +} +#endif /* WEBSERVER_CONF_FILESTATS*/ + +#if WEBSERVER_CONF_TCPSTATS +/*---------------------------------------------------------------------------*/ +static unsigned short +make_tcp_stats(void *arg) +{ + static const char httpd_cgi_tcpstat1[] HTTPD_STRING_ATTR = "%d"; + static const char httpd_cgi_tcpstat2[] HTTPD_STRING_ATTR = "-%u%s%u%u%c %c\r\n"; + static const char httpd_cgi_tcpstat3[] HTTPD_STRING_ATTR = "[Room for %d more]"; + + struct uip_conn *conn; + struct httpd_state *s = (struct httpd_state *)arg; + char tstate[20]; + uint16_t numprinted; + + if (s->u.count==UIP_CONNS){ + for(numprinted = 0; numprinted < UIP_CONNS; numprinted++ ) { + if((uip_conns[numprinted].tcpstateflags & UIP_TS_MASK) != UIP_CLOSED) s->u.count--; + } + return(httpd_snprintf((char *)uip_appdata, uip_mss(), httpd_cgi_tcpstat3, s->u.count)); + } + + conn = &uip_conns[s->u.count]; + + numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(), httpd_cgi_tcpstat1, uip_htons(conn->lport)); +#if WEBSERVER_CONF_PRINTADDR + numprinted += httpd_cgi_sprint_ip6(conn->ripaddr, uip_appdata + numprinted); +#endif + httpd_strcpy(tstate,states[conn->tcpstateflags & UIP_TS_MASK]); + numprinted += httpd_snprintf((char *)uip_appdata + numprinted, uip_mss() - numprinted, + httpd_cgi_tcpstat2, + uip_htons(conn->rport), + tstate, + conn->nrtx, + conn->timer, + (uip_outstanding(conn))? '*':' ', + (uip_stopped(conn))? '!':' '); + + return numprinted; +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(tcp_stats(struct httpd_state *s, char *ptr)) +{ + + PSOCK_BEGIN(&s->sout); + + s->u.count=UIP_CONNS; + PSOCK_GENERATOR_SEND(&s->sout, make_tcp_stats, s); + + for(s->u.count = 0; s->u.count < UIP_CONNS; ++s->u.count) { + if((uip_conns[s->u.count].tcpstateflags & UIP_TS_MASK) != UIP_CLOSED) { + PSOCK_GENERATOR_SEND(&s->sout, make_tcp_stats, s); + } + } + + PSOCK_END(&s->sout); +} +#endif /* WEBSERVER_CONF_TCPSTATS */ + +#if WEBSERVER_CONF_PROCESSES +/*---------------------------------------------------------------------------*/ +static unsigned short +make_processes(void *p) +{ + static const char httpd_cgi_proc[] HTTPD_STRING_ATTR = "%p%s%p%s\r\n"; + char name[40],tstate[20]; +#if PROCESS_CONF_NO_PROCESS_NAMES + strcpy(name, "Not Available"); +#else + strncpy(name, ((struct process *)p)->name, 40); +#endif + petsciiconv_toascii(name, 40); + httpd_strcpy(tstate,states[9 + ((struct process *)p)->state]); + return httpd_snprintf((char *)uip_appdata, uip_mss(), httpd_cgi_proc, p, name, + // *((char **)&(((struct process *)p)->thread)), + *(char **)(&(((struct process *)p)->thread)), //minimal net + tstate); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(processes(struct httpd_state *s, char *ptr)) +{ + PSOCK_BEGIN(&s->sout); + for(s->u.ptr = PROCESS_LIST(); s->u.ptr != NULL; s->u.ptr = ((struct process *)s->u.ptr)->next) { + PSOCK_GENERATOR_SEND(&s->sout, make_processes, s->u.ptr); + } + PSOCK_END(&s->sout); +} +#endif /* WEBSERVER_CONF_PROCESSES */ + +#if WEBSERVER_CONF_ADDRESSES || WEBSERVER_CONF_NEIGHBORS || WEBSERVER_CONF_ROUTES +static const char httpd_cgi_addrh[] HTTPD_STRING_ATTR = ""; +static const char httpd_cgi_addrf[] HTTPD_STRING_ATTR = "[Room for %u more]"; +static const char httpd_cgi_addrb[] HTTPD_STRING_ATTR = "
"; +static const char httpd_cgi_addrn[] HTTPD_STRING_ATTR = "(none)
"; +#endif + +#if WEBSERVER_CONF_ADDRESSES +/*---------------------------------------------------------------------------*/ +extern uip_ds6_netif_t uip_ds6_if; + +static unsigned short +make_addresses(void *p) +{ +uint8_t i,j=0; +uint16_t numprinted; + numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh); + for (i=0; isout); + + PSOCK_GENERATOR_SEND(&s->sout, make_addresses, s->u.ptr); + + PSOCK_END(&s->sout); +} +#endif /* WEBSERVER_CONF_ADDRESSES */ + +#if WEBSERVER_CONF_NEIGHBORS +extern uip_ds6_nbr_t uip_ds6_nbr_cache[]; +/*---------------------------------------------------------------------------*/ +static unsigned short +make_neighbors(void *p) +{ +uint8_t i,j=0; +uint16_t numprinted; + numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh); + for (i=0; isout); + + PSOCK_GENERATOR_SEND(&s->sout, make_neighbors, s->u.ptr); + + PSOCK_END(&s->sout); +} +#endif + +#if WEBSERVER_CONF_ROUTES +extern uip_ds6_route_t uip_ds6_routing_table[]; +/*---------------------------------------------------------------------------*/ +static unsigned short +make_routes(void *p) +{ +static const char httpd_cgi_rtes1[] HTTPD_STRING_ATTR = "(%u (via "; +static const char httpd_cgi_rtes2[] HTTPD_STRING_ATTR = ") %lus
"; +static const char httpd_cgi_rtes3[] HTTPD_STRING_ATTR = ")
"; +uint8_t i,j=0; +uint16_t numprinted; + numprinted = httpd_snprintf((char *)uip_appdata, uip_mss(),httpd_cgi_addrh); + for (i=0; isout); + + PSOCK_GENERATOR_SEND(&s->sout, make_routes, s->u.ptr); + + PSOCK_END(&s->sout); +} +#endif /* WEBSERVER_CONF_ROUTES */ + +#if WEBSERVER_CONF_SENSORS +/*---------------------------------------------------------------------------*/ +static unsigned short +generate_sensor_readings(void *arg) +{ + uint16_t numprinted; + uint16_t h,m,s; + unsigned long seconds=clock_seconds(); +// uint8_t p1; + static const char httpd_cgi_sensor0[] HTTPD_STRING_ATTR = "[Updated %d seconds ago]

"; + static const char httpd_cgi_sensor1[] HTTPD_STRING_ATTR = "Temperature: %s
"; + static const char httpd_cgi_sensor2[] HTTPD_STRING_ATTR = "Battery: %s
"; +// static const char httpd_cgi_sensr12[] HTTPD_STRING_ATTR = "Temperature: %s Battery: %s
"; + static const char httpd_cgi_sensor3[] HTTPD_STRING_ATTR = "Elapsed timer : %02d:%02d:%02d
"; +// static const char httpd_cgi_sensor4[] HTTPD_STRING_ATTR = "Sleeping time : %02d:%02d:%02d (%d%%)
"; + + numprinted=0; + if (last_tempupdate) { + numprinted =httpd_snprintf((char *)uip_appdata, uip_mss(), httpd_cgi_sensor0,(unsigned int) (seconds-last_tempupdate)); + } + numprinted+=httpd_snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, httpd_cgi_sensor1, sensor_temperature); + +#if 0 +//Measuring AVcc might be useful to check on battery condition but on ext power it's always 3v3 + ADMUX =0x1E; //Select AREF as reference, measure 1.1 volt bandgap reference. +//ADMUX =0x5E; //Select AVCC as reference, measure 1.1 volt bandgap reference. + ADCSRA=0x07; //Enable ADC, not free running, interrupt disabled, clock divider 128 (62 KHz@ 8 MHz) + ADCSRA|=1<sout); + + PSOCK_GENERATOR_SEND(&s->sout, generate_sensor_readings, s); +#if RADIOSTATS + PSOCK_GENERATOR_SEND(&s->sout, generate_radio_stats, s); +#endif + + PSOCK_END(&s->sout); +} +#endif /* WEBSERVER_CONF_SENSORS */ + +#if WEBSERVER_CONF_TICTACTOE +/*---------------------------------------------------------------------------*/ +static uint8_t whowon(char x) { + + if (httpd_query[0]==x) { + if(((httpd_query[1]==x)&&(httpd_query[2]==x)) + || ((httpd_query[4]==x)&&(httpd_query[8]==x)) + || ((httpd_query[3]==x)&&(httpd_query[6]==x))){ + return 1; + } + } + if (httpd_query[1]==x) { + if ((httpd_query[4]==x)&&(httpd_query[7]==x)) { + return 1; + } + } + if (httpd_query[2]==x) { + if(((httpd_query[4]==x)&&(httpd_query[6]==x)) + || ((httpd_query[5]==x)&&(httpd_query[8]==x))){ + return 1; + } + } + if (httpd_query[3]==x) { + if ((httpd_query[4]==x)&&(httpd_query[5]==x)) { + return 1; + } + } + if (httpd_query[6]==x) { + if ((httpd_query[7]==x)&&(httpd_query[8]==x)) { + return 1; + } + } + return 0; +} + +/*---------------------------------------------------------------------------*/ +static unsigned short +make_tictactoe(void *p) +{ + uint8_t i,newgame,iwon,uwon,nx,no; + char me,you,locater; + unsigned short numprinted=0; + + /* If no query string restart game, else put into proper form */ + newgame=0;httpd_query[9]=0; + if ((httpd_query[0]==0)||(httpd_query[0]==' ')) { + newgame=1; + for (i=0;i<9;i++) httpd_query[i]='b'; + } else for (i=0;i<9;i++) { + if (!((httpd_query[i]=='x')||(httpd_query[i]=='o'))) { + httpd_query[i]='b'; + } + } + + /* I am x if I move first, or if number of x's is <= number of o's */ + for (nx=0,no=0,i=0;i<9;i++) { + if (httpd_query[i]=='x') nx++; + else if (httpd_query[i]=='o') no++; + } + if ((no>=nx)&&!newgame) {me='x';you='o';} + else {me='o';you='x';}; + + iwon=whowon(me); + uwon=whowon(you); + + if (newgame||iwon||uwon||(nx+no)>=9) goto showboard; + + /* Make a move */ + if (me=='x') nx++;else no++; + if (httpd_query[4]=='b') httpd_query[4]=me; + else if (httpd_query[0]=='b') httpd_query[0]=me; + else if (httpd_query[2]=='b') httpd_query[2]=me; + else if (httpd_query[6]=='b') httpd_query[6]=me; + else if (httpd_query[8]=='b') httpd_query[8]=me; + else if (httpd_query[1]=='b') httpd_query[1]=me; + else if (httpd_query[3]=='b') httpd_query[3]=me; + else if (httpd_query[5]=='b') httpd_query[5]=me; + else if (httpd_query[7]=='b') httpd_query[7]=me; + + /* Did I win? */ + iwon=whowon(me); + + showboard: + for (i=0;i<9;i++) { + + if (i==4) locater='c'; + else if ((i==1)||(i==7)) locater='v'; + else if ((i==3)||(i==5)) locater='h'; + else locater=0; + + if ((httpd_query[i]=='b')&&(!(iwon||uwon))) { + httpd_query[i]=you; + numprinted+=snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, ""); + if (httpd_query[i]=='b') { + numprinted+=snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, ""); + } + if ((i==2)||(i==5)) { + numprinted+=snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, "
"); + } + } + + if ((nx>(no+1))||(no>(nx+1))) { + numprinted+=snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, "

You cheated!!!

"); + } else if (iwon) { + numprinted+=snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, "

I Win!

"); + } else if (uwon) { + numprinted+=snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, "

You Win!

"); + } else if ((nx+no)==9) { + numprinted+=snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, "

Draw!

"); + } + if (iwon||uwon||((nx+no)==9)) { + numprinted+=snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, "
Play Again"); + } + + /* If new game give option for me to start */ + if ((nx==0)&&(no==0)) { + numprinted+=snprintf((char *)uip_appdata+numprinted, uip_mss()-numprinted, "

Let computer move first"); + } + httpd_query[0]=0; //zero the query string + return numprinted; + +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(tictactoe(struct httpd_state *s, char *ptr)) +{ + PSOCK_BEGIN(&s->sout); + PSOCK_GENERATOR_SEND(&s->sout, make_tictactoe, s); + PSOCK_END(&s->sout); +} +#endif /* WEBSERVER_CONF_TICTACTOE */ + +/*---------------------------------------------------------------------------*/ +void +httpd_cgi_add(struct httpd_cgi_call *c) +{ + struct httpd_cgi_call *l; + + c->next = NULL; + if(calls == NULL) { + calls = c; + } else { + for(l = calls; l->next != NULL; l = l->next); + l->next = c; + } +} +/*---------------------------------------------------------------------------*/ +#if WEBSERVER_CONF_HEADER +HTTPD_CGI_CALL( hdr, hdr_name, header ); +#endif +#if WEBSERVER_CONF_FILESTATS +HTTPD_CGI_CALL( file, file_name, file_stats ); +#endif +#if WEBSERVER_CONF_TCPSTATS +HTTPD_CGI_CALL( tcp, tcp_name, tcp_stats ); +#endif +#if WEBSERVER_CONF_PROCESSES +HTTPD_CGI_CALL( proc, proc_name, processes ); +#endif +#if WEBSERVER_CONF_ADDRESSES +HTTPD_CGI_CALL( adrs, adrs_name, addresses ); +#endif +#if WEBSERVER_CONF_NEIGHBORS +HTTPD_CGI_CALL( nbrs, nbrs_name, neighbors ); +#endif +#if WEBSERVER_CONF_ROUTES +HTTPD_CGI_CALL( rtes, rtes_name, routes ); +#endif +#if WEBSERVER_CONF_SENSORS +HTTPD_CGI_CALL(sensors, sensor_name, sensor_readings); +#endif +#if WEBSERVER_CONF_TICTACTOE +HTTPD_CGI_CALL( tictac, tictac_name, tictactoe ); +#endif + +void +httpd_cgi_init(void) +{ +#if WEBSERVER_CONF_HEADER + httpd_cgi_add( &hdr); +#endif +#if WEBSERVER_CONF_FILESTATS + httpd_cgi_add( &file); +#endif +#if WEBSERVER_CONF_TCPSTATS + httpd_cgi_add( &tcp); +#endif +#if WEBSERVER_CONF_PROCESSES + httpd_cgi_add( &proc); +#endif +#if WEBSERVER_CONF_ADDRESSES + httpd_cgi_add( &adrs); +#endif +#if WEBSERVER_CONF_NEIGHBORS + httpd_cgi_add( &nbrs); +#endif +#if WEBSERVER_CONF_ROUTES + httpd_cgi_add( &rtes); +#endif +#if WEBSERVER_CONF_SENSORS + httpd_cgi_add(&sensors); +#endif +#if WEBSERVER_CONF_TICTACTOE + httpd_cgi_add( &tictac); +#endif +} +#endif /* WEBSERVER_CONF_CGI */ + +#if WEBSERVER_CONF_PRINTADDR +/*---------------------------------------------------------------------------*/ +uint8_t httpd_cgi_sprint_ip6(uip_ip6addr_t addr, char * result) +{ + unsigned char zerocnt = 0; + unsigned char numprinted = 0; + char * starting = result; + unsigned char i = 0; + + while (numprinted < 8) + { + //Address is zero, have we used our ability to + //replace a bunch with : yet? + if ((addr.u16[i] == 0) && (zerocnt == 0)) + { + //How mant zeros? + zerocnt = 0; + while(addr.u16[zerocnt + i] == 0) + zerocnt++; + + //just one, don't waste our zeros... + if (zerocnt == 1) + { + *result++ = '0'; + numprinted++; + break; + } + + //Cool - can replace a bunch of zeros + i += zerocnt; + numprinted += zerocnt; + } + //Normal address, just print it + else + { + result += sprintf(result, "%x", (unsigned int)(uip_ntohs(addr.u16[i]))); + i++; + numprinted++; + } + + //Don't print : on last one + if (numprinted != 8) + *result++ = ':'; + } + + return (result - starting); + } +#endif /* WEBSERVER_CONF_PRINTADDR */ \ No newline at end of file diff --git a/apps/webserver-nano/httpd-cgi.h b/apps/webserver-nano/httpd-cgi.h new file mode 100644 index 000000000..f6cae6291 --- /dev/null +++ b/apps/webserver-nano/httpd-cgi.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2001, 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: httpd-cgi.h,v 1.3 2008/10/14 11:07:57 adamdunkels Exp $ + * + */ + +#ifndef __HTTPD_CGI_H__ +#define __HTTPD_CGI_H__ + +#include "contiki.h" +#include "httpd.h" + +typedef PT_THREAD((* httpd_cgifunction)(struct httpd_state *, char *)); + +httpd_cgifunction httpd_cgi(char *name); + +struct httpd_cgi_call { + struct httpd_cgi_call *next; + const char *name; + httpd_cgifunction function; +}; + +void httpd_cgi_add(struct httpd_cgi_call *c); + +#define HTTPD_CGI_CALL(name, str, function) \ +static struct httpd_cgi_call name = {NULL, str, function} + +void httpd_cgi_init(void); +#endif /* __HTTPD_CGI_H__ */ diff --git a/apps/webserver-nano/httpd-fs.c b/apps/webserver-nano/httpd-fs.c new file mode 100644 index 000000000..23552a2cb --- /dev/null +++ b/apps/webserver-nano/httpd-fs.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2001, Swedish Institute of Computer Science. + * 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. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#include "contiki-net.h" +#include "httpd.h" +#include "httpd-fs.h" +#include "httpd-fsdata.h" + +#include /* for memcpy */ + +/* httpd-fsdata.c contains the web content. + * It is generated using the PERL script /tools/makefsdata + */ +#include "httpd-fsdata.c" + +#if WEBSERVER_CONF_FILESTATS==1 +u16_t httpd_filecount[HTTPD_FS_NUMFILES]; +#endif +/*-----------------------------------------------------------------------------------*/ +void * +httpd_fs_get_root() +{ + return (void *)HTTPD_FS_ROOT; +} +/*-----------------------------------------------------------------------------------*/ +u16_t +httpd_fs_get_size() +{ + return HTTPD_FS_SIZE; +} +/*-----------------------------------------------------------------------------------*/ +static u8_t +httpd_fs_strcmp(const char *str1, const char *str2) +{ + u8_t i; + i = 0; + +loop: + if(str2[i] == 0 || + str1[i] == '\r' || + str1[i] == '\n') { + return 0; + } + + if(str1[i] != str2[i]) { + return 1; + } + + ++i; + goto loop; +} +/*-----------------------------------------------------------------------------------*/ +uint16_t +httpd_fs_open(const char *name, struct httpd_fs_file *file) +{ +#if WEBSERVER_CONF_FILESTATS + u16_t i = 0; +#endif + struct httpd_fsdata_file_noconst *f,fram; + + for(f = (struct httpd_fsdata_file_noconst *)HTTPD_FS_ROOT; + f != NULL; + f = (struct httpd_fsdata_file_noconst *)fram.next) { + + /*Get the linked list entry into ram from wherever it is */ + httpd_memcpy(&fram,f,sizeof(fram)); + + /*Compare name passed in RAM with name in whatever flash the file is in */ + /*makefsdata adds an extra zero byte at the end of the file */ + if(httpd_fs_strcmp((char *)name, fram.name) == 0) { + if (file) { + file->data = fram.data; + file->len = fram.len-1; +#if WEBSERVER_CONF_FILESTATS==2 //increment count in linked list field if it is in RAM + f->count++; + } + return f->count; + } + ++i +#elif WEBSERVER_CONF_FILESTATS==1 //increment count in RAM array when linked list is in flash + ++httpd_filecount[i]; + } + return httpd_filecount[i]; + } + ++i; +#else //no file statistics + } + return 1; + } +#endif /* WEBSERVER_CONF_FILESTATS */ + } + return 0; +} +/*-----------------------------------------------------------------------------------*/ +void +httpd_fs_init(void) +{ +#if WEBSERVER_CONF_FILESTATS==1 + u16_t i; + for(i = 0; i < HTTPD_FS_NUMFILES; i++) { + httpd_filecount[i] = 0; + } +#endif +} +/*-----------------------------------------------------------------------------------*/ +#if WEBSERVER_CONF_FILESTATS && 0 +u16_t +httpd_fs_count(char *name) +{ + struct httpd_fsdata_file_noconst *f; + u16_t i; + + i = 0; + for(f = (struct httpd_fsdata_file_noconst *)HTTPD_FS_ROOT; + f != NULL; + f = (struct httpd_fsdata_file_noconst *)f->next) { + + if(httpd_fs_strcmp(name, f->name) == 0) { + return httpd_filecount[i]; + } + ++i; + } + return 0; +} +#endif +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/webserver-nano/httpd-fs.h b/apps/webserver-nano/httpd-fs.h new file mode 100644 index 000000000..de44abee7 --- /dev/null +++ b/apps/webserver-nano/httpd-fs.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2001, Swedish Institute of Computer Science. + * 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. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the lwIP TCP/IP stack. + */ +#ifndef __HTTPD_FS_H__ +#define __HTTPD_FS_H__ + +#include "contiki-net.h" +#include "httpd.h" + +struct httpd_fs_file { + char *data; + int len; +}; + +/* file must be allocated by caller and will be filled in + by the function. */ +uint16_t httpd_fs_open(const char *name, struct httpd_fs_file *file); + +#if WEBSERVER_CONF_FILESTATS +extern u16_t httpd_filecount[]; +u16_t httpd_fs_count(char *name); +void* httpd_fs_get_root(void); +#endif + +void httpd_fs_init(void); + +#endif /* __HTTPD_FS_H__ */ diff --git a/apps/webserver-nano/httpd-fs/404.html b/apps/webserver-nano/httpd-fs/404.html new file mode 100644 index 000000000..e5977f9d3 --- /dev/null +++ b/apps/webserver-nano/httpd-fs/404.html @@ -0,0 +1 @@ +404 - file not found - go to index \ No newline at end of file diff --git a/apps/webserver-nano/httpd-fs/files.shtml b/apps/webserver-nano/httpd-fs/files.shtml new file mode 100644 index 000000000..2bd8be54f --- /dev/null +++ b/apps/webserver-nano/httpd-fs/files.shtml @@ -0,0 +1,4 @@ +%! header.html +

File statistics


+%! file-stats * +
NameAccesses
diff --git a/apps/webserver-nano/httpd-fs/index.shtml b/apps/webserver-nano/httpd-fs/index.shtml new file mode 100644 index 000000000..b6dcb2c5d --- /dev/null +++ b/apps/webserver-nano/httpd-fs/index.shtml @@ -0,0 +1,3 @@ +%! header +Welcome to the Contiki nano web server! +%! file-stats . \ No newline at end of file diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/404.html b/apps/webserver-nano/httpd-fs/makefsdata.ignore/404.html new file mode 100644 index 000000000..e5977f9d3 --- /dev/null +++ b/apps/webserver-nano/httpd-fs/makefsdata.ignore/404.html @@ -0,0 +1 @@ +404 - file not found - go to index \ No newline at end of file diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/README.makefsdata b/apps/webserver-nano/httpd-fs/makefsdata.ignore/README.makefsdata new file mode 100644 index 000000000..2a366266d --- /dev/null +++ b/apps/webserver-nano/httpd-fs/makefsdata.ignore/README.makefsdata @@ -0,0 +1,5 @@ +Move the desired pages into httpd-fs and regenerate httpd-fsdata.c using the PERL script makefsdata. +Stage unused pages in this directory; anything here will be ignored by makefsdata. +When using non-ram storage it must be invoked with the HTTPD_STRING_ATTR! +E.g. cd ~/contiki/apps/webserver (or webserver-nano, -micro, -mini, ...) +../../tools/makefsdata -A HTTPD_STRING_ATTR diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/favicon.gif b/apps/webserver-nano/httpd-fs/makefsdata.ignore/favicon.gif new file mode 100644 index 000000000..ba3f81c48 Binary files /dev/null and b/apps/webserver-nano/httpd-fs/makefsdata.ignore/favicon.gif differ diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/files.shtml b/apps/webserver-nano/httpd-fs/makefsdata.ignore/files.shtml new file mode 100644 index 000000000..2bd8be54f --- /dev/null +++ b/apps/webserver-nano/httpd-fs/makefsdata.ignore/files.shtml @@ -0,0 +1,4 @@ +%! header.html +

File statistics


+%! file-stats * +
NameAccesses
diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/footer.html b/apps/webserver-nano/httpd-fs/makefsdata.ignore/footer.html new file mode 100644 index 000000000..62b274f1c --- /dev/null +++ b/apps/webserver-nano/httpd-fs/makefsdata.ignore/footer.html @@ -0,0 +1 @@ + diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/header.html b/apps/webserver-nano/httpd-fs/makefsdata.ignore/header.html new file mode 100644 index 000000000..0b5700c1c --- /dev/null +++ b/apps/webserver-nano/httpd-fs/makefsdata.ignore/header.html @@ -0,0 +1 @@ +Contiki-nano
Front page|Status|Network connections|System processes|File statistics
diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/index.html b/apps/webserver-nano/httpd-fs/makefsdata.ignore/index.html new file mode 100644 index 000000000..7c8f868f5 --- /dev/null +++ b/apps/webserver-nano/httpd-fs/makefsdata.ignore/index.html @@ -0,0 +1 @@ +Contiki-nano Welcome to the Contiki nano web server! diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/index.shtml b/apps/webserver-nano/httpd-fs/makefsdata.ignore/index.shtml new file mode 100644 index 000000000..b6dcb2c5d --- /dev/null +++ b/apps/webserver-nano/httpd-fs/makefsdata.ignore/index.shtml @@ -0,0 +1,3 @@ +%! header +Welcome to the Contiki nano web server! +%! file-stats . \ No newline at end of file diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/processes.shtml b/apps/webserver-nano/httpd-fs/makefsdata.ignore/processes.shtml new file mode 100644 index 000000000..8c7793373 --- /dev/null +++ b/apps/webserver-nano/httpd-fs/makefsdata.ignore/processes.shtml @@ -0,0 +1,6 @@ +%! header +

System processes


+ +%! processes +
IDNameThreadProcess state
+%! file-stats . diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/robots.txt b/apps/webserver-nano/httpd-fs/makefsdata.ignore/robots.txt new file mode 100644 index 000000000..dd33f956a --- /dev/null +++ b/apps/webserver-nano/httpd-fs/makefsdata.ignore/robots.txt @@ -0,0 +1,2 @@ +user-agent: * +Disallow: / \ No newline at end of file diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/status.shtml b/apps/webserver-nano/httpd-fs/makefsdata.ignore/status.shtml new file mode 100644 index 000000000..b6574fbcb --- /dev/null +++ b/apps/webserver-nano/httpd-fs/makefsdata.ignore/status.shtml @@ -0,0 +1,10 @@ +%! header +

Addresses

+%! addresses +

Neighbors

+%! neighbors +

Routes

+%! routes +

Sensors

+%! sensors +%! file-stats . diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/tcp.shtml b/apps/webserver-nano/httpd-fs/makefsdata.ignore/tcp.shtml new file mode 100644 index 000000000..9869f0dae --- /dev/null +++ b/apps/webserver-nano/httpd-fs/makefsdata.ignore/tcp.shtml @@ -0,0 +1,6 @@ +%! header.html +

Current connections


+ +%! tcp-connections +
LocalRemoteStateRetransmissionsTimerFlags
+%! file-stats . \ No newline at end of file diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/b.gif b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/b.gif new file mode 100644 index 000000000..4fdea6d45 Binary files /dev/null and b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/b.gif differ diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/bc.gif b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/bc.gif new file mode 100644 index 000000000..3d143cc55 Binary files /dev/null and b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/bc.gif differ diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/bh.gif b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/bh.gif new file mode 100644 index 000000000..e67b9070f Binary files /dev/null and b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/bh.gif differ diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/bv.gif b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/bv.gif new file mode 100644 index 000000000..87510d8b4 Binary files /dev/null and b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/bv.gif differ diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/index.html b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/index.html new file mode 100644 index 000000000..7c8f868f5 --- /dev/null +++ b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/index.html @@ -0,0 +1 @@ +Contiki-nano Welcome to the Contiki nano web server! diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/index.shtml b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/index.shtml new file mode 100644 index 000000000..3a23b43ed --- /dev/null +++ b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/index.shtml @@ -0,0 +1,3 @@ +
+%! tictac +
\ No newline at end of file diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/o.gif b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/o.gif new file mode 100644 index 000000000..eaa6f4d7c Binary files /dev/null and b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/o.gif differ diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/oc.gif b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/oc.gif new file mode 100644 index 000000000..045624207 Binary files /dev/null and b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/oc.gif differ diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/oh.gif b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/oh.gif new file mode 100644 index 000000000..598cbe0e1 Binary files /dev/null and b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/oh.gif differ diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/ov.gif b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/ov.gif new file mode 100644 index 000000000..b4ca2b1a5 Binary files /dev/null and b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/ov.gif differ diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/s.css b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/s.css new file mode 100644 index 000000000..2e5941ac4 --- /dev/null +++ b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/s.css @@ -0,0 +1 @@ +img{border-style: none;} diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/ttt.shtml b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/ttt.shtml new file mode 100644 index 000000000..3a23b43ed --- /dev/null +++ b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/ttt.shtml @@ -0,0 +1,3 @@ +
+%! tictac +
\ No newline at end of file diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/x.gif b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/x.gif new file mode 100644 index 000000000..bd1c34492 Binary files /dev/null and b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/x.gif differ diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/xc.gif b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/xc.gif new file mode 100644 index 000000000..a8f01b4d0 Binary files /dev/null and b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/xc.gif differ diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/xh.gif b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/xh.gif new file mode 100644 index 000000000..6ec93d36e Binary files /dev/null and b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/xh.gif differ diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/xv.gif b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/xv.gif new file mode 100644 index 000000000..7fdc5430a Binary files /dev/null and b/apps/webserver-nano/httpd-fs/makefsdata.ignore/ttt/xv.gif differ diff --git a/apps/webserver-nano/httpd-fs/makefsdata.ignore/upload.html b/apps/webserver-nano/httpd-fs/makefsdata.ignore/upload.html new file mode 100644 index 000000000..575dbf8f1 --- /dev/null +++ b/apps/webserver-nano/httpd-fs/makefsdata.ignore/upload.html @@ -0,0 +1,8 @@ + + +
+ + +
+ + \ No newline at end of file diff --git a/apps/webserver-nano/httpd-fs/status.shtml b/apps/webserver-nano/httpd-fs/status.shtml new file mode 100644 index 000000000..b6574fbcb --- /dev/null +++ b/apps/webserver-nano/httpd-fs/status.shtml @@ -0,0 +1,10 @@ +%! header +

Addresses

+%! addresses +

Neighbors

+%! neighbors +

Routes

+%! routes +

Sensors

+%! sensors +%! file-stats . diff --git a/apps/webserver-nano/httpd-fs/tcp.shtml b/apps/webserver-nano/httpd-fs/tcp.shtml new file mode 100644 index 000000000..9869f0dae --- /dev/null +++ b/apps/webserver-nano/httpd-fs/tcp.shtml @@ -0,0 +1,6 @@ +%! header.html +

Current connections


+ +%! tcp-connections +
LocalRemoteStateRetransmissionsTimerFlags
+%! file-stats . \ No newline at end of file diff --git a/apps/webserver-nano/httpd-fsdata.c b/apps/webserver-nano/httpd-fsdata.c new file mode 100644 index 000000000..58cef3c1c --- /dev/null +++ b/apps/webserver-nano/httpd-fsdata.c @@ -0,0 +1,116 @@ +/*********Generated by contiki/tools/makefsdata on 2011-07-23*********/ + + +const char data_404_html[87] HTTPD_STRING_ATTR = { + /* /404.html */ + 0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x00, + 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x62, 0x6f, 0x64, + 0x79, 0x3e, 0x34, 0x30, 0x34, 0x20, 0x2d, 0x20, 0x66, 0x69, + 0x6c, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, + 0x6e, 0x64, 0x20, 0x2d, 0x20, 0x67, 0x6f, 0x20, 0x74, 0x6f, + 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, + 0x2f, 0x22, 0x3e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3c, 0x2f, + 0x61, 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, + 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x00}; + +const char data_files_shtml[169] HTTPD_STRING_ATTR = { + /* /files.shtml */ + 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x00, + 0x25, 0x21, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, + 0x68, 0x74, 0x6d, 0x6c, 0x0a, 0x3c, 0x68, 0x31, 0x3e, 0x46, + 0x69, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, + 0x74, 0x69, 0x63, 0x73, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x3c, + 0x62, 0x72, 0x3e, 0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 0x31, 0x30, 0x30, + 0x25, 0x22, 0x3e, 0x3c, 0x74, 0x72, 0x20, 0x61, 0x6c, 0x69, + 0x67, 0x6e, 0x3d, 0x22, 0x6c, 0x65, 0x66, 0x74, 0x22, 0x3e, + 0x3c, 0x74, 0x68, 0x3e, 0x4e, 0x61, 0x6d, 0x65, 0x3c, 0x2f, + 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x65, 0x73, 0x3c, 0x2f, 0x74, 0x68, 0x3e, + 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x0a, 0x25, 0x21, 0x20, 0x66, + 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x73, 0x20, + 0x2a, 0x0a, 0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, + 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, + 0x74, 0x6d, 0x6c, 0x3e, 0x0a, 0x00}; + +const char data_index_shtml[121] HTTPD_STRING_ATTR = { + /* /index.shtml */ + 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x00, + 0x25, 0x21, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x0a, + 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x74, 0x6f, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, + 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x69, 0x63, 0x73, 0x2e, + 0x73, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6b, 0x69, + 0x2f, 0x22, 0x3e, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6b, 0x69, + 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x6e, 0x61, 0x6e, 0x6f, 0x20, + 0x77, 0x65, 0x62, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x21, 0x0a, 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, + 0x73, 0x74, 0x61, 0x74, 0x73, 0x20, 0x2e, 0x00}; + +const char data_status_shtml[159] HTTPD_STRING_ATTR = { + /* /status.shtml */ + 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x00, + 0x25, 0x21, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x0a, + 0x3c, 0x68, 0x34, 0x3e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x65, 0x73, 0x3c, 0x2f, 0x68, 0x34, 0x3e, 0x0a, 0x25, + 0x21, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, + 0x73, 0x0a, 0x3c, 0x68, 0x34, 0x3e, 0x4e, 0x65, 0x69, 0x67, + 0x68, 0x62, 0x6f, 0x72, 0x73, 0x3c, 0x2f, 0x68, 0x34, 0x3e, + 0x0a, 0x25, 0x21, 0x20, 0x6e, 0x65, 0x69, 0x67, 0x68, 0x62, + 0x6f, 0x72, 0x73, 0x0a, 0x3c, 0x68, 0x34, 0x3e, 0x52, 0x6f, + 0x75, 0x74, 0x65, 0x73, 0x3c, 0x2f, 0x68, 0x34, 0x3e, 0x0a, + 0x25, 0x21, 0x20, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x0a, + 0x3c, 0x68, 0x34, 0x3e, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, + 0x73, 0x3c, 0x2f, 0x68, 0x34, 0x3e, 0x0a, 0x25, 0x21, 0x20, + 0x73, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x73, 0x0a, 0x25, 0x21, + 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, 0x74, 0x61, 0x74, + 0x73, 0x20, 0x2e, 0x0a, 0x00}; + +const char data_tcp_shtml[228] HTTPD_STRING_ATTR = { + /* /tcp.shtml */ + 0x2f, 0x74, 0x63, 0x70, 0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, 0x00, + 0x25, 0x21, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, + 0x68, 0x74, 0x6d, 0x6c, 0x0a, 0x3c, 0x68, 0x31, 0x3e, 0x43, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x63, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, + 0x68, 0x31, 0x3e, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, + 0x22, 0x31, 0x30, 0x30, 0x25, 0x22, 0x3e, 0x0a, 0x3c, 0x74, + 0x72, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x4c, 0x6f, 0x63, 0x61, + 0x6c, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, + 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x3c, 0x2f, 0x74, 0x68, + 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x52, + 0x65, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x73, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, + 0x74, 0x68, 0x3e, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x3c, 0x2f, + 0x74, 0x68, 0x3e, 0x3c, 0x74, 0x68, 0x3e, 0x46, 0x6c, 0x61, + 0x67, 0x73, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x3c, 0x2f, 0x74, + 0x72, 0x3e, 0x0a, 0x25, 0x21, 0x20, 0x74, 0x63, 0x70, 0x2d, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x0a, 0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, + 0x0a, 0x25, 0x21, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2d, 0x73, + 0x74, 0x61, 0x74, 0x73, 0x20, 0x2e, 0x00}; + + +/* Structure of linked list (all offsets relative to start of section): +struct httpd_fsdata_file { + const struct httpd_fsdata_file *next; //actual flash address of next link + const char *name; //offset to coffee file name + const char *data; //offset to coffee file data + const int len; //length of file data +#if HTTPD_FS_STATISTICS == 1 //not enabled since list is in PROGMEM + u16_t count; //storage for file statistics +#endif +} +*/ +const struct httpd_fsdata_file file_404_html[] HTTPD_STRING_ATTR ={{ NULL, data_404_html , data_404_html +10, sizeof(data_404_html) -10}}; +const struct httpd_fsdata_file file_files_shtml[] HTTPD_STRING_ATTR ={{ file_404_html, data_files_shtml , data_files_shtml +13, sizeof(data_files_shtml) -13}}; +const struct httpd_fsdata_file file_index_shtml[] HTTPD_STRING_ATTR ={{ file_files_shtml, data_index_shtml , data_index_shtml +13, sizeof(data_index_shtml) -13}}; +const struct httpd_fsdata_file file_status_shtml[] HTTPD_STRING_ATTR ={{ file_index_shtml, data_status_shtml , data_status_shtml +14, sizeof(data_status_shtml) -14}}; +const struct httpd_fsdata_file file_tcp_shtml[] HTTPD_STRING_ATTR ={{ file_status_shtml, data_tcp_shtml , data_tcp_shtml +11, sizeof(data_tcp_shtml) -11}}; + +#define HTTPD_FS_ROOT file_tcp_shtml +#define HTTPD_FS_NUMFILES 5 +#define HTTPD_FS_SIZE 764 diff --git a/apps/webserver-nano/httpd-fsdata.h b/apps/webserver-nano/httpd-fsdata.h new file mode 100644 index 000000000..0d514bacf --- /dev/null +++ b/apps/webserver-nano/httpd-fsdata.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2001, Swedish Institute of Computer Science. + * 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. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + * $Id: httpd-fsdata.h,v 1.1 2006/06/17 22:41:14 adamdunkels Exp $ + */ +#ifndef __HTTPD_FSDATA_H__ +#define __HTTPD_FSDATA_H__ + +#include "contiki-net.h" + +struct httpd_fsdata_file { + const struct httpd_fsdata_file *next; + const char *name; + const char *data; + const int len; +#ifdef HTTPD_FS_STATISTICS +#if HTTPD_FS_STATISTICS == 1 + u16_t count; +#endif /* HTTPD_FS_STATISTICS */ +#endif /* HTTPD_FS_STATISTICS */ +}; + +struct httpd_fsdata_file_noconst { + struct httpd_fsdata_file *next; + char *name; + char *data; + int len; +#ifdef HTTPD_FS_STATISTICS +#if HTTPD_FS_STATISTICS == 1 + u16_t count; +#endif /* HTTPD_FS_STATISTICS */ +#endif /* HTTPD_FS_STATISTICS */ +}; + +#endif /* __HTTPD_FSDATA_H__ */ diff --git a/apps/webserver-nano/httpd.c b/apps/webserver-nano/httpd.c new file mode 100644 index 000000000..52cb3577a --- /dev/null +++ b/apps/webserver-nano/httpd.c @@ -0,0 +1,504 @@ +/* + * Copyright (c) 2004, 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. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + + /* Configurable Contiki Webserver - see httpd.h */ + +#include +#include + +#include "contiki-net.h" +#include "httpd.h" + +#include "webserver.h" +#include "httpd-fs.h" + +#if WEBSERVER_CONF_CGI +#include "httpd-cgi.h" +#endif + +#include "lib/petsciiconv.h" + +#if COFFEE_FILES +#include "cfs-coffee-arch.h" +#endif + +#define DEBUG 0 +#if DEBUG +#define PRINTD PRINTA +#else +#define PRINTD(...) +#endif + +#define STATE_WAITING 0 +#define STATE_OUTPUT 1 +/* Allocate memory for the tcp connections */ +MEMB(conns, struct httpd_state, WEBSERVER_CONF_CONNS); + +#define ISO_tab 0x09 +#define ISO_nl 0x0a +#define ISO_cr 0x0d +#define ISO_space 0x20 +#define ISO_bang 0x21 +#define ISO_percent 0x25 +#define ISO_period 0x2e +#define ISO_slash 0x2f +#define ISO_colon 0x3a +#define ISO_qmark 0x3f + + +/*---------------------------------------------------------------------------*/ +static unsigned short +generate(void *state) +{ + struct httpd_state *s = (struct httpd_state *)state; + + if(s->file.len > uip_mss()) { + s->len = uip_mss(); + } else { + s->len = s->file.len; + } + httpd_fs_cpy(uip_appdata, s->file.data, s->len); + return s->len; +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(send_file(struct httpd_state *s)) +{ + PSOCK_BEGIN(&s->sout); + + do { + PSOCK_GENERATOR_SEND(&s->sout, generate, s); + s->file.len -= s->len; + s->file.data += s->len; + } while(s->file.len > 0); + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +#if WEBSERVER_CONF_INCLUDE || WEBSERVER_CONF_CGI +static +PT_THREAD(send_part_of_file(struct httpd_state *s)) +{ + PSOCK_BEGIN(&s->sout); + + static int oldfilelen, oldlen; + static char * olddata; + + //Store stuff that gets clobbered... + oldfilelen = s->file.len; + oldlen = s->len; + olddata = s->file.data; + + s->file.len = s->len; + do { + PSOCK_GENERATOR_SEND(&s->sout, generate, s); + s->file.len -= s->len; + s->file.data += s->len; + } while(s->file.len > 0); + + s->len = oldlen; + s->file.len = oldfilelen; + s->file.data = olddata; + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +static void +next_scriptstate(struct httpd_state *s) +{ + char *p; +/* Skip over any script parameters to the beginning of the next line */ + if((p = (char *)httpd_fs_strchr(s->scriptptr, ISO_nl)) != NULL) { + p += 1; + s->scriptlen -= (unsigned short)(p - s->scriptptr); + s->scriptptr = p; + } else { + s->scriptlen = 0; + } +} + +/*---------------------------------------------------------------------------*/ +char * +get_scriptname(char *dest, char *fromfile) +{ + uint8_t i=0,skip=1; + /* Extract a file or cgi name, trim leading spaces and replace termination with zero */ + /* Returns number of characters processed up to the next non-tab or space */ + do { + dest[i]=httpd_fs_getchar(fromfile++); + if (dest[i]==ISO_colon) {if (!skip) break;} //allow leading colons + else if (dest[i]==ISO_tab ) {if (skip) continue;else break;}//skip leading tabs + else if (dest[i]==ISO_space) {if (skip) continue;else break;}//skip leading spaces + else if (dest[i]==ISO_nl ) break; //nl is preferred delimiter + else if (dest[i]==ISO_cr ) break; //some editors insert cr + else if (dest[i]==0 ) break; //files are terminated with null + else skip=0; + i++; + } while (i<(MAX_SCRIPT_NAME_LENGTH+1)); + fromfile--; + while ((dest[i]==ISO_space) || (dest[i]==ISO_tab)) dest[i]=httpd_fs_getchar(++fromfile); + dest[i]=0; + return (fromfile); +} +/*---------------------------------------------------------------------------*/ + +static +PT_THREAD(handle_script(struct httpd_state *s)) +{ + /* Note script includes will attach a leading : to the filename and a trailing zero */ + static char scriptname[MAX_SCRIPT_NAME_LENGTH+1],*pptr; + static uint16_t filelength; + + PT_BEGIN(&s->scriptpt); + + filelength=s->file.len; + while(s->file.len > 0) { + /* Sanity check */ + if (s->file.len > filelength) break; + + /* Check if we should start executing a script, flagged by %! */ + if(httpd_fs_getchar(s->file.data) == ISO_percent && + httpd_fs_getchar(s->file.data + 1) == ISO_bang) { + + /* Extract name, if starts with colon include file else call cgi */ + s->scriptptr=get_scriptname(scriptname,s->file.data+2); + s->scriptlen=s->file.len-(s->scriptptr-s->file.data); + PRINTD("httpd: Handle script named %s\n",scriptname); + if(scriptname[0] == ISO_colon) { +#if WEBSERVER_CONF_INCLUDE + if (httpd_fs_open(&scriptname[1], &s->file)) { + PT_WAIT_THREAD(&s->scriptpt, send_file(s)); + } + /*TODO dont print anything if file not found */ +#endif + } else { +#if WEBSERVER_CONF_CGI + PT_WAIT_THREAD(&s->scriptpt,httpd_cgi(scriptname)(s, s->scriptptr)); +#endif + } + next_scriptstate(s); + + /* Reset the pointers and continue sending the current file. */ + s->file.data = s->scriptptr; + s->file.len = s->scriptlen; + } else { + + /* Send file up to the next potential script */ + if(s->file.len > uip_mss()) { + s->len = uip_mss(); + } else { + s->len = s->file.len; + } + + if(httpd_fs_getchar(s->file.data) == ISO_percent) { + pptr = (char *) httpd_fs_strchr(s->file.data + 1, ISO_percent); + } else { + pptr = (char *) httpd_fs_strchr(s->file.data, ISO_percent); + } + + if(pptr != NULL && pptr != s->file.data) { + s->len = (int)(pptr - s->file.data); + if(s->len >= uip_mss()) { + s->len = uip_mss(); + } + } + PRINTD("httpd: Sending %u bytes from 0x%04x\n",s->file.len,(unsigned int)s->file.data); + PT_WAIT_THREAD(&s->scriptpt, send_part_of_file(s)); + s->file.data += s->len; + s->file.len -= s->len; + } + } + + PT_END(&s->scriptpt); +} +#endif /* WEBSERVER_CONF_INCLUDE || WEBSERVER_CONF_CGI */ +/*---------------------------------------------------------------------------*/ +const char httpd_http[] HTTPD_STRING_ATTR = "HTTP/1.0 "; +const char httpd_server[] HTTPD_STRING_ATTR = "\r\nServer: Contiki/2.0 http://www.sics.se/contiki/\r\nConnection: close\r\n"; +static unsigned short +generate_status(void *sstr) +{ + uint8_t slen=httpd_strlen((char *)sstr); + httpd_memcpy(uip_appdata, httpd_http, sizeof(httpd_http)-1); + httpd_memcpy(uip_appdata+sizeof(httpd_http)-1, (char *)sstr, slen); + slen+=sizeof(httpd_http)-1; + httpd_memcpy(uip_appdata+slen, httpd_server, sizeof(httpd_server)-1); + return slen+sizeof(httpd_server)-1; +} +/*---------------------------------------------------------------------------*/ +const char httpd_content[] HTTPD_STRING_ATTR = "Content-type: "; +const char httpd_crlf[] HTTPD_STRING_ATTR = "\r\n\r\n"; +static unsigned short +generate_header(void *hstr) +{ + uint8_t slen=httpd_strlen((char *)hstr); + httpd_memcpy(uip_appdata,httpd_content,sizeof(httpd_content)-1); + httpd_memcpy(uip_appdata+sizeof(httpd_content)-1, (char *)hstr, slen); + slen+=sizeof(httpd_content)-1; + httpd_memcpy(uip_appdata+slen,httpd_crlf,sizeof(httpd_crlf)-1); + return slen+4; +} +/*---------------------------------------------------------------------------*/ +const char httpd_mime_htm[] HTTPD_STRING_ATTR = "text/html"; +#if WEBSERVER_CONF_CSS +const char httpd_mime_css[] HTTPD_STRING_ATTR = "text/css"; +#endif +#if WEBSERVER_CONF_PNG +const char httpd_mime_png[] HTTPD_STRING_ATTR = "image/png"; +#endif +#if WEBSERVER_CONF_GIF +const char httpd_mime_gif[] HTTPD_STRING_ATTR = "image/gif"; +#endif +#if WEBSERVER_CONF_JPG +const char httpd_mime_jpg[] HTTPD_STRING_ATTR = "image/jpeg"; +const char httpd_jpg [] HTTPD_STRING_ATTR = "jpg"; +#endif +#if WEBSERVER_CONF_TXT +const char httpd_mime_txt[] HTTPD_STRING_ATTR = "text/plain"; +#endif +#if WEBSERVER_CONF_BIN +const char httpd_mime_bin[] HTTPD_STRING_ATTR = "application/octet-stream"; +#endif +#if WEBSERVER_CONF_INCLUDE || WEBSERVER_CONF_CGI +const char httpd_shtml [] HTTPD_STRING_ATTR = ".shtml"; +#endif + +static +PT_THREAD(send_headers(struct httpd_state *s, const char *statushdr)) +{ + char *ptr; + PSOCK_BEGIN(&s->sout); + + PSOCK_GENERATOR_SEND(&s->sout, generate_status, (char *)statushdr); + + ptr = strrchr(s->filename, ISO_period); + if (httpd_strncmp("4", statushdr, 1)==0) { //404 + PSOCK_GENERATOR_SEND(&s->sout, generate_header, &httpd_mime_htm ); + } else if(ptr == NULL) { +#if WEBSERVER_CONF_BIN + PSOCK_GENERATOR_SEND(&s->sout, generate_header, &httpd_mime_bin ); +#else + PSOCK_GENERATOR_SEND(&s->sout, generate_header, &httpd_mime_htm ); +#endif + } else { + ptr++; +#if WEBSERVER_CONF_INCLUDE || WEBSERVER_CONF_CGI + if(httpd_strncmp(ptr, &httpd_mime_htm[5],3)== 0 ||httpd_strncmp(ptr, &httpd_shtml[1], 4) == 0) { +#else + if(httpd_strncmp(ptr, &httpd_mime_htm[5],3)== 0) { +#endif + PSOCK_GENERATOR_SEND(&s->sout, generate_header, &httpd_mime_htm ); +#if WEBSEVER_CONF_CSS + } else if(httpd_strcmp(ptr, &httpd_mime_css[5]) == 0) { + PSOCK_GENERATOR_SEND(&s->sout, generate_header, &httpd_mime_css ); +#endif +#if WEBSERVER_CONF_PNG + } else if(httpd_strcmp(ptr, &httpd_mime_png[6]) == 0) { + PSOCK_GENERATOR_SEND(&s->sout, generate_header, &httpd_mime_png ); +#endif +#if WEBSERVER_CONF_GIF + } else if(httpd_strcmp(ptr, &httpd_mime_gif[6])== 0) { + PSOCK_GENERATOR_SEND(&s->sout, generate_header, &httpd_mime_gif ); +#endif +#if WEBSERVER_CONF_JPG + } else if(httpd_strcmp(ptr, httpd_mime_jpg) == 0) { + PSOCK_GENERATOR_SEND(&s->sout, generate_header, &httpd_mime_jpg ); +#endif +#if WEBSERVER_CONF_TXT + } else { + PSOCK_GENERATOR_SEND(&s->sout, generate_header, &httpd_mime_txt); +#endif + } + } + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +const char httpd_indexfn [] HTTPD_STRING_ATTR = "/index.html"; +#if WEBSERVER_CONF_INCLUDE || WEBSERVER_CONF_CGI +const char httpd_indexsfn [] HTTPD_STRING_ATTR = "/index.shtml"; +#endif +const char httpd_404fn [] HTTPD_STRING_ATTR = "/404.html"; +const char httpd_404notf [] HTTPD_STRING_ATTR = "404 Not found"; +const char httpd_200ok [] HTTPD_STRING_ATTR = "200 OK"; +static +PT_THREAD(handle_output(struct httpd_state *s)) +{ + char *ptr; + + PT_BEGIN(&s->outputpt); + if(!httpd_fs_open(s->filename, &s->file)) { +#if WEBSERVER_CONF_INCLUDE || WEBSERVER_CONF_CGI + /* If index.html not found try index.shtml */ + if (httpd_strcmp(s->filename,httpd_indexfn)==0) httpd_strcpy(s->filename,httpd_indexsfn); + if (httpd_fs_open(s->filename, &s->file)) goto sendfile; +#endif + httpd_strcpy(s->filename, httpd_404fn); + httpd_fs_open(s->filename, &s->file); + PT_WAIT_THREAD(&s->outputpt, send_headers(s, httpd_404notf)); + PT_WAIT_THREAD(&s->outputpt, send_file(s)); + } else { +sendfile: + PT_WAIT_THREAD(&s->outputpt, send_headers(s, httpd_200ok)); +#if WEBSERVER_CONF_INCLUDE || WEBSERVER_CONF_CGI + ptr = strchr(s->filename, ISO_period); + if((ptr != NULL && httpd_strncmp(ptr, httpd_shtml, 6) == 0) || httpd_strcmp(s->filename,httpd_indexfn)==0) { + PT_INIT(&s->scriptpt); + PT_WAIT_THREAD(&s->outputpt, handle_script(s)); + } else { +#else + if (1) +#endif + PT_WAIT_THREAD(&s->outputpt, send_file(s)); + } + } + PSOCK_CLOSE(&s->sout); + PT_END(&s->outputpt); +} +/*---------------------------------------------------------------------------*/ +#if WEBSERVER_CONF_PASSQUERY +char httpd_query[WEBSERVER_CONF_PASSQUERY]; +#endif + +const char httpd_get[] HTTPD_STRING_ATTR = "GET "; +const char httpd_ref[] HTTPD_STRING_ATTR = "Referer:"; +static +PT_THREAD(handle_input(struct httpd_state *s)) +{ + + PSOCK_BEGIN(&s->sin); + + PSOCK_READTO(&s->sin, ISO_space); + + if(httpd_strncmp(s->inputbuf, httpd_get, 4) != 0) { + PSOCK_CLOSE_EXIT(&s->sin); + } + PSOCK_READTO(&s->sin, ISO_space); + + if(s->inputbuf[0] != ISO_slash) { + PSOCK_CLOSE_EXIT(&s->sin); + } + + if(s->inputbuf[1] == ISO_space) { + httpd_strcpy(s->filename, httpd_indexfn); + } else { + s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0; + strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename)); +#if WEBSERVER_CONF_PASSQUERY +/* Query string is left in the buffer until zeroed by the application! */ +{uint8_t i; + for (i=0;ifilename)+1;i++) { + if (s->inputbuf[i]==ISO_space) break; + if (s->inputbuf[i]==ISO_qmark) { + s->inputbuf[i]=0; + strncpy(httpd_query,&s->inputbuf[i+1],sizeof(httpd_query)); +// raven_lcd_show_text(&s->inputbuf[i]); + } + } +} +#endif + } +#if WEBSERVER_CONF_LOG + webserver_log_file(&uip_conn->ripaddr, s->filename); +// webserver_log(httpd_query); +#endif + s->state = STATE_OUTPUT; + while(1) { + PSOCK_READTO(&s->sin, ISO_nl); +#if WEBSERVER_CONF_LOG && WEBSERVER_CONF_REFERER + if(httpd_strncmp(s->inputbuf, httpd_ref, 8) == 0) { + s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0; + petsciiconv_topetscii(s->inputbuf, PSOCK_DATALEN(&s->sin) - 2); + webserver_log(s->inputbuf); + } +#endif + } + PSOCK_END(&s->sin); +} +/*---------------------------------------------------------------------------*/ +static void +handle_connection(struct httpd_state *s) +{ + handle_input(s); + if(s->state == STATE_OUTPUT) { + handle_output(s); + } +} +/*---------------------------------------------------------------------------*/ +void +httpd_appcall(void *state) +{ + struct httpd_state *s = (struct httpd_state *)state; + if(uip_closed() || uip_aborted() || uip_timedout()) { + if(s != NULL) { + memb_free(&conns, s); + } + } else if(uip_connected()) { + s = (struct httpd_state *)memb_alloc(&conns); + if(s == NULL) { + uip_abort(); + return; + } + tcp_markconn(uip_conn, s); + PSOCK_INIT(&s->sin, (uint8_t *)s->inputbuf, sizeof(s->inputbuf) - 1); + PSOCK_INIT(&s->sout, (uint8_t *)s->inputbuf, sizeof(s->inputbuf) - 1); + PT_INIT(&s->outputpt); + s->state = STATE_WAITING; + s->timer = 0; + handle_connection(s); + } else if(s != NULL) { + if(uip_poll()) { + ++s->timer; + if(s->timer >= 20) { + uip_abort(); + memb_free(&conns, s); + } + } else { + s->timer = 0; + } + handle_connection(s); + } else { + uip_abort(); + } +} +/*---------------------------------------------------------------------------*/ +void +httpd_init(void) +{ + tcp_listen(UIP_HTONS(80)); + memb_init(&conns); + PRINTD(" sizof(struct httpd_state) = %d\n",sizeof(struct httpd_state)); + PRINTA(" %d bytes used for httpd state storage\n",conns.size * conns.num); +#if WEBSERVER_CONF_CGI + httpd_cgi_init(); +#endif +} +/*---------------------------------------------------------------------------*/ diff --git a/apps/webserver-nano/httpd.h b/apps/webserver-nano/httpd.h new file mode 100644 index 000000000..0f07ca9e7 --- /dev/null +++ b/apps/webserver-nano/httpd.h @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2001-2005, 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. + * + * + */ + +#ifndef __HTTPD_H__ +#define __HTTPD_H__ +/* + * The default number of simultaneous server connections is 4. Multiple connections can be triggered + * by requests for embedded images, style sheets, icons, etc. and a TCP RESET is issued when no more + * connections are available. + * The Firefox default connections per server is 15. It can be reduced to 1 in about:config and generally + * will improve throughput in the half-duplex 6LoWPAN link as embedded files will be requested sequentially. + * Tictactoe is a good test for multiple connections; it can use as many as 9, but should also work when + * Firefox network.http.max-connections-per-server is set to a lower number. + * The RAM needed for each entry depends on script enabling and buffer sizes; see struct httpd_state below. + * Typical range is 100 - 200 bytes per connection + */ +#define WEBSERVER_CONF_CONNS 2 +#define WEBSERVER_CONF_NAMESIZE 16 +#define WEBSERVER_CONF_BUFSIZE 40 +/* Allow include in .shtml pages, e.g. %!: /header.html */ +#define WEBSERVER_CONF_INCLUDE 1 +/* Allow cgi in .shtml pages, e.g. %! file-stats . */ +#define WEBSERVER_CONF_CGI 1 +/* MAX_SCRIPT_NAME_LENGTH should be at least the maximum file name length+2 for %!: includes */ +#define MAX_SCRIPT_NAME_LENGTH WEBSERVER_CONF_NAMESIZE+2 +/* Enable specific cgi's */ +#define WEBSERVER_CONF_HEADER 1 +//#define WEBSERVER_CONF_HEADER_W3C 1 //Proper header +#define WEBSERVER_CONF_HEADER_MENU 1 //with links to other pages +//#define WEBSERVER_CONF_HEADER_ICON 1 //with favicon +#define WEBSERVER_CONF_FILESTATS 1 +#define WEBSERVER_CONF_TCPSTATS 0 +#define WEBSERVER_CONF_PROCESSES 0 +#define WEBSERVER_CONF_ADDRESSES 1 +#define WEBSERVER_CONF_NEIGHBORS 1 +#define WEBSERVER_CONF_ROUTES 1 +#define WEBSERVER_CONF_SENSORS 0 +#define WEBSERVER_CONF_TICTACTOE 0 //Needs passquery of at least 10 chars +//#define WEBSERVER_CONF_PASSQUERY 10 +#if WEBSERVER_CONF_PASSQUERY +extern char httpd_query[WEBSERVER_CONF_PASSQUERY]; +#endif +/* Enable specific file types */ +#define WEBSERVER_CONF_JPG 0 +#define WEBSERVER_CONF_PNG 0 +#define WEBSERVER_CONF_GIF 0 +#define WEBSERVER_CONF_TXT 1 +#define WEBSERVER_CONF_CSS 0 +#define WEBSERVER_CONF_BIN 0 + +/* Log page accesses */ +#define WEBSERVER_CONF_LOG 0 +/* Include referrer in log */ +#define WEBSERVER_CONF_REFERER 0 + +/* Address printing used by cgi's and logging, but it can be turned off if desired */ +#if WEBSERVER_CONF_LOG || WEBSERVER_CONF_ADDRESSES || WEBSERVER_CONF_NEIGHBORS || WEBSERVER_CONF_ROUTES +#define WEBSERVER_CONF_PRINTADDR 1 +uint8_t httpd_cgi_sprint_ip6(uip_ip6addr_t addr, char * result); +#endif + + +#include "contiki-net.h" +#include "httpd-fs.h" + +#if defined(__AVR__) +/* When using non-ram storage httpd-fsdata.c must be generated with the HTTPD_STRING_ATTR, eg + * ../../tools/makefsdata -A HTTPD_STRING_ATTR + */ +#include +#define HTTPD_STRING_ATTR PROGMEM +#define PRINTA(FORMAT,args...) printf_P(PSTR(FORMAT),##args) +/* These will fail if the server strings are above 64K in program flash */ +#define httpd_memcpy memcpy_P +#define httpd_strcpy strcpy_P +#define httpd_strcmp strcmp_P +#define httpd_strncmp strncmp_P +#define httpd_strlen strlen_P +#define httpd_snprintf snprintf_P +#define httpd_fs_cpy memcpy_P +#define httpd_fs_strchr strchr_P +#define httpd_fs_getchar(x) pgm_read_byte(x) + +#else /* All storage in RAM */ +#define HTTPD_STRING_ATTR +#define PRINTA(FORMAT,args...) printf(FORMAT,##args) +#define httpd_snprintf snprintf +#define httpd_fs_cpy memcpy +#define httpd_memcpy memcpy +#define httpd_strcpy strcpy +#define httpd_strcmp strcmp +#define httpd_strncmp strncmp +#define httpd_strlen strlen +#define httpd_fs_strchr strchr +#define httpd_fs_getchar(c) *(c) +#endif + +struct httpd_state { + unsigned char timer; + struct psock sin, sout; + struct pt outputpt; +#if WEBSERVER_CONF_INCLUDE || WEBSERVER_CONF_CGI + struct pt scriptpt; +#endif + char inputbuf[WEBSERVER_CONF_BUFSIZE]; + char filename[WEBSERVER_CONF_NAMESIZE]; + char state; + struct httpd_fs_file file; + int len; +#if WEBSERVER_CONF_INCLUDE || WEBSERVER_CONF_CGI + char *scriptptr; + int scriptlen; +#endif +#if WEBSERVER_CONF_CGI + union { + unsigned short count; + void *ptr; + } u; +#endif +}; + +void httpd_init(void); +void httpd_appcall(void *state); + +#endif /* __HTTPD_H__ */ diff --git a/apps/webserver-nano/urlconv.c b/apps/webserver-nano/urlconv.c new file mode 100644 index 000000000..29585c895 --- /dev/null +++ b/apps/webserver-nano/urlconv.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2010, Kajtar Zsolt . + * 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. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * Author: Kajtar Zsolt + * + * $Id: urlconv.c,v 1.4 2010/09/29 09:35:56 oliverschmidt Exp $ + */ + +#include + +#include "cfs/cfs.h" +#include "http-strings.h" + +#define ISO_number 0x23 +#define ISO_percent 0x25 +#define ISO_period 0x2e +#define ISO_slash 0x2f +#define ISO_question 0x3f + +static char wwwroot[40]; +static unsigned char wwwrootlen; + +void +urlconv_init(void) +{ + int fd = cfs_open("wwwroot.cfg", CFS_READ); + int rd = cfs_read(fd, wwwroot, sizeof(wwwroot)); + cfs_close(fd); + if(rd != -1) wwwrootlen = rd; +} + +/*---------------------------------------------------------------------------*/ +/* URL to filename conversion + * + * prepends wwwroot prefix + * normalizes path by removing "/./" + * interprets "/../" and calculates path accordingly + * resulting path is always absolute + * replaces "%AB" notation with characters + * strips "#fragment" and "?query" from end + * replaces multiple slashes with a single one + * rejects non-ASCII characters + * + * MAXLEN is including trailing zero! + * input and output is ASCII + */ +void +urlconv_tofilename(char *dest, char *source, unsigned char maxlen) +{ + static unsigned char len; + static unsigned char c, hex1; + static unsigned char *from, *to; + + *dest = ISO_slash; + strncpy(dest + 1, wwwroot, wwwrootlen); + len = 0; + from = source; to = dest + wwwrootlen; + maxlen -= 2 + wwwrootlen; + do { + c = *(from++); + switch(c) { + case ISO_number: + case ISO_question: + c = 0; + break; + case ISO_percent: + c = 0; + hex1 = (*(from++) | 0x20) ^ 0x30; // ascii only! + if(hex1 > 0x50 && hex1 < 0x57) + hex1 -= 0x47; + else + if(hex1 > 9) + break; // invalid hex + c = (*(from++) | 0x20) ^ 0x30; // ascii only! + if(c > 0x50 && c < 0x57) + c -= 0x47; + else + if(c > 9) + break; // invalid hex + c |= hex1 << 4; + } + + if(c < 0x20 || c > 0x7e) + c = 0; // non ascii?! + if(len >= maxlen) + c = 0; // too long? + + if(c == ISO_slash || !c) { + switch(*to) { + case ISO_slash: + continue; // no repeated slash + case ISO_period: + switch(to[-1]) { + case ISO_slash: // handle "./" + --to; --len; + continue; + case ISO_period: + if(to[-2] == ISO_slash) { + to -= 2; len -= 2; + if(len) { + do { + --to; --len; + } while(*to != ISO_slash); + } + continue; + } + } + } + } + if(c) { + ++to; ++len; + *to = c; + } + } while(c); + if(*to == ISO_slash && (len + sizeof(http_index_htm) - 3) < maxlen) { + strcpy(to, http_index_htm); // add index.htm + } else { + ++to; + *to = 0; + } +} +/*---------------------------------------------------------------------------*/ diff --git a/apps/webserver-nano/urlconv.h b/apps/webserver-nano/urlconv.h new file mode 100644 index 000000000..23d6bfe51 --- /dev/null +++ b/apps/webserver-nano/urlconv.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2010, Kajtar Zsolt . + * 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. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * $Id: urlconv.h,v 1.3 2010/08/30 19:44:38 oliverschmidt Exp $ + */ + +#ifndef __URLCONV_H__ +#define __URLCONV_H__ + +void urlconv_init(void); +void urlconv_tofilename(char *dest, char *source, unsigned char maxlen); + +#endif /* __URLCONV_H__ */ diff --git a/apps/webserver-nano/webserver-dsc.c b/apps/webserver-nano/webserver-dsc.c new file mode 100644 index 000000000..9292db7fe --- /dev/null +++ b/apps/webserver-nano/webserver-dsc.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2003, 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 Contiki desktop environment + * + * $Id: webserver-dsc.c,v 1.3 2007/09/06 01:36:12 matsutsuka Exp $ + * + */ + +#include "sys/dsc.h" +/*-----------------------------------------------------------------------------------*/ +#if CTK_CONF_ICON_BITMAPS +static unsigned char webservericon_bitmap[3*3*8] = { + 0x00, 0x7f, 0x40, 0x41, 0x44, 0x48, 0x40, 0x50, + 0x00, 0xff, 0x5a, 0x00, 0x00, 0x00, 0x3c, 0x81, + 0x00, 0xfe, 0x02, 0x82, 0x22, 0x12, 0x02, 0x0a, + + 0x41, 0x60, 0x42, 0x62, 0x62, 0x42, 0x60, 0x41, + 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, + 0x82, 0x06, 0x42, 0x46, 0x46, 0x42, 0x06, 0x82, + + 0x50, 0x40, 0x48, 0x44, 0x41, 0x40, 0x7e, 0x00, + 0xc5, 0x34, 0x3c, 0x52, 0x7a, 0x7e, 0xa1, 0xfd, + 0x0a, 0x02, 0x12, 0x22, 0x82, 0x02, 0x7e, 0x00 +}; +#endif /* CTK_CONF_ICON_BITMAPS */ + +#if CTK_CONF_ICON_TEXTMAPS +static char webservericon_textmap[9] = { + '+', '-', '+', + '|', ')', '|', + '+', '-', '+' +}; +#endif /* CTK_CONF_ICON_TEXTMAPS */ + +#if CTK_CONF_ICONS +static struct ctk_icon webserver_icon = + {CTK_ICON("Web server", webservericon_bitmap, webservericon_textmap)}; +#endif /* CTK_CONF_ICONS */ +/*-----------------------------------------------------------------------------------*/ +DSC(webserver_dsc, + "The Contiki web server", + "webserver.prg", + webserver_process, + &webserver_icon); +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/webserver-nano/webserver-dsc.h b/apps/webserver-nano/webserver-dsc.h new file mode 100644 index 000000000..5abd496c3 --- /dev/null +++ b/apps/webserver-nano/webserver-dsc.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2003, 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 Contiki desktop environment + * + * $Id: webserver-dsc.h,v 1.1 2006/06/17 22:41:14 adamdunkels Exp $ + * + */ +#ifndef __WEBSERVER_DSC_H__ +#define __WEBSERVER_DSC_H__ + +#include "sys/dsc.h" + +DSC_HEADER(webserver_dsc); + +#endif /* __WEBSERVER_DSC_H__ */ diff --git a/apps/webserver-nano/webserver-nogui.c b/apps/webserver-nano/webserver-nogui.c new file mode 100644 index 000000000..a5ce9c664 --- /dev/null +++ b/apps/webserver-nano/webserver-nogui.c @@ -0,0 +1,94 @@ +/* + * 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 Contiki OS. + * + */ + +#include +#include + +#include "contiki.h" +#include "sys/log.h" + +//#include "http-strings.h" +#include "webserver-nogui.h" +#include "httpd.h" + +PROCESS(webserver_nogui_process, "Web server"); + +AUTOSTART_PROCESSES(&webserver_nogui_process); + +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(webserver_nogui_process, ev, data) +{ + PROCESS_BEGIN(); + + httpd_init(); + + while(1) { + PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event); + httpd_appcall(data); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +void +webserver_log_file(uip_ipaddr_t *requester, char *file) +{ +#if LOG_CONF_ENABLED + /* Print out IP address of requesting host. */ + +#if UIP_CONF_IPV6 +#if WEBSERVER_CONF_ADDRESSES + char buf[48]; + uint8_t j; + j=httpd_cgi_sprint_ip6((uip_ip6addr_t)*requester, buf); + buf[j]=':';buf[j+1]=' ';buf[j+2]=0; +#else + char buf[2]; + buf[0]=' ';buf[1]=0; +#endif +#else + char buf[20]; + sprintf(buf, "%d.%d.%d.%d: ", requester->u8[0], requester->u8[1], + requester->u8[2], requester->u8[3]); +#endif /* UIP_CONF_IPV6 */ + + log_message(buf, file); +#endif /* LOG_CONF_ENABLED */ +} +/*---------------------------------------------------------------------------*/ +void +webserver_log(char *msg) +{ + log_message(msg, ""); +} +/*---------------------------------------------------------------------------*/ diff --git a/apps/webserver-nano/webserver-nogui.h b/apps/webserver-nano/webserver-nogui.h new file mode 100644 index 000000000..b362a8d29 --- /dev/null +++ b/apps/webserver-nano/webserver-nogui.h @@ -0,0 +1,45 @@ +/* + * 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 Contiki OS + * + * $Id: webserver-nogui.h,v 1.4 2008/10/14 11:07:57 adamdunkels Exp $ + * + */ +#ifndef __WEBSERVER_NOGUI_H__ +#define __WEBSERVER_NOGUI_H__ + +#include "contiki-net.h" + +PROCESS_NAME(webserver_nogui_process); + +void webserver_log(char *msg); +void webserver_log_file(uip_ipaddr_t *requester, char *file); + +#endif /* __WEBSERVER_H__ */ diff --git a/apps/webserver-nano/webserver.c b/apps/webserver-nano/webserver.c new file mode 100644 index 000000000..8e6b8e9aa --- /dev/null +++ b/apps/webserver-nano/webserver.c @@ -0,0 +1,127 @@ +/* + * 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 Contiki desktop environment for the C64. + * + * $Id: webserver.c,v 1.5 2008/02/08 22:53:32 oliverschmidt Exp $ + * + */ + +#include +#include + +#include "contiki.h" +#include "ctk/ctk.h" + +#include "http-strings.h" +#include "webserver.h" +#include "httpd.h" + +/* The main window. */ +static struct ctk_window mainwindow; + +static struct ctk_label message = + {CTK_LABEL(0, 0, 15, 1, "Latest requests")}; + +PROCESS(webserver_process, "Web server"); + +AUTOSTART_PROCESSES(&webserver_process); + +#define LOG_WIDTH 38 +#define LOG_HEIGHT 16 +static char log[LOG_WIDTH*LOG_HEIGHT]; + +static struct ctk_label loglabel = +{CTK_LABEL(0, 1, LOG_WIDTH, LOG_HEIGHT, log)}; +/*-----------------------------------------------------------------------------------*/ +PROCESS_THREAD(webserver_process, ev, data) +{ + PROCESS_BEGIN(); + + ctk_window_new(&mainwindow, LOG_WIDTH, LOG_HEIGHT+1, "Web server"); + + CTK_WIDGET_ADD(&mainwindow, &message); + CTK_WIDGET_ADD(&mainwindow, &loglabel); + + httpd_init(); + + ctk_window_open(&mainwindow); + + while(1) { + PROCESS_WAIT_EVENT(); + + if(ev == ctk_signal_window_close || + ev == PROCESS_EVENT_EXIT) { + ctk_window_close(&mainwindow); + process_exit(&webserver_process); + LOADER_UNLOAD(); + } else if(ev == tcpip_event) { + httpd_appcall(data); + } + } + + PROCESS_END(); +} +/*-----------------------------------------------------------------------------------*/ +void +webserver_log_file(uip_ipaddr_t *requester, char *file) +{ + int size; + + /* Scroll previous entries upwards */ + memcpy(log, &log[LOG_WIDTH], LOG_WIDTH * (LOG_HEIGHT - 1)); + + /* Print out IP address of requesting host. */ + size = sprintf(&log[LOG_WIDTH * (LOG_HEIGHT - 1)], + "%d.%d.%d.%d: ", + requester->u8[0], + requester->u8[1], + requester->u8[2], + requester->u8[3]); + + /* Copy filename into last line. */ + strncpy(&log[LOG_WIDTH * (LOG_HEIGHT - 1) + size], file, LOG_WIDTH - size); + + /* Update log display. */ + CTK_WIDGET_REDRAW(&loglabel); +} +/*-----------------------------------------------------------------------------------*/ +void +webserver_log(char *msg) +{ + /* Scroll previous entries upwards */ + memcpy(log, &log[LOG_WIDTH], LOG_WIDTH * (LOG_HEIGHT - 1)); + + /* Copy filename into last line. */ + strncpy(&log[LOG_WIDTH * (LOG_HEIGHT - 1)], msg, LOG_WIDTH); + + /* Update log display. */ + CTK_WIDGET_REDRAW(&loglabel); +} +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/webserver-nano/webserver.h b/apps/webserver-nano/webserver.h new file mode 100644 index 000000000..ead46dc53 --- /dev/null +++ b/apps/webserver-nano/webserver.h @@ -0,0 +1,45 @@ +/* + * 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 Contiki operating system + * + * $Id: webserver.h,v 1.2 2007/04/23 21:19:55 oliverschmidt Exp $ + * + */ +#ifndef __WEBSERVER_H__ +#define __WEBSERVER_H__ + +#include "contiki-net.h" + +PROCESS_NAME(webserver_process); + +void webserver_log(char *msg); +void webserver_log_file(uip_ipaddr_t *requester, char *file); + +#endif /* __WEBSERVER_H__ */ diff --git a/tools/makefsdata b/tools/makefsdata index 0b81b473f..893bb79d2 100755 --- a/tools/makefsdata +++ b/tools/makefsdata @@ -166,7 +166,7 @@ if ($coffee) { print "Processing directory $directory as root of packed httpd-fs file system\n"; } opendir(DIR, "."); -@files = grep { !/^\./ && !/(CVS|~)/ } readdir(DIR); +@files = grep { !/^\./ && !/(CVS|~)/ && !/(makefsdata.ignore)/ } readdir(DIR); closedir(DIR); foreach $file (@files) {