static PT_THREAD(handle_output(struct httpd_state *s)) { PT_BEGIN(&s->outputpt); s->script = httpd_cgi(&s->filename[1]); if(!s->script) { httpd_cgi_command_t *cmd = httpd_cgi_command(&s->filename[1]); if(cmd) { s->script = cmd->function(s); } } if(s->script) { if((s->script->flags & HTTPD_CUSTOM_HEADER) == 0) { PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_200)); } if((s->script->flags & HTTPD_CUSTOM_TOP) == 0) { PT_WAIT_THREAD(&s->outputpt, generate_top(s)); } PT_WAIT_THREAD(&s->outputpt, s->script->function(s)); if((s->script->flags & HTTPD_CUSTOM_BOTTOM) == 0) { PT_WAIT_THREAD(&s->outputpt, generate_bottom(s)); } #if CONTIKI_TARGET_NATIVE } else if (httpd_is_file(s->filename)){ PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_200)); PT_WAIT_THREAD(&s->outputpt, send_file(s)); #endif } else { LOG6LBR_6ADDR(WARN, &uip_conn->ripaddr, "File '%s' not found, from ", s->filename); PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_404)); PT_WAIT_THREAD(&s->outputpt, generate_404(s)); } PSOCK_CLOSE(&s->sout); PT_END(&s->outputpt); }
/*---------------------------------------------------------------------------*/ static PT_THREAD(handle_script(struct httpd_state *s)) { char *ptr; PT_BEGIN(&s->scriptpt); while(s->file.len > 0) { /* Check if we should start executing a script. */ if(*s->file.data == ISO_percent && *(s->file.data + 1) == ISO_bang) { s->scriptptr = s->file.data + 3; s->scriptlen = s->file.len - 3; if(*(s->scriptptr - 1) == ISO_colon) { httpd_fs_open(s->scriptptr + 1, &s->file); PT_WAIT_THREAD(&s->scriptpt, send_file(s)); } else { // Httpd_cgi is called here PT_WAIT_THREAD(&s->scriptpt, httpd_cgi(s->scriptptr)(s, s->scriptptr)); } next_scriptstate(s); /* The script is over, so we reset the pointers and continue sending the rest of the file. */ s->file.data = s->scriptptr; s->file.len = s->scriptlen; } else { /* See if we find the start of script marker in the block of HTML to be sent. */ if(s->file.len > uip_mss()) { s->len = uip_mss(); } else { s->len = s->file.len; } if(*s->file.data == ISO_percent) { ptr = strchr(s->file.data + 1, ISO_percent); } else { ptr = strchr(s->file.data, ISO_percent); } if(ptr != NULL && ptr != s->file.data) { s->len = (int)(ptr - 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 PT_THREAD(handle_script(struct httpd_state *s)) { PGM_P ptr; PT_BEGIN(&s->scriptpt); while(s->file.len > 0) { /* Check if we should start executing a script. */ if(pgm_read_byte_near(s->file.data) == ISO_percent && pgm_read_byte_near(s->file.data + 1) == ISO_bang) { s->scriptptr = s->file.data + 3; s->scriptlen = s->file.len - 3; if(pgm_read_byte_near(s->scriptptr - 1) == ISO_colon) { strncpy_P(s->tmp_str, s->scriptptr + 1, sizeof(s->tmp_str) -1); if(httpd_fs_open(s->tmp_str, &s->file) || httpd_fs_open(s->tmp_str + 1 , &s->file)) { PT_WAIT_THREAD(&s->scriptpt, send_file(s)); } else { // could not open the file. } } else { strncpy_P(s->tmp_str, s->scriptptr, sizeof(s->tmp_str) -1); ((s->tmp_str)[sizeof(s->tmp_str) - 1]) = '\0'; PT_WAIT_THREAD(&s->scriptpt, httpd_cgi(s->tmp_str)(s, s->tmp_str)); } next_scriptstate(s); /* The script is over, so we reset the pointers and continue sending the rest of the file. */ s->file.data = s->scriptptr; s->file.len = s->scriptlen; } else { /* See if we find the start of script marker in the block of HTML to be sent. */ if(s->file.len > uip_mss()) { s->len = uip_mss(); } else { s->len = s->file.len; } if(pgm_read_byte_near(s->file.data) == ISO_percent) { ptr = strchr_P(s->file.data + 1, ISO_percent); } else { ptr = strchr_P(s->file.data, ISO_percent); } if(ptr != NULL && ptr != s->file.data) { s->len = (int)(ptr - 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); /* PGM_P ptr; PT_BEGIN(&s->scriptpt); while(s->file.len > 0) { // Check if we should start executing a script. if( (pgm_read_byte(s->file.data) == ISO_percent) && (pgm_read_byte(s->file.data + 1) == ISO_bang)) { s->scriptptr = s->file.data + 3; s->scriptlen = s->file.len - 3; if(pgm_read_byte(s->scriptptr - 1) == ISO_colon) { strncpy_P(s->tmp_str, s->scriptptr + 1, sizeof(s->tmp_str) -1); if (httpd_fs_open(s->tmp_str, &s->file)) { PT_WAIT_THREAD(&s->scriptpt, send_file(s)); } } else { PT_WAIT_THREAD(&s->scriptpt, httpd_cgi(s->scriptptr)(s, s->scriptptr)); } next_scriptstate(s); // The script is over, so we reset the pointers and continue // sending the rest of the file. s->file.data = s->scriptptr; s->file.len = s->scriptlen; } else { // See if we find the start of script marker in the block of HTML // to be sent. if(s->file.len > uip_mss()) { s->len = uip_mss(); } else { s->len = s->file.len; } if(pgm_read_byte(s->file.data) == ISO_percent) { ptr = strchr_P(s->file.data + 1, ISO_percent); } else { ptr = strchr_P(s->file.data, ISO_percent); } if(ptr != NULL && ptr != s->file.data) { s->len = (int)(ptr - 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 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); PRINTF("httpd: Handle script named %s\n",scriptname); if(scriptname[0] == ISO_colon) { if (httpd_fs_open(&scriptname[1], &s->file)) { PT_WAIT_THREAD(&s->scriptpt, send_file(s)); } } else { PT_WAIT_THREAD(&s->scriptpt,httpd_cgi(scriptname)(s, s->scriptptr)); } 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(); } } PRINTF("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); }
/** * Parses shtml document for possible script includes. * Accepts includes of the form '%! scriptname'. * * If scriptname starts with ':' it is assumed to be an SSI, * otherwise it will be handled as CGI call. */ static PT_THREAD(handle_scripts(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; static int done, eof, eoc; PT_BEGIN(&s->scriptpt); eoc = eof = done = 0; /* Init cache (null-terminated)*/ load_cache(s); while (!done) { /* Assure we can read at least a '%!' sequence. */ // if (cache_size() < 2) { // reload_cache(s); // } /* Check if we should start executing a script, flagged by %! */ if (file_cache_ptr[0] == ISO_percent && file_cache_ptr[1] == ISO_bang) { /* Test if a whole line is in cache, otherwise reload cache. */ if (strchr(&file_cache_ptr[2], ISO_nl) == NULL) { reload_cache(s); } /* Extract name, if starts with colon include file else call cgi */ s->scriptptr = get_scriptname(scriptname, &file_cache_ptr[2]); // s->scriptlen = files[s->fd].len - (s->scriptptr - file_cache_ptr[0]); PRINTD("httpd: Handle script named %s\n", scriptname); /* Include scripts prefixed with ':' are SSI else CGI scripts */ if (scriptname[0] == ISO_colon) { #if WEBSERVER_CONF_INCLUDE PRINTD("IS SSI\n"); s->scriptfd = httpd_fs_open(&scriptname[1], HTTPD_FS_READ); /* Send script if open succeeded. */ if (s->scriptfd != -1) { s->sendfd = s->scriptfd; PT_WAIT_THREAD(&s->scriptpt, send_file(s)); } else { PRINTD("failed opening %s\n", scriptname); } httpd_fs_close(s->scriptfd); /*TODO dont print anything if file not found */ #endif /* Execute unprefixed scripts. */ } else { PRINTD("IS CGI\n"); #if WEBSERVER_CONF_CGI PT_WAIT_THREAD(&s->scriptpt, httpd_cgi(scriptname)(s, s->scriptptr)); #endif } skip_scriptline(s); file_cache_ptr = s->scriptptr; if (cache_size() < 2) { reload_cache(s); } if (cache_size() == 0) { done = 1; } } else { // no script /* get position of next percent character */ if (file_cache_ptr[0] == ISO_percent) { pptr = (char *) strchr(&file_cache_ptr[1], ISO_percent); } else { pptr = (char *) strchr(&file_cache_ptr[0], ISO_percent); } /* calc new length to send */ if (pptr == NULL) { /* no further percent sign found in cache. */ /* Send to end of cache */ s->sendlen = cache_len - (&file_cache_ptr[0] - &file_cache_array[0]); eoc = 1;// inidcates thate we need new cache } else { s->sendlen = (int) ((int) pptr - (int) &file_cache_ptr[0]); } if (s->sendlen > 0) { PRINTD("httpd: Sending %u bytes from 0x%04x\n", s->sendlen, (unsigned int) pptr); s->sendfd = s->fd; PT_WAIT_THREAD(&s->scriptpt, send_part_of_cache(s)); } /* Reload cache if it was marked as empty. */ if (eoc) { reload_cache(s); } /* If (reloaded) cache empty, stop sending */ if (cache_size() == 0) { done = 1; } } } PT_END(&s->scriptpt); }