/[H8]/trunk/docs/Microchip TCP_IP stack/TCPIP Stack/HTTP.c
ViewVC logotype

Contents of /trunk/docs/Microchip TCP_IP stack/TCPIP Stack/HTTP.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 15 - (show annotations) (download)
Thu Apr 19 09:01:15 2007 UTC (17 years, 1 month ago) by hedin
File MIME type: text/plain
File size: 21917 byte(s)
added the TCP/IP stack, source code.
1 /*********************************************************************
2 *
3 * HyperText Transfer Protocol (HTTP) Server
4 * Module for Microchip TCP/IP Stack
5 * -Serves dynamic pages to web browsers such as Microsoft Internet
6 * Explorer, Mozilla Firefox, etc.
7 * -Reference: RFC 2068
8 *
9 **********************************************************************
10 * FileName: HTTP.c
11 * Dependencies: string.h
12 * Stacktsk.h
13 * Http.h
14 * MPFS.h
15 * TCP.h
16 * Processor: PIC18, PIC24F, PIC24H, dsPIC30F, dsPIC33F
17 * Complier: Microchip C18 v3.02 or higher
18 * Microchip C30 v2.01 or higher
19 * Company: Microchip Technology, Inc.
20 *
21 * Software License Agreement
22 *
23 * Copyright © 2002-2007 Microchip Technology Inc. All rights
24 * reserved.
25 *
26 * Microchip licenses to you the right to use, modify, copy, and
27 * distribute:
28 * (i) the Software when embedded on a Microchip microcontroller or
29 * digital signal controller product (“Device”) which is
30 * integrated into Licensee’s product; or
31 * (ii) ONLY the Software driver source files ENC28J60.c and
32 * ENC28J60.h ported to a non-Microchip device used in
33 * conjunction with a Microchip ethernet controller for the
34 * sole purpose of interfacing with the ethernet controller.
35 *
36 * You should refer to the license agreement accompanying this
37 * Software for additional information regarding your rights and
38 * obligations.
39 *
40 * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” WITHOUT
41 * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
42 * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
43 * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
44 * MICROCHIP BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR
45 * CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
46 * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
47 * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
48 * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
49 * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
50 * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
51 *
52 *
53 * Author Date Comment
54 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
55 * Nilesh Rajbharti 8/14/01 Original
56 * Nilesh Rajbharti 9/12/01 Released (Rev. 1.0)
57 * Nilesh Rajbharti 2/9/02 Cleanup
58 * Nilesh Rajbharti 5/22/02 Rev 2.0 (See version.log for detail)
59 * Nilesh Rajbharti 7/9/02 Rev 2.1 (Fixed HTTPParse bug)
60 * Howard Schlunder 2/9/05 Fixed variable substitution
61 * parsing (uses hex now)
62 ********************************************************************/
63 #define __HTTP_C
64
65 #include "TCPIP Stack/TCPIP.h"
66
67 #if defined(STACK_USE_HTTP_SERVER)
68
69
70 // Each dynamic variable within a CGI file should be preceeded with this character.
71 #define HTTP_VAR_ESC_CHAR '%'
72 #define HTTP_DYNAMIC_FILE_TYPE (HTTP_CGI)
73
74 // HTTP File Types
75 #define HTTP_TXT (0u)
76 #define HTTP_HTML (1u)
77 #define HTTP_CGI (2u)
78 #define HTTP_XML (3u)
79 #define HTTP_GIF (4u)
80 #define HTTP_PNG (5u)
81 #define HTTP_JPG (6u)
82 #define HTTP_JAVA (7u)
83 #define HTTP_WAV (8u)
84 #define HTTP_UNKNOWN (9u)
85
86
87 #define FILE_EXT_LEN (3u)
88 typedef struct _FILE_TYPES
89 {
90 BYTE fileExt[FILE_EXT_LEN+1];
91 } FILE_TYPES;
92
93 // Each entry in this structure must be in UPPER case.
94 // Order of these entries must match with those defined by "HTTP File Types" defines.
95 static ROM FILE_TYPES httpFiles[] =
96 {
97 { "TXT" }, // HTTP_TXT
98 { "HTM" }, // HTTP_HTML
99 { "CGI" }, // HTTP_CGI
100 { "XML" }, // HTTP_XML
101 { "GIF" }, // HTTP_GIF
102 { "PNG" }, // HTTP_PNG
103 { "JPG" }, // HTTP_JPG
104 { "CLA" }, // HTTP_JAVA
105 { "WAV" }, // HTTP_WAV
106 { "" } // HTTP_UNKNOWN
107 };
108 #define TOTAL_FILE_TYPES ( sizeof(httpFiles)/sizeof(httpFiles[0]) )
109
110
111 typedef struct _HTTP_CONTENT
112 {
113 ROM BYTE typeString[20];
114 } HTTP_CONTENT;
115
116 // Content entry order must match with those "HTTP File Types" define's.
117 static ROM HTTP_CONTENT httpContents[] =
118 {
119 { "text/plain" }, // HTTP_TXT
120 { "text/html" }, // HTTP_HTML
121 { "text/html" }, // HTTP_CGI
122 { "text/xml" }, // HTTP_XML
123 { "image/gif" }, // HTTP_GIF
124 { "image/png" }, // HTTP_PNG
125 { "image/jpeg" }, // HTTP_JPG
126 { "application/java-vm" }, // HTTP_JAVA
127 { "audio/x-wave" }, // HTTP_WAV
128 { "" } // HTTP_UNKNOWN
129 };
130 #define TOTAL_HTTP_CONTENTS ( sizeof(httpContents)/sizeof(httpConetents[0]) )
131
132 // HTTP FSM states for each connection.
133 typedef enum _SM_HTTP
134 {
135 SM_HTTP_IDLE = 0u,
136 SM_HTTP_GET,
137 SM_HTTP_NOT_FOUND,
138 SM_HTTP_GET_READ,
139 SM_HTTP_GET_PASS,
140 SM_HTTP_GET_DLE,
141 SM_HTTP_GET_HANDLE,
142 SM_HTTP_GET_HANDLE_NEXT,
143 SM_HTTP_GET_VAR,
144 SM_HTTP_HEADER,
145 SM_HTTP_DISCARD
146 } SM_HTTP;
147
148 // Supported HTTP Commands
149 typedef enum _HTTP_COMMAND
150 {
151 HTTP_GET = 0u,
152 HTTP_POST,
153 HTTP_NOT_SUPPORTED,
154 HTTP_INVALID_COMMAND
155 } HTTP_COMMAND;
156
157 // HTTP Connection Info - one for each connection.
158 typedef struct _HTTP_INFO
159 {
160 TCP_SOCKET socket;
161 MPFS file;
162 SM_HTTP smHTTP;
163 BYTE smHTTPGet;
164 WORD VarRef;
165 BYTE bProcess;
166 BYTE Variable;
167 BYTE fileType;
168 } HTTP_INFO;
169 typedef BYTE HTTP_HANDLE;
170
171
172 typedef enum
173 {
174 HTTP_NOT_FOUND = 0u,
175 HTTP_NOT_AVAILABLE
176 } HTTP_MESSAGES;
177
178 // Following message order must match with that of HTTP_MESSAGES enum.
179 static ROM BYTE *HTTPMessages[] =
180 {
181 (ROM BYTE*)"HTTP/1.1 404 Not found\r\n\r\nNot found.\r\n",
182 (ROM BYTE*)"HTTP/1.1 503 \r\n\r\nService Unavailable\r\n"
183 };
184
185 // Standard HTTP messages.
186 static ROM BYTE HTTP_OK_STRING[] = "HTTP/1.1 200 OK\r\nContent-type: ";
187 static ROM BYTE HTTP_OK_NO_CACHE_STRING[] = "HTTP/1.1 200 OK\r\nDate: Wed, 05 Apr 2006 02:53:05 GMT\r\nExpires: Wed, 05 Apr 2006 02:52:05 GMT\r\nCache-control: private\r\nContent-type: ";
188 #define HTTP_OK_STRING_LEN (sizeof(HTTP_OK_STRING)-1)
189 #define HTTP_OK_NO_CACHE_STRING_LEN (sizeof(HTTP_OK_NO_CACHE_STRING)-1)
190
191 static ROM BYTE HTTP_HEADER_END_STRING[] = "\r\n\r\n";
192 #define HTTP_HEADER_END_STRING_LEN (sizeof(HTTP_HEADER_END_STRING)-1)
193
194 // HTTP Command Strings
195 static ROM BYTE HTTP_GET_STRING[] = "GET";
196 #define HTTP_GET_STRING_LEN (sizeof(HTTP_GET_STRING)-1)
197
198 // Default HTML file.
199 static ROM BYTE HTTP_DEFAULT_FILE_STRING[] = "INDEX.HTM";
200 #define HTTP_DEFAULT_FILE_STRING_LEN (sizeof(HTTP_DEFAULT_FILE_STRING)-1)
201
202
203 // Maximum nuber of arguments supported by this HTTP Server.
204 #define MAX_HTTP_ARGS (11u)
205
206 // Maximum HTML Command String length.
207 #define MAX_HTML_CMD_LEN (100u)
208
209
210 static HTTP_INFO HCB[MAX_HTTP_CONNECTIONS];
211
212
213 static void HTTPProcess(HTTP_HANDLE h);
214 static HTTP_COMMAND HTTPParse(BYTE *string,
215 BYTE** arg,
216 BYTE* argc,
217 BYTE* type);
218 static BOOL SendFile(HTTP_INFO* ph);
219
220
221
222
223 /*********************************************************************
224 * Function: void HTTPInit(void)
225 *
226 * PreCondition: TCP must already be initialized.
227 *
228 * Input: None
229 *
230 * Output: HTTP FSM and connections are initialized
231 *
232 * Side Effects: None
233 *
234 * Overview: Set all HTTP connections to Listening state.
235 * Initialize FSM for each connection.
236 *
237 * Note: This function is called only one during lifetime
238 * of the application.
239 ********************************************************************/
240 void HTTPInit(void)
241 {
242 BYTE i;
243
244 for ( i = 0; i < MAX_HTTP_CONNECTIONS; i++ )
245 {
246 HCB[i].socket = TCPListen(HTTP_PORT);
247 HCB[i].smHTTP = SM_HTTP_IDLE;
248 }
249 }
250
251
252
253 /*********************************************************************
254 * Function: void HTTPServer(void)
255 *
256 * PreCondition: HTTPInit() must already be called.
257 *
258 * Input: None
259 *
260 * Output: Opened HTTP connections are served.
261 *
262 * Side Effects: None
263 *
264 * Overview: Browse through each connections and let it
265 * handle its connection.
266 * If a connection is not finished, do not process
267 * next connections. This must be done, all
268 * connections use some static variables that are
269 * common.
270 *
271 * Note: This function acts as a task (similar to one in
272 * RTOS). This function performs its task in
273 * co-operative manner. Main application must call
274 * this function repeatdly to ensure all open
275 * or new connections are served on time.
276 ********************************************************************/
277 void HTTPServer(void)
278 {
279 BYTE conn;
280
281 for ( conn = 0; conn < MAX_HTTP_CONNECTIONS; conn++ )
282 HTTPProcess(conn);
283 }
284
285
286 /*********************************************************************
287 * Function: static BOOL HTTPProcess(HTTP_HANDLE h)
288 *
289 * PreCondition: HTTPInit() called.
290 *
291 * Input: h - Index to the handle which needs to be
292 * processed.
293 *
294 * Output: Connection referred by 'h' is served.
295 *
296 * Side Effects: None
297 *
298 * Overview:
299 *
300 * Note: None.
301 ********************************************************************/
302 static void HTTPProcess(HTTP_HANDLE h)
303 {
304 BYTE httpData[MAX_HTML_CMD_LEN+1];
305 HTTP_COMMAND httpCommand;
306 BOOL lbContinue;
307 BYTE *arg[MAX_HTTP_ARGS];
308 BYTE argc;
309 BYTE i;
310 HTTP_INFO* ph;
311 WORD w;
312
313 ph = &HCB[h];
314
315
316 do
317 {
318 lbContinue = FALSE;
319
320 // If during handling of HTTP socket, it gets disconnected,
321 // forget about previous processing and return to idle state.
322 if(!TCPIsConnected(ph->socket))
323 {
324 ph->smHTTP = SM_HTTP_IDLE;
325 break;
326 }
327
328
329 switch(ph->smHTTP)
330 {
331 case SM_HTTP_IDLE:
332 // Search for the CRLF deliminating the end of the first GET/HEAD/POST request
333 w = TCPFindROMArray(ph->socket, (ROM BYTE*)"\r\n", 2, 0, FALSE);
334 if(w == 0xFFFFu)
335 {
336 if(TCPGetRxFIFOFree(ph->socket) == 0)
337 {
338 // Request is too big, we can't support it.
339 TCPDisconnect(ph->socket);
340 }
341 break;
342 }
343
344 lbContinue = TRUE;
345
346 if(w > sizeof(httpData)-1)
347 w = sizeof(httpData)-1;
348
349 TCPGetArray(ph->socket, httpData, w);
350 httpData[w] = '\0';
351 TCPDiscard(ph->socket);
352
353 ph->smHTTP = SM_HTTP_NOT_FOUND;
354 argc = MAX_HTTP_ARGS;
355 httpCommand = HTTPParse(httpData, arg, &argc, &ph->fileType);
356 if ( httpCommand == HTTP_GET )
357 {
358 // If there are any arguments, this must be a remote command.
359 // Execute it and then send the file.
360 // The file name may be modified by command handler.
361 if ( argc > 1u )
362 {
363 // Let main application handle this remote command.
364 HTTPExecCmd(&arg[0], argc);
365
366 // Command handler must have modified arg[0] which now
367 // points to actual file that will be sent as a result of
368 // this remote command.
369
370 // Assume that Web author will only use CGI or HTML
371 // file for remote command.
372 ph->fileType = HTTP_CGI;
373 }
374
375 ph->file = MPFSOpen(arg[0]);
376 if ( ph->file == MPFS_INVALID )
377 {
378 ph->Variable = HTTP_NOT_FOUND;
379 ph->smHTTP = SM_HTTP_NOT_FOUND;
380 }
381 else if ( ph->file == MPFS_NOT_AVAILABLE )
382 {
383 ph->Variable = HTTP_NOT_AVAILABLE;
384 ph->smHTTP = SM_HTTP_NOT_FOUND;
385 }
386 else
387 {
388 ph->smHTTP = SM_HTTP_HEADER;
389 }
390 }
391 break;
392
393 case SM_HTTP_NOT_FOUND:
394 if(TCPIsPutReady(ph->socket) >= strlenpgm((ROM char*)HTTPMessages[ph->Variable]))
395 {
396 TCPPutROMString(ph->socket, HTTPMessages[ph->Variable]);
397 TCPFlush(ph->socket);
398 TCPDisconnect(ph->socket);
399 ph->smHTTP = SM_HTTP_IDLE;
400 }
401 break;
402
403 case SM_HTTP_HEADER:
404 if ( TCPIsPutReady(ph->socket) )
405 {
406 lbContinue = TRUE;
407
408 if ( ph->fileType == HTTP_DYNAMIC_FILE_TYPE )
409 {
410 ph->bProcess = TRUE;
411 TCPPutROMArray(ph->socket, (ROM BYTE*)HTTP_OK_NO_CACHE_STRING, HTTP_OK_NO_CACHE_STRING_LEN);
412 }
413 else
414 {
415 ph->bProcess = FALSE;
416 TCPPutROMArray(ph->socket, (ROM BYTE*)HTTP_OK_STRING, HTTP_OK_STRING_LEN);
417 }
418
419 TCPPutROMString(ph->socket, httpContents[ph->fileType].typeString);
420 TCPPutROMArray(ph->socket, (ROM BYTE*)HTTP_HEADER_END_STRING, HTTP_HEADER_END_STRING_LEN);
421
422 ph->smHTTPGet = SM_HTTP_GET_READ;
423 ph->smHTTP = SM_HTTP_GET;
424 }
425 break;
426
427 case SM_HTTP_GET:
428 // Throw away any more data receieved - we aren't going to use it.
429 TCPDiscard(ph->socket);
430
431 if(SendFile(ph))
432 {
433 MPFSClose();
434 TCPDisconnect(ph->socket);
435 ph->smHTTP = SM_HTTP_IDLE;
436 }
437 break;
438
439 }
440 } while( lbContinue );
441 }
442
443
444 /*********************************************************************
445 * Function: static BOOL SendFile(HTTP_INFO* ph)
446 *
447 * PreCondition: None
448 *
449 * Input: ph - A HTTP connection info.
450 *
451 * Output: File reference by this connection is served.
452 *
453 * Side Effects: None
454 *
455 * Overview: None
456 *
457 * Note: None.
458 ********************************************************************/
459 static BOOL SendFile(HTTP_INFO* ph)
460 {
461 BOOL lbTransmit;
462 BYTE c;
463 BYTE buffer[8];
464 WORD w;
465 WORD_VAL HexNumber;
466
467 MPFSGetBegin(ph->file);
468
469 // Check if file is dynamic (.cgi) -- need to look for and
470 // process escape sequences
471 if(ph->bProcess)
472 {
473 for(w = TCPIsPutReady(ph->socket); w; w--)
474 {
475 lbTransmit = FALSE;
476
477 if(ph->smHTTPGet != SM_HTTP_GET_VAR)
478 {
479 c = MPFSGet();
480 if(MPFSIsEOF())
481 {
482 MPFSGetEnd();
483 TCPFlush(ph->socket);
484 return TRUE;
485 }
486 }
487
488 switch(ph->smHTTPGet)
489 {
490 case SM_HTTP_GET_READ:
491 if ( c == HTTP_VAR_ESC_CHAR )
492 ph->smHTTPGet = SM_HTTP_GET_DLE;
493 else
494 lbTransmit = TRUE;
495 break;
496
497 case SM_HTTP_GET_DLE:
498 if ( c == HTTP_VAR_ESC_CHAR )
499 {
500 lbTransmit = TRUE;
501 ph->smHTTPGet = SM_HTTP_GET_READ;
502 }
503 else
504 {
505 HexNumber.v[1] = c;
506 ph->smHTTPGet = SM_HTTP_GET_HANDLE;
507 }
508 break;
509
510 case SM_HTTP_GET_HANDLE:
511 HexNumber.v[0] = c;
512 ph->Variable = hexatob(HexNumber);
513
514 ph->smHTTPGet = SM_HTTP_GET_VAR;
515 ph->VarRef = HTTP_START_OF_VAR;
516 break;
517
518 case SM_HTTP_GET_VAR:
519 ph->VarRef = HTTPGetVar(ph->Variable, ph->VarRef, &c);
520 lbTransmit = TRUE;
521 if ( ph->VarRef == HTTP_END_OF_VAR )
522 ph->smHTTPGet = SM_HTTP_GET_READ;
523 break;
524 }
525
526 if(lbTransmit)
527 TCPPut(ph->socket, c);
528 }
529 }
530 else // Static page content -- no processing required
531 {
532 w = TCPIsPutReady(ph->socket);
533 while(w >= sizeof(buffer))
534 {
535 for(c = 0; c < sizeof(buffer); c++)
536 {
537 buffer[c] = MPFSGet();
538 if(MPFSIsEOF())
539 {
540 MPFSGetEnd();
541 TCPPutArray(ph->socket, buffer, c);
542 TCPFlush(ph->socket);
543 return TRUE;
544 }
545 }
546
547 TCPPutArray(ph->socket, buffer, sizeof(buffer));
548 w -= sizeof(buffer);
549 lbTransmit = TRUE;
550 }
551 if(lbTransmit)
552 TCPFlush(ph->socket);
553 }
554 ph->file = MPFSGetEnd();
555
556 // We are not done sending a file yet...
557 return FALSE;
558 }
559
560
561 /*********************************************************************
562 * Function: static HTTP_COMMAND HTTPParse(BYTE *string,
563 * BYTE** arg,
564 * BYTE* argc,
565 * BYTE* type)
566 *
567 * PreCondition: None
568 *
569 * Input: string - HTTP Command String
570 * arg - List of string pointer to hold
571 * HTTP arguments.
572 * argc - Pointer to hold total number of
573 * arguments in this command string/
574 * type - Pointer to hold type of file
575 * received.
576 * Valid values are:
577 * HTTP_TXT
578 * HTTP_HTML
579 * HTTP_GIF
580 * HTTP_CGI
581 * HTTP_UNKNOWN
582 *
583 * Output: HTTP FSM and connections are initialized
584 *
585 * Side Effects: None
586 *
587 * Overview: None
588 *
589 * Note: This function parses URL that may or may not
590 * contain arguments.
591 * e.g. "GET HTTP/1.0 thank.htm?name=MCHP&age=12"
592 * would be returned as below:
593 * arg[0] => GET
594 * arg[1] => thank.htm
595 * arg[2] => name
596 * arg[3] => MCHP
597 * arg[4] => 12
598 * argc = 5
599 *
600 * This parses does not "de-escape" URL string.
601 ********************************************************************/
602 static HTTP_COMMAND HTTPParse(BYTE *string,
603 BYTE** arg,
604 BYTE* argc,
605 BYTE* type)
606 {
607 BYTE i;
608 BYTE smParse;
609 HTTP_COMMAND cmd;
610 BYTE *ext;
611 BYTE c;
612 ROM BYTE *fileType;
613
614 enum
615 {
616 SM_PARSE_IDLE,
617 SM_PARSE_ARG,
618 SM_PARSE_ARG_FORMAT
619 };
620
621 smParse = SM_PARSE_IDLE;
622 ext = NULL;
623 i = 0;
624
625 // Only "GET" is supported for time being.
626 if ( !memcmppgm2ram(string, (ROM void*) HTTP_GET_STRING, HTTP_GET_STRING_LEN) )
627 {
628 string += (HTTP_GET_STRING_LEN + 1);
629 cmd = HTTP_GET;
630 }
631 else
632 {
633 return HTTP_NOT_SUPPORTED;
634 }
635
636 // Skip white spaces.
637 while( *string == ' ' )
638 string++;
639
640 c = *string;
641
642 while ( c != ' ' && c != '\0' && c != '\r' && c != '\n' )
643
644 {
645 // Do not accept any more arguments than we haved designed to.
646 if ( i >= *argc )
647 break;
648
649 switch(smParse)
650 {
651 case SM_PARSE_IDLE:
652 arg[i] = string;
653 c = *string;
654 if ( c == '/' || c == '\\' )
655 smParse = SM_PARSE_ARG;
656 break;
657
658 case SM_PARSE_ARG:
659 arg[i++] = string;
660 smParse = SM_PARSE_ARG_FORMAT;
661 /*
662 * Do not break.
663 * Parameter may be empty.
664 */
665
666 case SM_PARSE_ARG_FORMAT:
667 c = *string;
668 if ( c == '?' || c == '&' )
669 {
670 *string = '\0';
671 smParse = SM_PARSE_ARG;
672 }
673 else
674 {
675 // Recover space characters.
676 if ( c == '+' )
677 *string = ' ';
678
679 // Remember where file extension starts.
680 else if ( c == '.' && i == 1u )
681 {
682 ext = ++string;
683 }
684
685 else if ( c == '=' )
686 {
687 *string = '\0';
688 smParse = SM_PARSE_ARG;
689 }
690
691 // Only interested in file name - not a path.
692 else if ( c == '/' || c == '\\' )
693 arg[i-1] = string+1;
694
695 }
696 break;
697 }
698 string++;
699 c = *string;
700 }
701 *string = '\0';
702
703 *type = HTTP_UNKNOWN;
704 if ( ext != NULL )
705 {
706 ext = (BYTE*)strupr((char*)ext);
707
708 fileType = httpFiles[0].fileExt;
709 for ( c = 0; c < TOTAL_FILE_TYPES; c++ )
710 {
711 if ( !memcmppgm2ram((void*)ext, (ROM void*)fileType, FILE_EXT_LEN) )
712 {
713 *type = c;
714 break;
715 }
716 fileType += sizeof(FILE_TYPES);
717
718 }
719 }
720
721 if ( i == 0u )
722 {
723 memcpypgm2ram(arg[0], (ROM void*)HTTP_DEFAULT_FILE_STRING,
724 HTTP_DEFAULT_FILE_STRING_LEN);
725 arg[0][HTTP_DEFAULT_FILE_STRING_LEN] = '\0';
726 *type = HTTP_HTML;
727 i++;
728 }
729 *argc = i;
730
731 return cmd;
732 }
733
734
735 #endif //#if defined(STACK_USE_HTTP_SERVER)

  ViewVC Help
Powered by ViewVC 1.1.20