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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [Common/] [ethernet/] [FreeTCPIP/] [apps/] [httpd/] [httpd.c] - Blame information for rev 606

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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