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) { PSOCK_GENERATOR_SEND(&s->sout, generate_header, &httpd_mime_htm ); } else if(ptr == NULL) { PSOCK_GENERATOR_SEND(&s->sout, generate_header, &httpd_mime_bin ); } else { ptr++; if(httpd_strncmp(ptr, &httpd_mime_htm[5],3)== 0 ||httpd_strncmp(ptr, &httpd_shtml[1], 4) == 0) { PSOCK_GENERATOR_SEND(&s->sout, generate_header, &httpd_mime_htm ); } else if(httpd_strcmp(ptr, &httpd_mime_css[5]) == 0) { PSOCK_GENERATOR_SEND(&s->sout, generate_header, &httpd_mime_css ); } else if(httpd_strcmp(ptr, &httpd_mime_png[6]) == 0) { PSOCK_GENERATOR_SEND(&s->sout, generate_header, &httpd_mime_png ); } else if(httpd_strcmp(ptr, &httpd_mime_gif[6])== 0) { PSOCK_GENERATOR_SEND(&s->sout, generate_header, &httpd_mime_gif ); } else if(httpd_strcmp(ptr, httpd_mime_jpg) == 0) { PSOCK_GENERATOR_SEND(&s->sout, generate_header, &httpd_mime_jpg ); } else { PSOCK_GENERATOR_SEND(&s->sout, generate_header, &httpd_mime_txt); } } PSOCK_END(&s->sout); }
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)); { /* Look for ?, if found strip file name and send any following text to the LCD */ uint8_t i; for (i=0;i<sizeof(s->inputbuf);i++) { if (s->inputbuf[i]=='?') { raven_lcd_show_text(&s->inputbuf[i]); if (i<sizeof(s->filename)) s->filename[i]=0; // s->inputbuf[i]=0; //allow multiple beeps with multiple ?'s } if (s->inputbuf[i]==0) break; } } } webserver_log_file(&uip_conn->ripaddr, s->filename); s->state = STATE_OUTPUT; while(1) { PSOCK_READTO(&s->sin, ISO_nl); 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); } } PSOCK_END(&s->sin); }
static PT_THREAD(handle_output(struct httpd_state *s)) { char *ptr; PT_BEGIN(&s->outputpt); #if DEBUGLOGIC httpd_strcpy(s->filename,httpd_indexfn); #endif if(!httpd_fs_open(s->filename, &s->file)) { 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 { PT_WAIT_THREAD(&s->outputpt, send_headers(s, httpd_200ok)); 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 { PT_WAIT_THREAD(&s->outputpt, send_file(s)); } } PSOCK_CLOSE(&s->sout); PT_END(&s->outputpt); }
/*---------------------------------------------------------------------------*/ 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; }
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)); } webserver_log_file(&uip_conn->ripaddr, s->filename); s->state = STATE_OUTPUT; while(1) { PSOCK_READTO(&s->sin, ISO_nl); 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); } } PSOCK_END(&s->sin); }
static PT_THREAD(handle_output(struct httpd_state *s)) { char *ptr; PT_BEGIN(&s->outputpt); #if DEBUGLOGIC httpd_strcpy(s->filename,httpd_indexfn); #endif if(!httpd_fs_open(s->filename, &s->file)) { 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 { PRINTF("s->state: %d\r\n", s->state); if(s->state == STATE_OUTPUT) { PT_WAIT_THREAD(&s->outputpt, send_headers(s, httpd_200ok)); 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 { PT_WAIT_THREAD(&s->outputpt, send_file(s)); } } else { // state == STATE_OUTPUT_ERROR if(s->error_number == 413) { // Send the error message file instead. httpd_strcpy(s->filename, httpd_413fn); httpd_fs_open(s->filename, &s->file); PT_WAIT_THREAD(&s->outputpt, send_headers(s, httpd_413error)); PT_WAIT_THREAD(&s->outputpt, send_file(s)); } // other error messages can be added here. } } PSOCK_CLOSE(&s->sout); PT_END(&s->outputpt); }
static PT_THREAD(handle_input(struct httpd_state *s)) { int found = 0; PSOCK_BEGIN(&s->sin); PSOCK_READTO(&s->sin, ISO_space); if(httpd_strncmp(s->inputbuf, httpd_get, 4) == 0) { 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)); /* Look for ?, if found strip file name and send any following text to the LCD */ uint8_t i; for (i=0;i<sizeof(s->inputbuf);i++) { if (s->inputbuf[i]=='?') { if (i<sizeof(s->filename)) s->filename[i]=0; // s->inputbuf[i]=0; //allow multiple beeps with multiple ?'s } if (s->inputbuf[i]==0) break; } } } else if(httpd_strncmp(s->inputbuf, httpd_post, 5) == 0) { PSOCK_READTO(&s->sin, ISO_space); if(s->inputbuf[0] != ISO_slash) { PSOCK_CLOSE_EXIT(&s->sin); } if (httpd_strncmp(&s->inputbuf[1], httpd_config_file, sizeof(httpd_config_file)-1) == 0) { s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0; strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename)); /* Look for ?, if found strip file name*/ uint8_t i; for (i=0;i<sizeof(s->inputbuf);i++) { if (s->inputbuf[i]=='?') { if (i<sizeof(s->filename)) s->filename[i]=0; } if (s->inputbuf[i]==0) break; } //parse config data found = 0; //look for the combination "\r\n\r\n"; the post data follow thereafter while (!found) { PSOCK_READTO(&s->sin, ISO_nl); PSOCK_READTO(&s->sin, ISO_cr); if (PSOCK_DATALEN(&s->sin) == 1) { PSOCK_READTO(&s->sin, ISO_nl); found=1; } } PSOCK_READTO(&s->sin, ISO_equal); //check for domain_name PSOCK_READTO(&s->sin, ISO_amper); if(s->inputbuf[0] != ISO_amper) { char tmp[nvm_size(domain_name)]; memset(tmp, 0, sizeof (tmp)); memcpy(tmp, s->inputbuf, PSOCK_DATALEN(&s->sin) - 1); nvm_write_block(domain_name, tmp, sizeof(tmp)); } PSOCK_READTO(&s->sin, ISO_equal); //check for relay_default_state PSOCK_READTO(&s->sin, ISO_amper); if(s->inputbuf[0] == '1') set_relay_default(0); else if (s->inputbuf[0] == '0') set_relay_default(1); #if S0_ENABLE PSOCK_READTO(&s->sin, ISO_equal); //check for s0 calibration value PSOCK_READTO(&s->sin, ISO_amper); if(s->inputbuf[0] != ISO_amper) { metering_set_s0_calibration((uint16_t)atoi(s->inputbuf)); } #endif } else if (httpd_strncmp(&s->inputbuf[1], httpd_socket_status_file, sizeof(httpd_socket_status_file)-1) == 0) { // toggle button has been pressed s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0; strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename)); /* Look for ?, if found strip file name*/ uint8_t i; for (i=0;i<sizeof(s->inputbuf);i++) { if (s->inputbuf[i]=='?') { if (i<sizeof(s->filename)) s->filename[i]=0; } if (s->inputbuf[i]==0) break; } relay_toggle(); } else { PSOCK_CLOSE_EXIT(&s->sin); } } else { PSOCK_CLOSE_EXIT(&s->sin); } webserver_log_file(&uip_conn->ripaddr, s->filename); s->state = (s->state == STATE_ERROR) ? STATE_OUTPUT_ERROR : STATE_OUTPUT; while(1) { PSOCK_READTO(&s->sin, ISO_nl); 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); } } PSOCK_END(&s->sin); }
/*---------------------------------------------------------------------------*/ 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_str_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); } /*---------------------------------------------------------------------------*/ static PT_THREAD(handle_output(struct httpd_state *s)) { char *ptr; PT_BEGIN(&s->outputpt); #if DEBUGLOGIC httpd_strcpy(s->filename, httpd_str_indexfn); #endif s->fd = httpd_fs_open(s->filename, HTTPD_FS_READ); if (s->fd == -1) { // Opening file failed. /* TODO: try index.htm ? */ #if WEBSERVER_CONF_INCLUDE || WEBSERVER_CONF_CGI /* If index.html not found try index.htm */ if (httpd_strcmp(s->filename, httpd_str_indexfn) == 0) { httpd_strcpy(s->filename, httpd_str_indexfn3); } s->fd = httpd_fs_open(s->filename, HTTPD_FS_READ); if (s->fd != -1) { goto sendfile; } /* If index.html not found try index.shtml */ if (httpd_strcmp(s->filename, httpd_str_indexfn) == 0) { httpd_strcpy(s->filename, httpd_str_indexsfn); } s->fd = httpd_fs_open(s->filename, HTTPD_FS_READ); if (s->fd == -1) { PRINTD("Opening %s failed\n", s->filename); goto psock_close; } else { goto sendfile; } #endif /* If nothing was found, send 404 page */ httpd_strcpy(s->filename, httpd_str_404fn); s->fd = httpd_fs_open(s->filename, HTTPD_FS_READ); PT_WAIT_THREAD(&s->outputpt, send_headers(s, httpd_str_404notf)); PT_WAIT_THREAD(&s->outputpt, send_file(s)); } else { // Opening file succeeded. sendfile: PT_WAIT_THREAD(&s->outputpt, send_headers(s, httpd_str_200ok)); #if WEBSERVER_CONF_INCLUDE || WEBSERVER_CONF_CGI /* If filename ends with .shtml, scan file for script includes or cgi */ ptr = strchr(s->filename, ISO_period); if ((ptr != NULL && httpd_strncmp(ptr, httpd_str_shtml, 6) == 0) || httpd_strcmp(s->filename, httpd_str_indexfn) == 0) { PT_INIT(&s->scriptpt); PT_WAIT_THREAD(&s->outputpt, handle_scripts(s)); } else { #else if (1) { #endif PT_WAIT_THREAD(&s->outputpt, send_file(s)); httpd_fs_close(s->fd); } } psock_close: PSOCK_CLOSE(<y & s->sout); PT_END(&s->outputpt); } /*---------------------------------------------------------------------------*/ #if WEBSERVER_CONF_PASSQUERY char httpd_query[WEBSERVER_CONF_PASSQUERY]; #endif 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_str_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_str_indexfn); } else { uint8_t i; for (i = 0; i<sizeof (s->filename) + 1; i++) { if (i >= (PSOCK_DATALEN(&s->sin) - 1)) break; if (s->inputbuf[i] == ISO_space) break; #if WEBSERVER_CONF_PASSQUERY /* Query string is left in the httpd_query buffer until zeroed by the application! */ if (s->inputbuf[i] == ISO_qmark) { strncpy(httpd_query, &s->inputbuf[i + 1], sizeof (httpd_query)); break; } #endif s->filename[i] = s->inputbuf[i]; } s->filename[i] = 0; } #if WEBSERVER_CONF_LOG webserver_log_file(&uip_conn->ripaddr, s->filename); // webserver_log(httpd_query); #endif #if WEBSERVER_CONF_LOADTIME s->pagetime = clock_time(); #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_str_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); }