Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

http.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2001, Swedish Institute of Computer Science.
00003  * All rights reserved. 
00004  *
00005  * Redistribution and use in source and binary forms, with or without 
00006  * modification, are permitted provided that the following conditions 
00007  * are met: 
00008  * 1. Redistributions of source code must retain the above copyright 
00009  *    notice, this list of conditions and the following disclaimer. 
00010  * 2. Redistributions in binary form must reproduce the above copyright 
00011  *    notice, this list of conditions and the following disclaimer in the 
00012  *    documentation and/or other materials provided with the distribution. 
00013  * 3. Neither the name of the Institute nor the names of its contributors 
00014  *    may be used to endorse or promote products derived from this software 
00015  *    without specific prior written permission. 
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
00027  * SUCH DAMAGE. 
00028  *
00029  * httpd.c
00030  *                     
00031  * Author : Adam Dunkels <adam@sics.se>                               
00032  *
00033  * CHANGELOG: this file has been modified by Sergio Perez Alcañiz <serpeal@disca.upv.es> 
00034  *            Departamento de Informática de Sistemas y Computadores          
00035  *            Universidad Politécnica de Valencia                             
00036  *            Valencia (Spain)    
00037  *            Date: March 2003                                          
00038  *
00039  */
00040 
00041 #include "http.h"
00042 #include <rtl_printf.h>
00043 #include "lwip/tcp.h"
00044 #include <string.h>
00045 #include "fs.h"
00046 // KERNEL INCLUDES
00047 #include <linux/module.h>
00048 #include <linux/kernel.h>
00049 
00050 struct http_state {
00051   char *file;
00052   u32_t left;
00053 };
00054 
00055 /*-----------------------------------------------------------------------------------*/
00056 static void
00057 conn_err(void *arg, err_t err)
00058 {
00059   struct http_state *hs;
00060 
00061   hs = arg;
00062   mem_free(hs);
00063 }
00064 /*-----------------------------------------------------------------------------------*/
00065 static void
00066 close_conn(struct tcp_pcb *pcb, struct http_state *hs)
00067 {
00068 
00069   tcp_arg(pcb, NULL);
00070   tcp_sent(pcb, NULL);
00071   tcp_recv(pcb, NULL);
00072   mem_free(hs);
00073   tcp_close(pcb);
00074 }
00075 /*-----------------------------------------------------------------------------------*/
00076 static void
00077 send_data(struct tcp_pcb *pcb, struct http_state *hs)
00078 {
00079   err_t err;
00080   u16_t len;
00081 
00082   /* We cannot send more data than space avaliable in the send
00083      buffer. */     
00084   if(tcp_sndbuf(pcb) < hs->left) {
00085     len = tcp_sndbuf(pcb);
00086   } else {
00087     len = hs->left;
00088   }
00089 
00090   err = tcp_write(pcb, hs->file, len, 0);
00091   
00092   if(err == ERR_OK) {
00093     hs->file += len;
00094     hs->left -= len;
00095   }
00096 }
00097 
00098 
00099 /*-----------------------------------------------------------------------------------*/
00100 static err_t
00101 http_poll(void *arg, struct tcp_pcb *pcb)
00102 {
00103   if(arg == NULL) {
00104     /*    printf("Null, close\n");*/
00105     tcp_close(pcb);
00106   } else {
00107     send_data(pcb, (struct http_state *)arg);
00108   }
00109 
00110   return ERR_OK;
00111 }
00112 /*-----------------------------------------------------------------------------------*/
00113 static err_t
00114 http_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
00115 {
00116   struct http_state *hs;
00117 
00118   hs = arg;
00119 
00120   if(hs->left > 0) {    
00121     send_data(pcb, hs);
00122   } else {
00123     close_conn(pcb, hs);
00124   }
00125 
00126   return ERR_OK;
00127 }
00128 /*-----------------------------------------------------------------------------------*/
00129 static err_t
00130 http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
00131 {
00132   int i, j;
00133   char *data;
00134   char fname[40];
00135   struct fs_file file;
00136   struct http_state *hs;
00137 
00138   hs = arg;
00139 
00140   if(err == ERR_OK && p != NULL) {
00141 
00142     /* Inform TCP that we have taken the data. */
00143     tcp_recved(pcb, p->tot_len);
00144     
00145     if(hs->file == NULL) {
00146       data = p->payload;
00147       
00148       if(strncmp(data, "GET ", 4) == 0) {
00149         for(i = 0; i < 40; i++) {
00150           if(((char *)data + 4)[i] == ' ' ||
00151              ((char *)data + 4)[i] == '\r' ||
00152              ((char *)data + 4)[i] == '\n') {
00153             ((char *)data + 4)[i] = 0;
00154           }
00155         }
00156         i = 0;
00157         do {
00158           fname[i] = "/http"[i];
00159           i++;
00160         } while(fname[i - 1] != 0 && i < 40);
00161         i--;
00162         j = 0;
00163         do {
00164           fname[i] = ((char *)data + 4)[j];
00165           j++;
00166           i++;
00167         } while(fname[i - 1] != 0 && i < 40);
00168         pbuf_free(p);
00169         
00170         if(!fs_open(fname, &file)) {
00171           fs_open("/http/index.html", &file);
00172 //        fs_open("/index.shtml", &file);
00173         }
00174         hs->file = file.data;
00175         hs->left = file.len;
00176 
00177         send_data(pcb, hs);
00178 
00179         /* Tell TCP that we wish be to informed of data that has been
00180            successfully sent by a call to the http_sent() function. */
00181         tcp_sent(pcb, http_sent);
00182       } else {
00183         close_conn(pcb, hs);
00184       }
00185     } else {
00186       pbuf_free(p);
00187     }
00188   }
00189   
00190   
00191 
00192   if(err == ERR_OK && p == NULL) {
00193 
00194     close_conn(pcb, hs);
00195   }
00196   return ERR_OK;
00197 }
00198 /*-----------------------------------------------------------------------------------*/
00199 static err_t
00200 http_accept(void *arg, struct tcp_pcb *pcb, err_t err)
00201 {
00202   struct http_state *hs;
00203 
00204   /* Allocate memory for the structure that holds the state of the
00205      connection. */
00206   hs = mem_malloc(sizeof(struct http_state));
00207 
00208   if(hs == NULL) {
00209     rtl_printf("http_accept: Out of memory\n");
00210     return ERR_MEM;
00211   }
00212   
00213   /* Initialize the structure. */
00214   hs->file = NULL;
00215   hs->left = 0;
00216 
00217   /* Tell TCP that this is the structure we wish to be passed for our
00218      callbacks. */
00219   tcp_arg(pcb, hs);
00220 
00221   /* Tell TCP that we wish to be informed of incoming data by a call
00222      to the http_recv() function. */
00223   tcp_recv(pcb, http_recv);
00224 
00225   tcp_err(pcb, conn_err);
00226   
00227   tcp_poll(pcb, http_poll, 10);
00228   return ERR_OK;
00229 }
00230 /*-----------------------------------------------------------------------------------*/
00231 void
00232 httpd_init(void)
00233 {
00234   struct tcp_pcb *pcb;
00235 
00236   pcb = tcp_new();
00237   tcp_bind(pcb, IP_ADDR_ANY, 80);
00238   pcb = tcp_listen(pcb);
00239   tcp_accept(pcb, http_accept);
00240 }
00241 /*-----------------------------------------------------------------------------------*/
00242 
00243 
00244 /*-----------------------------------------------------------------------------------*/
00245 int init_module(void){
00246 
00247   printk("\nHTTP Daemon inserted\n");
00248   
00249   httpd_init();
00250   return 0;
00251 }
00252 
00253 /*-----------------------------------------------------------------------------------*/
00254 void cleanup_module(void){
00255   printk("\nHTTP Daemon removed\n");
00256 
00257 }

Generated on Wed Jan 14 12:58:56 2004 for RTL-lwIP-0.4 by doxygen 1.3.4