OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [khttpd/] [rfc.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
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/slab.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
        transferred.
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_t(unsigned int, 255, tmp - Buffer + PrefixLen);
330
 
331
                        strncat(Head->FileName,Buffer,min_t(unsigned int, 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_t(unsigned int, 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_t(unsigned int, 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_t(unsigned int, 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
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.