示例#1
0
/*---------------------------------------------------------------------------*/
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, CFS_READ);
  petsciiconv_toascii(s->filename, sizeof(s->filename));
  if(s->fd < 0) {
    strcpy(s->filename, "notfound.html");
    s->fd = cfs_open(s->filename, CFS_READ);
    petsciiconv_toascii(s->filename, sizeof(s->filename));
    if(s->fd < 0) {
      PT_WAIT_THREAD(&s->outputpt,
                     send_headers(s, http_header_404));
      PT_WAIT_THREAD(&s->outputpt,
                     send_string(s, "not found"));
      uip_close();
      webserver_log_file(&uip_conn->ripaddr, "404 (no notfound.html)");
      PT_EXIT(&s->outputpt);
    }
    PT_WAIT_THREAD(&s->outputpt,
		   send_headers(s, http_header_404));
    webserver_log_file(&uip_conn->ripaddr, "404 - notfound.html");
  } 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);
}
示例#2
0
static
PT_THREAD(handle_output(struct httpd_state *s))
{
  PT_BEGIN(&s->outputpt);

  s->script = NULL;
  s->script = httpd_simple_get_script(&s->filename[1]);
  if(s->script == NULL) {
    strncpy(s->filename, "/notfound.html", sizeof(s->filename));
    PT_WAIT_THREAD(&s->outputpt,
                   send_headers(s, http_header_404));
    PT_WAIT_THREAD(&s->outputpt,
                   send_string(s, NOT_FOUND));
    uip_close();
    webserver_log_file(&uip_conn->ripaddr, "404 - not found");
    PT_EXIT(&s->outputpt);
  } else {
    PT_WAIT_THREAD(&s->outputpt,
                   send_headers(s, http_header_200));
    PT_WAIT_THREAD(&s->outputpt, s->script(s));
  }
  s->script = NULL;
  PSOCK_CLOSE(&s->sout);
  PT_END(&s->outputpt);
}
示例#3
0
/*---------------------------------------------------------------------------*/
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();
  }
}
示例#4
0
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);
}
示例#5
0
/*---------------------------------------------------------------------------*/
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);
}
示例#6
0
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);
}
示例#7
0
/*---------------------------------------------------------------------------*/
void
httpd_appcall(void *state)
{
#if DEBUGLOGIC
  struct httpd_state *s;   //Enter here for debugging with output directed to TCPBUF
  s = sg = (struct httpd_state *)memb_alloc(&conns);  //put ram watch on sg
  if (1) {
#else
  struct httpd_state *s = (struct httpd_state *)state;

  if(uip_closed() || uip_aborted() || uip_timedout()) {
    if(s != NULL) {
      s->script = NULL;
      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;
    }
#endif
    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->script = NULL;
    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();
        s->script = NULL;
        memb_free(&conns, s);
        webserver_log_file(&uip_conn->ripaddr, "reset (timeout)");
      }
    } else {
      timer_restart(&s->timer);
    }
    handle_connection(s);
  } else {
    uip_abort();
  }
}
/*---------------------------------------------------------------------------*/
PROCESS(httpd_process, "httpd");
PROCESS_THREAD(httpd_process, ev, data)
{
  PROCESS_BEGIN();

  httpd_init();

  while(1) {
    PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event);
    httpd_appcall(data);
  }

  PROCESS_END();
}
示例#8
0
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);
}
示例#9
0
/*-----------------------------------------------------------------------------------*/
DISPATCHER_UIPCALL(httpd_appcall, state)
{
  struct httpd_fs_file fsfile;  
  u8_t i;
  DISPATCHER_UIPCALL_ARG(state);

  hs = (struct httpd_state *)(state);
  
  /* We use the uip_ test functions to deduce why we were
     called. If uip_connected() is non-zero, we were called
     because a remote host has connected to us. If
     uip_newdata() is non-zero, we were called because the
     remote host has sent us new data, and if uip_acked() is
     non-zero, the remote host has acknowledged the data we
     previously sent to it. */
  if(uip_connected()) {

    /* Since we've just been connected, the state pointer should be
       NULL and we need to allocate a new state object. If we have run
       out of memory for state objects, we'll have to abort the
       connection and return. */
    if(hs == NULL) {
      hs = alloc_state();
      if(hs == NULL) {
	uip_close();
	return;
      }
      dispatcher_markconn(uip_conn, (void *)hs);
    }
    /* Since we have just been connected with the remote host, we
       reset the state for this connection. The ->count variable
       contains the amount of data that is yet to be sent to the
       remote host, and the ->state is set to HTTP_NOGET to signal
       that we haven't received any HTTP GET request for this
       connection yet. */
    hs->state = HTTP_NOGET;
    hs->count = 0;
    hs->poll = 0;
  } else if(uip_closed() || uip_aborted()) {
    if(hs != NULL) {
      dealloc_state(hs);
    }
    return;
  } else if(uip_poll()) {
    /* If we are polled ten times, we abort the connection. This is
       because we don't want connections lingering indefinately in
       the system. */
    if(hs != NULL) {
      if(hs->state == HTTP_DEALLOCATED) {
	uip_abort();
      } else if(hs->poll++ >= 100) {
	uip_abort();
	dealloc_state(hs);
      }
    }
    return;
  }


  if(uip_newdata() && hs->state == HTTP_NOGET) {
    hs->poll = 0;
    /* This is the first data we receive, and it should contain a
       GET. */
      
    /* Check for GET. */
    if(uip_appdata[0] != ISO_G ||
       uip_appdata[1] != ISO_E ||
       uip_appdata[2] != ISO_T ||
       uip_appdata[3] != ISO_space) {
      /* If it isn't a GET, we abort the connection. */
      uip_abort();
      dealloc_state(hs);
      return;
    }

    beep();
    
    /* Find the file we are looking for. */
    for(i = 4; i < 40; ++i) {
      if(uip_appdata[i] == ISO_space ||
	 uip_appdata[i] == ISO_cr ||
	 uip_appdata[i] == ISO_nl) {
	uip_appdata[i] = 0;
	break;
      }
    }

    PRINT("request for file ");
    PRINTLN(&uip_appdata[4]);
    webserver_log_file(uip_conn->ripaddr, &uip_appdata[4]);
    /* Check for a request for "/". */
    if(uip_appdata[4] == ISO_slash &&
       uip_appdata[5] == 0) {
      httpd_fs_open(file_index_html.name, &fsfile);    
    } else {
      if(!httpd_fs_open((const char *)&uip_appdata[4], &fsfile)) {
	PRINTLN("couldn't open file");
	httpd_fs_open(file_404_html.name, &fsfile);
      }
    } 

    if(uip_appdata[4] == ISO_slash &&
       uip_appdata[5] == ISO_c &&
       uip_appdata[6] == ISO_g &&
       uip_appdata[7] == ISO_i &&
       uip_appdata[8] == ISO_slash) {
      /* If the request is for a file that starts with "/cgi/", we
	 prepare for invoking a script. */	
      hs->script = fsfile.data;
      next_scriptstate();
    } else {
      hs->script = NULL;
      /* The web server is now no longer in the HTTP_NOGET state, but
	 in the HTTP_FILE state since is has now got the GET from
	 the client and will start transmitting the file. */
      hs->state = HTTP_FILE;

      /* Point the file pointers in the connection state to point to
	 the first byte of the file. */
      hs->dataptr = fsfile.data;
      hs->count = fsfile.len;	
    }     
  }

    
  if(hs->state != HTTP_FUNC) {
    /* Check if the client (remote end) has acknowledged any data that
       we've previously sent. If so, we move the file pointer further
       into the file and send back more data. If we are out of data to
       send, we close the connection. */
    if(uip_acked()) {
      hs->poll = 0;	
      if(hs->count >= uip_mss()) {
	hs->count -= uip_mss();
	hs->dataptr += uip_mss();
      } else {
	hs->count = 0;
      }
	
      if(hs->count == 0) {
	if(hs->script != NULL) {
	  next_scriptline();
	  next_scriptstate();
	} else {
	  uip_close();
	  dealloc_state(hs);
	}
      }
    }         
  }
    
  if(hs->state == HTTP_FUNC) {
    /* Call the CGI function. */
#if 1
    if(httpd_cgitab[hs->script[2] - ISO_a]()) {
      /* If the function returns non-zero, we jump to the next line
	 in the script. */
      next_scriptline();
      next_scriptstate();
    }
#endif
  }

  if(hs->state != HTTP_FUNC && !uip_poll()) {
    hs->poll = 0;
    /* Send a piece of data, but not more than the MSS of the
       connection. */
    uip_send(hs->dataptr,
	     hs->count > uip_mss()? uip_mss(): hs->count);
  }

  /* Finally, return to uIP. Our outgoing packet will soon be on its
     way... */
}
示例#10
0
/*---------------------------------------------------------------------------*/
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);
}