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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [ARM7_AT91SAM7X256_Eclipse/] [RTOSDemo/] [webserver/] [httpd.c] - Blame information for rev 577

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 577 jeremybenn
/*$T httpd.c GC 1.138 11/17/07 13:10:22 */
2
 
3
/*
4
 * \addtogroup apps @{ £
5
 * \defgroup httpd Web server @{ The uIP web server is a very simplistic
6
 * implementation of an HTTP server. It can serve web pages and files from a
7
 * read-only ROM filesystem, and provides a very small scripting language. £
8
 * \file Web server \author Adam Dunkels <adam@sics.se> £
9
 * Copyright (c) 2004, Adam Dunkels. All rights reserved. Redistribution and use
10
 * in source and binary forms, with or without modification, are permitted
11
 * provided that the following conditions are met: 1. Redistributions of source
12
 * code must retain the above copyright notice, this list of conditions and the
13
 * following disclaimer. 2. Redistributions in binary form must reproduce the
14
 * above copyright notice, this list of conditions and the following disclaimer in
15
 * the documentation and/or other materials provided with the distribution. 3.
16
 * Neither the name of the Institute nor the names of its contributors may be used
17
 * to endorse or promote products derived from this software without specific
18
 * prior written permission. THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND
19
 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
20
 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
21
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR
22
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
24
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
27
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
28
 * OF SUCH DAMAGE. This file is part of the uIP TCP/IP stack. Author: Adam Dunkels
29
 * <adam@sics.se> $Id: httpd.c 2 2011-07-17 20:13:17Z filepang@gmail.com $
30
 */
31
#include "uip.h"
32
#include "httpd.h"
33
#include "httpd-fs.h"
34
#include "httpd-cgi.h"
35
#include "http-strings.h"
36
 
37
#include <string.h>
38
 
39
#define STATE_WAITING   0
40
#define STATE_OUTPUT    1
41
 
42
#define ISO_nl                  0x0a
43
#define ISO_space               0x20
44
#define ISO_bang                0x21
45
#define ISO_percent             0x25
46
#define ISO_period              0x2e
47
#define ISO_slash               0x2f
48
#define ISO_colon               0x3a
49
 
50
/*
51
 =======================================================================================================================
52
 =======================================================================================================================
53
 */
54
static unsigned short generate_part_of_file(void *state)
55
{
56
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
57
        struct httpd_state      *s = (struct httpd_state *) state;
58
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
59
 
60
        if(s->file.len > uip_mss())
61
        {
62
                s->len = uip_mss();
63
        }
64
        else
65
        {
66
                s->len = s->file.len;
67
        }
68
 
69
        memcpy(uip_appdata, s->file.data, s->len);
70
 
71
        return s->len;
72
}
73
 
74
/*
75
 =======================================================================================================================
76
 =======================================================================================================================
77
 */
78
static PT_THREAD(send_file (struct httpd_state *s))
79
{
80
        PSOCK_BEGIN(&s->sout);
81
 
82
        do
83
        {
84
                PSOCK_GENERATOR_SEND(&s->sout, generate_part_of_file, s);
85
                s->file.len -= s->len;
86
                s->file.data += s->len;
87
        } while(s->file.len > 0);
88
 
89
        PSOCK_END(&s->sout);
90
}
91
 
92
/*
93
 =======================================================================================================================
94
 =======================================================================================================================
95
 */
96
static PT_THREAD(send_part_of_file (struct httpd_state *s))
97
{
98
        PSOCK_BEGIN(&s->sout);
99
 
100
        PSOCK_SEND(&s->sout, s->file.data, s->len);
101
 
102
        PSOCK_END(&s->sout);
103
}
104
 
105
/*
106
 =======================================================================================================================
107
 =======================================================================================================================
108
 */
109
static void next_scriptstate(struct httpd_state *s)
110
{
111
        /*~~~~~~~*/
112
        char    *p;
113
        /*~~~~~~~*/
114
 
115
        p = strchr(s->scriptptr, ISO_nl) + 1;
116
        s->scriptlen -= (unsigned short) (p - s->scriptptr);
117
        s->scriptptr = p;
118
}
119
 
120
/*
121
 =======================================================================================================================
122
 =======================================================================================================================
123
 */
124
static PT_THREAD(handle_script (struct httpd_state *s))
125
{
126
        /*~~~~~~~~~*/
127
        char    *ptr;
128
        /*~~~~~~~~~*/
129
 
130
        PT_BEGIN(&s->scriptpt);
131
 
132
        while(s->file.len > 0)
133
        {
134
                /* Check if we should start executing a script. */
135
                if(*s->file.data == ISO_percent && *(s->file.data + 1) == ISO_bang)
136
                {
137
                        s->scriptptr = s->file.data + 3;
138
                        s->scriptlen = s->file.len - 3;
139
                        if(*(s->scriptptr - 1) == ISO_colon)
140
                        {
141
                                httpd_fs_open(s->scriptptr + 1, &s->file);
142
                                PT_WAIT_THREAD(&s->scriptpt, send_file(s));
143
                        }
144
                        else
145
                        {
146
                                PT_WAIT_THREAD(&s->scriptpt, httpd_cgi(s->scriptptr) (s, s->scriptptr));
147
                        }
148
 
149
                        next_scriptstate(s);
150
 
151
                        /*
152
                         * The script is over, so we reset the pointers and continue sending the rest of
153
                         * the file.
154
                         */
155
                        s->file.data = s->scriptptr;
156
                        s->file.len = s->scriptlen;
157
                }
158
                else
159
                {
160
                        /* See if we find the start of script marker in the block of HTML to be sent. */
161
                        if(s->file.len > uip_mss())
162
                        {
163
                                s->len = uip_mss();
164
                        }
165
                        else
166
                        {
167
                                s->len = s->file.len;
168
                        }
169
 
170
                        if(*s->file.data == ISO_percent)
171
                        {
172
                                ptr = strchr(s->file.data + 1, ISO_percent);
173
                        }
174
                        else
175
                        {
176
                                ptr = strchr(s->file.data, ISO_percent);
177
                        }
178
 
179
                        if(ptr != NULL && ptr != s->file.data)
180
                        {
181
                                s->len = (int) (ptr - s->file.data);
182
                                if(s->len >= uip_mss())
183
                                {
184
                                        s->len = uip_mss();
185
                                }
186
                        }
187
 
188
                        PT_WAIT_THREAD(&s->scriptpt, send_part_of_file(s));
189
                        s->file.data += s->len;
190
                        s->file.len -= s->len;
191
                }
192
        }
193
 
194
        PT_END(&s->scriptpt);
195
}
196
 
197
/*
198
 =======================================================================================================================
199
 =======================================================================================================================
200
 */
201
static PT_THREAD(send_headers (struct httpd_state *s, const char *statushdr))
202
{
203
        /*~~~~~~~~~*/
204
        char    *ptr;
205
        /*~~~~~~~~~*/
206
 
207
        PSOCK_BEGIN(&s->sout);
208
 
209
        PSOCK_SEND_STR(&s->sout, statushdr);
210
 
211
        ptr = strrchr(s->filename, ISO_period);
212
        if(ptr == NULL)
213
        {
214
                PSOCK_SEND_STR(&s->sout, http_content_type_binary);
215
        }
216
        else if(strncmp(http_html, ptr, 5) == 0 || strncmp(http_shtml, ptr, 6) == 0)
217
        {
218
                PSOCK_SEND_STR(&s->sout, http_content_type_html);
219
        }
220
        else if(strncmp(http_css, ptr, 4) == 0)
221
        {
222
                PSOCK_SEND_STR(&s->sout, http_content_type_css);
223
        }
224
        else if(strncmp(http_png, ptr, 4) == 0)
225
        {
226
                PSOCK_SEND_STR(&s->sout, http_content_type_png);
227
        }
228
        else if(strncmp(http_gif, ptr, 4) == 0)
229
        {
230
                PSOCK_SEND_STR(&s->sout, http_content_type_gif);
231
        }
232
        else if(strncmp(http_jpg, ptr, 4) == 0)
233
        {
234
                PSOCK_SEND_STR(&s->sout, http_content_type_jpg);
235
        }
236
        else
237
        {
238
                PSOCK_SEND_STR(&s->sout, http_content_type_plain);
239
        }
240
 
241
        PSOCK_END(&s->sout);
242
}
243
 
244
/*
245
 =======================================================================================================================
246
 =======================================================================================================================
247
 */
248
static PT_THREAD(handle_output (struct httpd_state *s))
249
{
250
        /*~~~~~~~~~*/
251
        char    *ptr;
252
        /*~~~~~~~~~*/
253
 
254
        PT_BEGIN(&s->outputpt);
255
 
256
        if(!httpd_fs_open(s->filename, &s->file))
257
        {
258
                httpd_fs_open(http_404_html, &s->file);
259
                strcpy(s->filename, http_404_html);
260
                PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_404));
261
                PT_WAIT_THREAD(&s->outputpt, send_file(s));
262
        }
263
        else
264
        {
265
                PT_WAIT_THREAD(&s->outputpt, send_headers(s, http_header_200));
266
                ptr = strchr(s->filename, ISO_period);
267
                if(ptr != NULL && strncmp(ptr, http_shtml, 6) == 0)
268
                {
269
                        vProcessInput( s->filename );
270
                        PT_INIT(&s->scriptpt);
271
                        PT_WAIT_THREAD(&s->outputpt, handle_script(s));
272
                }
273
                else
274
                {
275
                        PT_WAIT_THREAD(&s->outputpt, send_file(s));
276
                }
277
        }
278
 
279
        PSOCK_CLOSE(&s->sout);
280
        PT_END(&s->outputpt);
281
}
282
 
283
/*
284
 =======================================================================================================================
285
 =======================================================================================================================
286
 */
287
static PT_THREAD(handle_input (struct httpd_state *s))
288
{
289
        PSOCK_BEGIN(&s->sin);
290
 
291
        PSOCK_READTO(&s->sin, ISO_space);
292
 
293
        if(strncmp(s->inputbuf, http_get, 4) != 0)
294
        {
295
                PSOCK_CLOSE_EXIT(&s->sin);
296
        }
297
 
298
        PSOCK_READTO(&s->sin, ISO_space);
299
 
300
        if(s->inputbuf[0] != ISO_slash)
301
        {
302
                PSOCK_CLOSE_EXIT(&s->sin);
303
        }
304
 
305
        if(s->inputbuf[1] == ISO_space)
306
        {
307
                strncpy(s->filename, http_index_html, sizeof(s->filename));
308
        }
309
        else
310
        {
311
                s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0;
312
 
313
                /* Process any form input being sent to the server. */
314
                {
315
                        /*
316
                         * extern void vApplicationProcessFormInput( char *pcInputString, long
317
                         * xInputLength ); £
318
                         * vApplicationProcessFormInput( s->inputbuf, PSOCK_DATALEN(&s->sin) );
319
                         */
320
                }
321
 
322
                strncpy(s->filename, &s->inputbuf[0], sizeof(s->filename));
323
        }
324
 
325
        /* httpd_log_file(uip_conn->ripaddr, s->filename); */
326
        s->state = STATE_OUTPUT;
327
 
328
        while(1)
329
        {
330
                PSOCK_READTO(&s->sin, ISO_nl);
331
 
332
                if(strncmp(s->inputbuf, http_referer, 8) == 0)
333
                {
334
                        s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0;
335
 
336
                        /* httpd_log(&s->inputbuf[9]); */
337
                }
338
        }
339
 
340
        PSOCK_END(&s->sin);
341
}
342
 
343
/*
344
 =======================================================================================================================
345
 =======================================================================================================================
346
 */
347
static void handle_connection(struct httpd_state *s)
348
{
349
        handle_input(s);
350
        if(s->state == STATE_OUTPUT)
351
        {
352
                handle_output(s);
353
        }
354
}
355
 
356
/*
357
 =======================================================================================================================
358
 =======================================================================================================================
359
 */
360
void httpd_appcall(void)
361
{
362
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
363
        struct httpd_state      *s = (struct httpd_state *) &(uip_conn->appstate);
364
        /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
365
 
366
        if(uip_closed() || uip_aborted() || uip_timedout())
367
        {
368
        }
369
        else if(uip_connected())
370
        {
371
                PSOCK_INIT(&s->sin, s->inputbuf, sizeof(s->inputbuf) - 1);
372
                PSOCK_INIT(&s->sout, s->inputbuf, sizeof(s->inputbuf) - 1);
373
                PT_INIT(&s->outputpt);
374
                s->state = STATE_WAITING;
375
 
376
                /* timer_set(&s->timer, CLOCK_SECOND * 100); */
377
                s->timer = 0;
378
                handle_connection(s);
379
        }
380
        else if(s != NULL)
381
        {
382
                if(uip_poll())
383
                {
384
                        ++s->timer;
385
                        if(s->timer >= 20)
386
                        {
387
                                uip_abort();
388
                        }
389
                }
390
                else
391
                {
392
                        s->timer = 0;
393
                }
394
 
395
                handle_connection(s);
396
        }
397
        else
398
        {
399
                uip_abort();
400
        }
401
}
402
 
403
/*
404
 =======================================================================================================================
405
    \brief Initialize the web server This function initializes the web server and should be called at system boot-up.
406
 =======================================================================================================================
407
 */
408
void httpd_init(void)
409
{
410
        uip_listen(HTONS(80));
411
}
412
 
413
/* @} */

powered by: WebSVN 2.1.0

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