All static strings to flash, add wildcard to file-stats cgi

This commit is contained in:
dak664 2009-06-19 17:11:28 +00:00
parent 6c30271ade
commit 17da57e989
9 changed files with 396 additions and 425 deletions

View file

@ -30,7 +30,7 @@
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: httpd.c,v 1.1 2009/03/12 19:15:25 adamdunkels Exp $
* $Id: httpd.c,v 1.2 2009/06/19 17:11:28 dak664 Exp $
*/
#include <string.h>
@ -40,8 +40,8 @@
#include "webserver.h"
#include "httpd-fs.h"
#include "httpd-cgi.h"
#include "lib/petsciiconv.h"
#include "http-strings.h"
//#include "lib/petsciiconv.h"
//#include "http-strings.h"
#include "httpd.h"
@ -54,10 +54,12 @@
#define STATE_WAITING 0
#define STATE_OUTPUT 1
#define SEND_STRING(s, str) PSOCK_SEND(s, (uint8_t *)str, (unsigned int)strlen(str))
//#define SEND_STRING(s, str) PSOCK_SEND(s, (uint8_t *)str, (unsigned int)strlen(str))
MEMB(conns, struct httpd_state, 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
@ -144,6 +146,23 @@ next_scriptstate(struct httpd_state *s)
s->scriptptr = p;*/
}
/*---------------------------------------------------------------------------*/
void
memcpy_P_trim(char *toram, char *fromflash)
{
uint8_t i;
for (i=0;i<19;) {
toram[i]=pgm_read_byte_near(fromflash++);
if (toram[i]==ISO_tab) {if (i) break; else continue;} //skip leading tabs
if (toram[i]==ISO_space) {if (i) break; else continue;} //skip leading spaces
if (toram[i]==ISO_nl) break; //nl is preferred delimiter
if (toram[i]==ISO_cr) break; //some editors insert cr
if (toram[i]==0) break; //files are terminated with null
i++;
}
toram[i]=0;
}
/*---------------------------------------------------------------------------*/
static char filenamebuf[25],*pptr;//See below!
static
@ -161,11 +180,10 @@ PT_THREAD(handle_script(struct httpd_state *s))
httpd_fs_getchar(s->file.data + 1) == ISO_bang) {
s->scriptptr = s->file.data + 3;
s->scriptlen = s->file.len - 3;
memcpy_P(filenamebuf, s->scriptptr, 25);
memcpy_P_trim(filenamebuf,s->scriptptr);
if(httpd_fs_getchar(s->scriptptr - 1) == ISO_colon) {
httpd_fs_open(filenamebuf + 1, &s->file);
httpd_fs_open(filenamebuf, &s->file);
PT_WAIT_THREAD(&s->scriptpt, send_file(s));
} else {
PT_WAIT_THREAD(&s->scriptpt,
@ -182,7 +200,7 @@ PT_THREAD(handle_script(struct httpd_state *s))
to be sent. */
if(s->file.len > uip_mss()) {
s->len = uip_mss();
s->len = uip_mss();
} else {
s->len = s->file.len;
}
@ -192,47 +210,82 @@ PT_THREAD(handle_script(struct httpd_state *s))
} 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();
}
if(pptr != NULL && pptr != s->file.data) {
s->len = (int)(pptr - s->file.data);
if(s->len >= uip_mss()) {
s->len = uip_mss();
}
}
PT_WAIT_THREAD(&s->scriptpt, send_part_of_file(s));
s->file.data += s->len;
s->file.len -= s->len;
}
}
PT_END(&s->scriptpt);
}
/*---------------------------------------------------------------------------*/
static unsigned short
generate_status_P(void *pstr)
{
uint8_t slen=strlen_P(pstr);
memcpy_P(uip_appdata, PSTR("HTTP/1.0 "), 9);
memcpy_P(uip_appdata+9, pstr, slen);
slen+=9;
memcpy_P(uip_appdata+slen, PSTR("\r\nServer: Contiki/2.0 http://www.sics.se/contiki/\r\nConnection: close\r\n"), 70);
return slen+70;
}
/*---------------------------------------------------------------------------*/
static unsigned short
generate_header_P(void *pstr)
{
uint8_t slen=strlen_P(pstr);
memcpy_P(uip_appdata,PSTR("Content-type: "),14);
memcpy_P(uip_appdata+14, pstr, slen);
slen+=14;
memcpy_P(uip_appdata+slen,PSTR("\r\n\r\n"),4);
return slen+4;
}
/*---------------------------------------------------------------------------*/
char http_htm[10] PROGMEM ="text/html";
char http_css[ 9] PROGMEM ="text/css";
char http_png[10] PROGMEM ="image/png";
char http_gif[10] PROGMEM ="image/gif";
char http_jpg[11] PROGMEM ="image/jpeg";
char http_txt[11] PROGMEM ="text/plain";
char http_shtml[ 6] PROGMEM =".shtml";
char index_html[12] PROGMEM ="/index.html";
static
PT_THREAD(send_headers(struct httpd_state *s, const char *statushdr))
PT_THREAD(send_headers(struct httpd_state *s, char *statushdr))
{
char *ptr;
PSOCK_BEGIN(&s->sout);
SEND_STRING(&s->sout, statushdr);
PSOCK_GENERATOR_SEND(&s->sout,generate_status_P,statushdr);
ptr = strrchr(s->filename, ISO_period);
if(ptr == NULL) {
SEND_STRING(&s->sout, http_content_type_binary);
} else if(strncmp(http_html, ptr, 5) == 0 ||
strncmp(http_shtml, ptr, 6) == 0) {
SEND_STRING(&s->sout, http_content_type_html);
} else if(strncmp(http_css, ptr, 4) == 0) {
SEND_STRING(&s->sout, http_content_type_css);
} else if(strncmp(http_png, ptr, 4) == 0) {
SEND_STRING(&s->sout, http_content_type_png);
} else if(strncmp(http_gif, ptr, 4) == 0) {
SEND_STRING(&s->sout, http_content_type_gif);
} else if(strncmp(http_jpg, ptr, 4) == 0) {
SEND_STRING(&s->sout, http_content_type_jpg);
if (pgm_read_byte_near(statushdr)=='4') {
PSOCK_GENERATOR_SEND(&s->sout, generate_header_P, http_htm);
} else if(ptr == NULL) {
PSOCK_GENERATOR_SEND(&s->sout, generate_header_P,PSTR("application/octet-stream"));
} else {
SEND_STRING(&s->sout, http_content_type_plain);
ptr++;
if(strncmp_P(ptr, &http_htm[5],3)== 0 ||strncmp_P(ptr, &http_shtml[1], 4) == 0) {
PSOCK_GENERATOR_SEND(&s->sout, generate_header_P, http_htm );
} else if(strcmp_P(ptr, &http_css[5]) == 0) {
PSOCK_GENERATOR_SEND(&s->sout, generate_header_P, http_css );
} else if(strcmp_P(ptr, &http_png[6]) == 0) {
PSOCK_GENERATOR_SEND(&s->sout, generate_header_P, http_png );
} else if(strcmp_P(ptr, &http_gif[6])== 0) {
PSOCK_GENERATOR_SEND(&s->sout, generate_header_P, http_gif );
} else if(strcmp_P(ptr, PSTR("jpg")) == 0) {
PSOCK_GENERATOR_SEND(&s->sout, generate_header_P, http_jpg );
} else {
PSOCK_GENERATOR_SEND(&s->sout, generate_header_P, http_txt);
}
}
PSOCK_END(&s->sout);
}
@ -243,40 +296,36 @@ PT_THREAD(handle_output(struct httpd_state *s))
char *ptr;
PT_BEGIN(&s->outputpt);
// strcpy(s->filename,"/index.html"); //for debugging
if(!httpd_fs_open(s->filename, &s->file)) {
httpd_fs_open(http_404_html, &s->file);
PT_WAIT_THREAD(&s->outputpt,
send_headers(s,
http_header_404));
PT_WAIT_THREAD(&s->outputpt,
send_file(s));
strcpy_P(s->filename, PSTR("/404.html"));
httpd_fs_open(s->filename, &s->file);
PT_WAIT_THREAD(&s->outputpt, send_headers(s, PSTR("404 Not found")));
PT_WAIT_THREAD(&s->outputpt, send_file(s));
} else {
PT_WAIT_THREAD(&s->outputpt,
send_headers(s,
http_header_200));
PT_WAIT_THREAD(&s->outputpt, send_headers(s, PSTR("200 OK")));
ptr = strchr(s->filename, ISO_period);
if(ptr != NULL && strncmp(ptr, http_shtml, 6) == 0 || strcmp_P(s->filename,PSTR("/index.html")) ==0) {
// if(ptr != NULL && strncmp(ptr, http_shtml, 6) == 0 ) {
if((ptr != NULL && strncmp_P(ptr, http_shtml, 6) == 0) || strcmp_P(s->filename,index_html)==0) {
PT_INIT(&s->scriptpt);
PT_WAIT_THREAD(&s->outputpt, handle_script(s));
} else {
PT_WAIT_THREAD(&s->outputpt,
send_file(s));
PT_WAIT_THREAD(&s->outputpt, send_file(s));
}
}
PSOCK_CLOSE(&s->sout);
PT_END(&s->outputpt);
}
/*---------------------------------------------------------------------------*/
char http_get[4] PROGMEM ="GET ";
char http_ref[8] PROGMEM ="Referer:";
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) {
if(strncmp_P(s->inputbuf, http_get, 4) != 0) {
PSOCK_CLOSE_EXIT(&s->sin);
}
PSOCK_READTO(&s->sin, ISO_space);
@ -286,26 +335,25 @@ PT_THREAD(handle_input(struct httpd_state *s))
}
if(s->inputbuf[1] == ISO_space) {
strncpy(s->filename, http_index_html, sizeof(s->filename));
strcpy_P(s->filename, index_html);
} else {
s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;
strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename));
}
webserver_log_file(&uip_conn->ripaddr, s->filename);
s->state = STATE_OUTPUT;
while(1) {
PSOCK_READTO(&s->sin, ISO_nl);
if(strncmp(s->inputbuf, http_referer, 8) == 0) {
if(strncmp_P(s->inputbuf, http_ref, 8) == 0) {
s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0;
petsciiconv_topetscii(s->inputbuf, PSOCK_DATALEN(&s->sin) - 2);
// petsciiconv_topetscii(s->inputbuf, PSOCK_DATALEN(&s->sin) - 2);
webserver_log(s->inputbuf);
}
}
PSOCK_END(&s->sin);
}
/*---------------------------------------------------------------------------*/