comparison packages/net/athttpd/current/src/forms.c @ 2250:0830ae6acddc

Add ATHTTPD server from Anthony Tonizzo.
author jlarmour
date Tue, 18 Jul 2006 16:37:23 +0000
parents
children b5670f3c40f2
comparison
equal deleted inserted replaced
2249:6778c16dcfcd 2250:0830ae6acddc
1 /* =================================================================
2 *
3 * forms.c
4 *
5 * Handles form variables of GET and POST requests.
6 *
7 * =================================================================
8 * ####ECOSGPLCOPYRIGHTBEGIN####
9 * -------------------------------------------
10 * This file is part of eCos, the Embedded Configurable Operating
11 * System.
12 * Copyright (C) 2005 eCosCentric Ltd.
13 *
14 * eCos is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 or (at your option)
17 * any later version.
18 *
19 * eCos is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with eCos; if not, write to the Free Software Foundation,
26 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27 *
28 * As a special exception, if other files instantiate templates or
29 * use macros or inline functions from this file, or you compile this
30 * file and link it with other works to produce a work based on this
31 * file, this file does not by itself cause the resulting work to be
32 * covered by the GNU General Public License. However the source code
33 * for this file must still be made available in accordance with
34 * section (3) of the GNU General Public License.
35 *
36 * This exception does not invalidate any other reasons why a work
37 * based on this file might be covered by the GNU General Public
38 * License.
39 *
40 * -------------------------------------------
41 * ####ECOSGPLCOPYRIGHTEND####
42 * =================================================================
43 * #####DESCRIPTIONBEGIN####
44 *
45 * Author(s): Anthony Tonizzo (atonizzo@gmail.com)
46 * Contributors:
47 * Date: 2006-06-12
48 * Purpose:
49 * Description:
50 *
51 * ####DESCRIPTIONEND####
52 *
53 * =================================================================
54 */
55 #include <pkgconf/hal.h>
56 #include <pkgconf/kernel.h>
57 #include <pkgconf/io_fileio.h>
58 #include <cyg/kernel/kapi.h> // Kernel API.
59 #include <cyg/kernel/ktypes.h> // base kernel types.
60 #include <cyg/infra/diag.h> // For diagnostic printing.
61 #include <network.h>
62 #include <sys/uio.h>
63
64 #include <cyg/hal/hal_tables.h>
65 #include <stdlib.h>
66
67 #include <cyg/athttpd/http.h>
68 #include <cyg/athttpd/socket.h>
69 #include <cyg/athttpd/handler.h>
70 #include <cyg/athttpd/forms.h>
71
72 CYG_HAL_TABLE_BEGIN(cyg_httpd_fvars_table, httpd_fvars_table);
73 CYG_HAL_TABLE_END(cyg_httpd_fvars_table_end, httpd_fvars_table);
74
75 cyg_int8 blank[] = "";
76
77 cyg_int8
78 cyg_httpd_from_hex (cyg_int8 c)
79 {
80 return c >= '0' && c <= '9' ? c - '0'
81 : c >= 'A' && c <= 'F'? c - 'A' + 10
82 : c - 'a' + 10;
83 }
84
85 char*
86 cyg_httpd_store_form_variable(char *query, cyg_httpd_fvars_table_entry *entry)
87 {
88 char *p = query;
89 char *q = entry->buf;
90 int len = 0;
91
92 while (len < (entry->buflen - 1))
93 switch(*p)
94 {
95 case '%':
96 p++;
97 if (*p)
98 *q = cyg_httpd_from_hex(*p++) * 16;
99 if (*p)
100 *q = (*q + cyg_httpd_from_hex(*p++));
101 q++;
102 len++;
103 break;
104 case '+':
105 *q++ = ' ';
106 p++;
107 len++;
108 break;
109 case '&':
110 case ' ':
111 *q++ = '\0';
112 return p;
113 default:
114 *q++ = *p++;
115 len++;
116 }
117 *q = '\0';
118 while ((*p != ' ') && (*p != '&'))
119 p++;
120 return p;
121 }
122
123 // We'll try to parse the data from the form, and store it in the variables
124 // that have been defined by the user in the 'form_variable_table'.
125 char*
126 cyg_httpd_store_form_data(char *p)
127 {
128 char *p2;
129 cyg_int32 var_length;
130 cyg_httpd_fvars_table_entry *entry = cyg_httpd_fvars_table;
131
132 // We'll clear all the variables first, to avoid stale data.
133 while (entry != cyg_httpd_fvars_table_end)
134 {
135 entry->buf[0] = '\0';
136 entry++;
137 }
138
139 while(*p != ' ')
140 {
141 p2 = strchr(p, '=');
142 var_length = (cyg_int32)p2 - (cyg_int32)p;
143 entry = cyg_httpd_fvars_table;
144 while (entry != cyg_httpd_fvars_table_end)
145 {
146 if (!strncmp((const char*)p, entry->name, var_length ))
147 break;
148 entry++;
149 }
150
151 if (entry == cyg_httpd_fvars_table_end)
152 {
153 // No such variable. Run through the data.
154 while ((*p != '&') && (*p != ' '))
155 p++;
156 continue;
157 }
158
159 p = p2;
160 if (*p == '=')
161 {
162 ++p;
163 // Found the variable, store the name.
164 p = cyg_httpd_store_form_variable(p, entry);
165 #if CYGOPT_NET_ATHTTPD_DEBUG_LEVEL > 1
166 diag_printf("Stored form variable: %s Value: %s\n",
167 entry->name,
168 entry->buf);
169 #endif
170 }
171 if (*p == '&')
172 p++;
173 }
174 return p;
175 }
176
177 char*
178 cyg_httpd_find_form_variable(char *p)
179 {
180 cyg_httpd_fvars_table_entry *entry = cyg_httpd_fvars_table;
181
182 while (entry != cyg_httpd_fvars_table_end)
183 {
184 if (!strcmp((const char*)p, entry->name))
185 return entry->buf;
186 entry++;
187 }
188
189 return (char*)0;
190 }
191
192 void
193 cyg_httpd_handle_method_POST(void)
194 {
195 cyg_int32 len = read(httpstate.sockets[httpstate.client_index].descriptor,
196 httpstate.inbuffer,
197 CYG_HTTPD_MAXINBUFFER);
198 CYG_ASSERT(len > 0, "Cannot read POST data");
199 if (len == 0)
200 return;
201
202 char *cp = httpstate.inbuffer;
203 while((*cp == '\r') || (*cp == '\n'))
204 cp++;
205 cp[httpstate.inbuffer_len] = ' ';
206 cyg_httpd_store_form_data(cp);
207
208 handler h = cyg_httpd_find_handler();
209 if (h != 0)
210 {
211 // A handler was found. We'll call the function associated to it. If
212 // the return value is 0 we'll also call cyg_httpd_send_file().
213 h(&httpstate);
214 return;
215 }
216
217 #ifdef CYGOPT_NET_ATHTTPD_USE_CGIBIN_OBJLOADER
218 // If we did not find a c language callback handler for this URL see if
219 // we are trying to execute a CGI via the OBJLOADER package.
220 if (httpstate.url[0] == '/' &&
221 !strncmp(httpstate.url + 1,
222 CYGDAT_NET_ATHTTPD_SERVEROPT_CGIDIR,
223 strlen(CYGDAT_NET_ATHTTPD_SERVEROPT_CGIDIR)))
224 {
225 // Here we'll look for extension to the file. We'll call the cgi
226 // handler only if the extension is '.o'.
227 cyg_httpd_exec_cgi();
228 return;
229 }
230 // If the OBJLOADER package is not loaded, then we'll try to send the
231 // file, which will likely generate a 404.
232 #endif
233
234 // No handler of any kind for a post request. Must send 404.
235 cyg_httpd_send_error(CYG_HTTPD_STATUS_NOT_FOUND);
236 }
237
238