/* * 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 * * Modifications by Nancy Minderman and Bruce Cockburn * Added more documentation and the following functions * httpd_error * http_find_hdr_end * Completely rewrote http_thread to be more sane */ #include "lwip/sys.h" #include "lwip/api.h" #include "./net_apps.h" #define MAX_RQST_1K 1024 #define CR 0x0D #define LF 0x0A #define HTTP_PORT 80 const char header[] = "HTTP/1.1 200 OK\r\nConnection:close\r\nContent-Type: \ text/html\r\n\r\nCMPE401 Lab3 HTTP Server\

Welcome to CMPE401 Webserver!

\n"; char http_rqst[MAX_RQST_1K]; char http_fragment[MAX_RQST_1K]; /*-----------------------------------------------------------------------------------*/ /*Description: http_thread is analgous to a uC task. This thread handles * all of the server tasks for the webserver * Params: void *arg that is recreation for thread creation but unused * Returns:zip * SideEffects: Bunches of server related side effects, tcp/ip etc. * */ static void httpd_thread(void *arg) { struct netconn *conn, *newconn; err_t err; int i, j; /* Create a new connection identifier. */ conn = netconn_new(NETCONN_TCP); /* Bind connection to well known port for http. */ netconn_bind(conn, NULL, HTTP_PORT); /* Tell connection to go into listening mode. */ netconn_listen(conn); while(1){ /* Grab new connection. */ outstr("HTTPD: listening on http port ...\n\r"); newconn = netconn_accept(conn); outstr("HTTPD: accepted new connection\n\r"); /* Process the new connection. */ if(newconn != NULL){ struct netbuf *buf; void *data; u16_t len; http_rqst[0] = '\0'; http_fragment[0] = '\0'; while((buf = netconn_recv(newconn)) != NULL) { // traverse through the http request // do nothing except copy and cat until buf has been completely read do { netbuf_data(buf, &data, &len); if(len < MAX_RQST_1K - strlen(http_rqst)) { if (len < MAX_RQST_1K) { strncpy(http_fragment,data,len); http_fragment[len]= '\0'; strncat(http_rqst,http_fragment, MAX_RQST_1K); } } else { outstr("http_rqst full - Yikes!\n\r"); } } while(netbuf_next(buf) >= 0); if(httpd_find_hdr_end(http_rqst) == true) { // we have a complete http hdr request err = netconn_write(newconn,header,sizeof(header),NETCONN_COPY); if (err != ERR_OK) { httpd_error(err); } /* Close connection and discard connection identifier. */ /* at this time no more pages can be loaded until next connection request arrives */ netconn_delete(newconn); } netbuf_delete(buf); } } } } /*-----------------------------------------------------------------------------------*/ /* Description: http_init creates the thread (uC task) that runs the server * Params : zip * Returns: zip * Side Efects: uC prio taken and assinged to this thread(task) * */ void httpd_init(void) { sys_thread_new(httpd_thread, NULL, 0); } /*-----------------------------------------------------------------------------------*/ /* Description: httpd_error handles error reporting from lwip calls * Params: err_t -> error retunred from lwip call * Returns: zip * Side Effects: zip * */ void httpd_error(err_t error) { outstr("\n\rHTTPD: error during netconn_write: "); switch(error) { case ERR_MEM: outstr("out of memory\n\r"); break; case ERR_BUF: outstr("buffer error\n\r"); break; case ERR_ABRT: outstr("connection aborted\n\r"); break; case ERR_RST: outstr("connection reset\n\r"); break; case ERR_CLSD: outstr("connection closed\n\r"); break; case ERR_CONN: outstr("not connected\n\r"); break; case ERR_VAL: outstr("illegal value\n\r"); break; case ERR_ARG: outstr("illegal argument\n\r"); break; case ERR_RTE: outstr("Routing problem\n\r"); break; case ERR_USE: outstr("Address in use\n\r"); break; case ERR_IF: outstr("Low-level netif error\n\r"); break; default: outstr("Got unknown error \n\r"); } } /*----------------------------------------------------------------------------------- * Description: * httpd_find_hdr_end * This function determines if the http header delimiter is present in * null-terminated string passed in by reference * Params: pointer to an existing null-terminated string * Returns: int false if "\r\n\r\n" is not found in string * true if "\r\n\r\n" is found in string -----------------------------------------------------------------------------------*/ int httpd_find_hdr_end(char * pBuffer) { char * found; found = strstr(pBuffer, "\r\n\r\n"); if (found ){ return true; } else { return false; } }