~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/net/khttpd/rfc.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2 
  3 kHTTPd -- the next generation
  4 
  5 RFC related functions (headers and stuff)
  6 
  7 */
  8 
  9 /****************************************************************
 10  *      This program is free software; you can redistribute it and/or modify
 11  *      it under the terms of the GNU General Public License as published by
 12  *      the Free Software Foundation; either version 2, or (at your option)
 13  *      any later version.
 14  *
 15  *      This program is distributed in the hope that it will be useful,
 16  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 17  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 18  *      GNU General Public License for more details.
 19  *
 20  *      You should have received a copy of the GNU General Public License
 21  *      along with this program; if not, write to the Free Software
 22  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 23  *
 24  ****************************************************************/
 25 
 26 
 27 #include <linux/kernel.h>
 28 
 29 #include <linux/ctype.h>
 30 #include <linux/errno.h>
 31 #include <linux/malloc.h>
 32 #include <linux/net.h>
 33 #include <linux/sched.h>
 34 #include <linux/skbuff.h>
 35 #include <linux/unistd.h>
 36 #include <linux/file.h>
 37 #include <linux/smp_lock.h>
 38 
 39 #include <net/ip.h>
 40 #include <net/sock.h>
 41 
 42 #include <asm/atomic.h>
 43 #include <asm/semaphore.h>
 44 #include <asm/processor.h>
 45 #include <asm/uaccess.h>
 46 
 47 
 48 #include "prototypes.h"
 49 #include "structure.h"
 50 #include "sysctl.h"
 51 
 52 
 53 #define KHTTPD_NUMMIMETYPES     40
 54 
 55 static atomic_t MimeCount;
 56 
 57 struct MimeType
 58 {
 59         __u32   identifier;
 60         char    type[64-sizeof(__u32)-sizeof(__kernel_size_t)];  
 61         __kernel_size_t len;
 62 };
 63 
 64 static struct MimeType  MimeTypes[KHTTPD_NUMMIMETYPES];
 65 
 66 
 67 void AddMimeType(const char *Ident,const char *Type)
 68 {       
 69         __u32   *I;
 70         
 71         EnterFunction("AddMimeType");
 72         
 73         if (strlen(Ident)!=4) 
 74         {       
 75                 (void)printk(KERN_ERR "httpd: Only 4-byte mime-identifiers are accepted\n");
 76                 return;
 77         }
 78 
 79         if (strlen(Type)>(64-sizeof(__u32)-sizeof(__kernel_size_t) ) )  
 80         {       
 81                 (void)printk(KERN_ERR "httpd: Mime-string too long.\n");
 82                 return;
 83         }
 84         
 85         I=(__u32*)Ident;
 86         
 87         /* FIXME: Need to lock-down all access to the mime-structure here */
 88         /*        For now, just don't add mime-types after initialisation */
 89         
 90         
 91         MimeTypes[atomic_read(&MimeCount)].identifier=*I;
 92         strncpy(MimeTypes[atomic_read(&MimeCount)].type,Type,(64-sizeof(__u32)-sizeof(__kernel_size_t)));
 93         MimeTypes[atomic_read(&MimeCount)].len = strlen(Type);
 94         
 95         atomic_inc(&MimeCount);
 96         LeaveFunction("AddMimeType");
 97 }
 98 
 99 
100 char *ResolveMimeType(const char *File,__kernel_size_t *Len)
101 /*
102 
103         The returned string is for READ ONLY, ownership of the memory is NOT
104         transfered.
105 
106 */
107 {       
108         __u32   *I;
109         int pos,lc,filelen;
110         
111         EnterFunction("ResolveMimeType");
112         
113         *Len = 0;
114         
115         if (File==NULL)
116                 return NULL;
117         
118         filelen = (int)strlen(File);
119         
120         if (filelen<4) 
121         {       
122                 return NULL;
123         }
124         
125         /* The Merced-people are NOT going to like this! So this has to be fixed
126            in a later stage. */
127 
128         pos = filelen-4;
129         I=(__u32*)(File+pos);
130         
131         lc=0;
132         
133         while (lc<atomic_read(&MimeCount))
134         {
135                 if (MimeTypes[lc].identifier == *I)
136                 {
137                         *Len = MimeTypes[lc].len;
138                         LeaveFunction("ResolveMimeType - success");
139                         return MimeTypes[lc].type;
140                 }
141                 lc++;
142         }       
143         
144         if (sysctl_khttpd_sloppymime)
145         {
146                 *Len = MimeTypes[0].len;  
147                 LeaveFunction("ResolveMimeType - unknown");
148                 return MimeTypes[0].type;
149         }
150         else
151         {
152                 LeaveFunction("ResolveMimeType - failure");
153                 return NULL;
154         }
155 }
156 
157 
158 static char HeaderPart1[] = "HTTP/1.0 200 OK\r\nServer: kHTTPd/0.1.6\r\nDate: ";
159 #ifdef BENCHMARK
160 static char HeaderPart1b[] ="HTTP/1.0 200 OK";
161 #endif
162 static char HeaderPart3[] = "\r\nContent-type: ";
163 static char HeaderPart5[] = "\r\nLast-modified: ";
164 static char HeaderPart7[] = "\r\nContent-length: ";
165 static char HeaderPart9[] = "\r\n\r\n";
166 
167 #ifdef BENCHMARK
168 /* In BENCHMARK-mode, just send the bare essentials */
169 void SendHTTPHeader(struct http_request *Request)
170 {
171         struct msghdr   msg;
172         mm_segment_t    oldfs;
173         struct iovec    iov[9];
174         int             len,len2;
175         
176         
177         EnterFunction("SendHTTPHeader");
178                 
179         msg.msg_name     = 0;
180         msg.msg_namelen  = 0;
181         msg.msg_iov      = &iov[0];
182         msg.msg_iovlen   = 6;
183         msg.msg_control  = NULL;
184         msg.msg_controllen = 0;
185         msg.msg_flags    = 0;  /* Synchronous for now */
186         
187         iov[0].iov_base = HeaderPart1b;
188         iov[0].iov_len  = 15;
189         iov[1].iov_base = HeaderPart3;
190         iov[1].iov_len  = 16;
191         iov[2].iov_base = Request->MimeType;
192         iov[2].iov_len  = Request->MimeLength;
193         
194         iov[3].iov_base = HeaderPart7;
195         iov[3].iov_len  = 18;
196         
197         
198         sprintf(Request->LengthS,"%i",Request->FileLength);
199         iov[4].iov_base = Request->LengthS;
200         iov[4].iov_len  = strlen(Request->LengthS);
201         iov[5].iov_base = HeaderPart9;
202         iov[5].iov_len  = 4;
203         
204         len2=15+16+18+iov[2].iov_len+iov[4].iov_len+4;
205         
206         
207         len = 0;
208         
209 
210         oldfs = get_fs(); set_fs(KERNEL_DS);
211         len = sock_sendmsg(Request->sock,&msg,len2);
212         set_fs(oldfs);
213 
214         
215         return; 
216 }
217 #else
218 void SendHTTPHeader(struct http_request *Request)
219 {
220         struct msghdr   msg;
221         mm_segment_t    oldfs;
222         struct iovec    iov[9];
223         int             len,len2;
224         __kernel_size_t slen;
225         
226         EnterFunction("SendHTTPHeader");
227         
228         msg.msg_name     = 0;
229         msg.msg_namelen  = 0;
230         msg.msg_iov      = &(iov[0]);
231         msg.msg_iovlen   = 9;
232         msg.msg_control  = NULL;
233         msg.msg_controllen = 0;
234         msg.msg_flags    = 0;  /* Synchronous for now */
235         
236         iov[0].iov_base = HeaderPart1;
237         iov[0].iov_len  = 45;
238         iov[1].iov_base = CurrentTime;
239         iov[1].iov_len  = 29;
240         iov[2].iov_base = HeaderPart3;
241         iov[2].iov_len  = 16;
242         
243         iov[3].iov_base = Request->MimeType;
244         iov[3].iov_len  = Request->MimeLength;
245         
246         iov[4].iov_base = HeaderPart5;
247         iov[4].iov_len  = 17;
248         iov[5].iov_base = &(Request->TimeS[0]);
249         iov[5].iov_len  = 29;
250         iov[6].iov_base = HeaderPart7;
251         iov[6].iov_len  = 18;
252         iov[7].iov_base = &(Request->LengthS[0]);
253         slen = strlen(Request->LengthS); 
254         iov[7].iov_len  = slen;
255         iov[8].iov_base = HeaderPart9;
256         iov[8].iov_len  = 4;
257         
258         len2=45+2*29+16+17+18+slen+4+iov[3].iov_len;
259         
260         len = 0;
261 
262         oldfs = get_fs(); set_fs(KERNEL_DS);
263         len = sock_sendmsg(Request->sock,&msg,len2);
264         set_fs(oldfs);
265         LeaveFunction("SendHTTPHeader");
266         
267 
268         return; 
269 }
270 #endif
271 
272 
273 
274 /* 
275 
276 Parse a HTTP-header. Be careful for buffer-overflows here, this is the most important
277 place for this, since the remote-user controls the data.
278 
279 */
280 void ParseHeader(char *Buffer,const int length, struct http_request *Head)
281 {
282         char *Endval,*EOL,*tmp;
283         
284         EnterFunction("ParseHeader");
285         Endval = Buffer + length;
286         
287         /* We want to parse only the first header if multiple headers are present */
288         tmp = strstr(Buffer,"\r\n\r\n"); 
289         if (tmp!=NULL)
290             Endval = tmp;
291         
292         
293         while (Buffer<Endval)
294         {
295                 if (isspace(Buffer[0]))
296                 {
297                         Buffer++;
298                         continue;
299                 }
300                         
301                 
302                 EOL=strchr(Buffer,'\n');
303                 
304                 if (EOL==NULL) EOL=Endval;
305                 
306                 if (EOL-Buffer<4) 
307                 {
308                         Buffer++;
309                         continue;
310                 }
311                 
312                 if (strncmp("GET ",Buffer,4)==0)
313                 {
314                         int PrefixLen;
315                         Buffer+=4;
316                         
317                         tmp=strchr(Buffer,' ');
318                         if (tmp==0) 
319                         {
320                                 tmp=EOL-1;
321                                 Head->HTTPVER = 9;
322                         } else
323                                 Head->HTTPVER = 10;
324                         
325                         if (tmp>Endval) continue;
326                         
327                         strncpy(Head->FileName,sysctl_khttpd_docroot,sizeof(Head->FileName));
328                         PrefixLen = strlen(sysctl_khttpd_docroot);
329                         Head->FileNameLength = min(255,tmp-Buffer+PrefixLen);           
330                         
331                         strncat(Head->FileName,Buffer,min(255-PrefixLen,tmp-Buffer));
332                                         
333                         Buffer=EOL+1;   
334 #ifdef BENCHMARK
335                         break;
336 #endif                                          
337                         continue;
338                 }
339 #ifndef BENCHMARK               
340                 if (strncmp("If-Modified-Since: ",Buffer,19)==0)
341                 {
342                         Buffer+=19;
343                         
344                         strncpy(Head->IMS,Buffer,min(127,EOL-Buffer-1));
345                                         
346                         Buffer=EOL+1;   
347                         continue;
348                 }
349 
350                 if (strncmp("User-Agent: ",Buffer,12)==0)
351                 {
352                         Buffer+=12;
353                         
354                         strncpy(Head->Agent,Buffer,min(127,EOL-Buffer-1));
355                                         
356                         Buffer=EOL+1;   
357                         continue;
358                 }
359                 
360 
361                 if (strncmp("Host: ",Buffer,6)==0)
362                 {
363                         Buffer+=6;
364                         
365                         strncpy(Head->Host,Buffer,min(127,EOL-Buffer-1));
366                                         
367                         Buffer=EOL+1;   
368                         continue;
369                 }
370 #endif          
371                 Buffer = EOL+1;  /* Skip line */
372         }
373         LeaveFunction("ParseHeader");
374 }
375 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.