comparison packages/net/httpd/current/src/httpd.c @ 1053:657f409c5dfe

* src/httpd.c: Fixed a problem with closing the client socket -- it was being done twice. Tidied up the formatting a little. * src/monitor.c: Fixed some compiler warnings.
author nickg
date Sat, 14 Jun 2003 18:04:55 +0000
parents 4ca8a5f30c03
children eeb14eae974b
comparison
equal deleted inserted replaced
1052:ee5b3444e088 1053:657f409c5dfe
152 /* ================================================================= */ 152 /* ================================================================= */
153 /* Main processing function */ 153 /* Main processing function */
154 /* */ 154 /* */
155 /* Reads the HTTP header, look it up in the table and calls the */ 155 /* Reads the HTTP header, look it up in the table and calls the */
156 /* handler. */ 156 /* handler. */
157 static void cyg_httpd_process( int client_socket, struct sockaddr *client_address ) { 157
158 158 static void cyg_httpd_process( int client_socket, struct sockaddr *client_address )
159 int calen = sizeof(*client_address); 159 {
160 int nlc = 0; 160 int calen = sizeof(*client_address);
161 char request[CYGNUM_HTTPD_SERVER_BUFFER_SIZE]; 161 int nlc = 0;
162 FILE *client; 162 char request[CYGNUM_HTTPD_SERVER_BUFFER_SIZE];
163 cyg_httpd_table_entry *entry = cyg_httpd_table; 163 FILE *client;
164 char *filename; 164 cyg_httpd_table_entry *entry = cyg_httpd_table;
165 char *formdata = NULL; 165 char *filename;
166 char *p; 166 char *formdata = NULL;
167 cyg_bool success = false; 167 char *p;
168 char name[64]; 168 cyg_bool success = false;
169 char port[10]; 169 char name[64];
170 170 char port[10];
171 getnameinfo(client_address, calen, name, sizeof(name), 171
172 port, sizeof(port), NI_NUMERICHOST|NI_NUMERICSERV); 172 getnameinfo(client_address, calen, name, sizeof(name),
173 HTTPD_DIAG("Connection from %s[%s]\n",name,port); 173 port, sizeof(port), NI_NUMERICHOST|NI_NUMERICSERV);
174 174 HTTPD_DIAG("Connection from %s[%s]\n",name,port);
175 /* Convert the file descriptor to a C library FILE object so 175
176 * we can use fprintf() and friends on it. 176 /* Convert the file descriptor to a C library FILE object so
177 */ 177 * we can use fprintf() and friends on it.
178 client = fdopen( client_socket, "r+"); 178 */
179 179 client = fdopen( client_socket, "r+");
180 /* We are really only interested in the first line. 180
181 */ 181 /* We are really only interested in the first line.
182 fgets( request, sizeof(request), client ); 182 */
183 183 fgets( request, sizeof(request), client );
184 HTTPD_DIAG("Request >%s<\n", request ); 184
185 185 HTTPD_DIAG("Request >%s<\n", request );
186 /* Absorb the rest of the header. We nibble it away a 186
187 * character at a time like this to avoid having to define 187 /* Absorb the rest of the header. We nibble it away a
188 * another buffer to read lines into. If we ever need to take 188 * character at a time like this to avoid having to define
189 * more interest in the header fields, we will need to be a 189 * another buffer to read lines into. If we ever need to take
190 * lot more sophisticated than this. 190 * more interest in the header fields, we will need to be a
191 */ 191 * lot more sophisticated than this.
192 do{ 192 */
193 int c = getc( client ); 193 do{
194 HTTPD_DIAG("%c",c); 194 int c = getc( client );
195 if( c == '\n' ) 195 HTTPD_DIAG("%c",c);
196 nlc++; 196 if( c == '\n' )
197 else if( c != '\r' ) 197 nlc++;
198 nlc = 0; 198 else if( c != '\r' )
199 } while(nlc < 2); 199 nlc = 0;
200 200 } while(nlc < 2);
201 /* Extract the filename and any form data being returned. 201
202 * We know that the "GET " request takes 4 bytes. 202 /* Extract the filename and any form data being returned.
203 * TODO: handle POST type requests as well as GET's. 203 * We know that the "GET " request takes 4 bytes.
204 */ 204 * TODO: handle POST type requests as well as GET's.
205 205 */
206 filename = p = request+4; 206
207 207 filename = p = request+4;
208 /* Now scan the filename until we hit a space or a '?'. If we 208
209 * end on a '?' then the rest is a form request. Put NULs at 209 /* Now scan the filename until we hit a space or a '?'. If we
210 * the end of each string. 210 * end on a '?' then the rest is a form request. Put NULs at
211 */ 211 * the end of each string.
212 while( *p != ' ' && *p != '?' ) 212 */
213 p++; 213 while( *p != ' ' && *p != '?' )
214 if( *p == '?' )
215 formdata = p+1;
216 *p = 0;
217
218 if( formdata != NULL )
219 {
220 while( *p != ' ' )
221 p++; 214 p++;
222 *p = 0; 215 if( *p == '?' )
216 formdata = p+1;
217 *p = 0;
218
219 if( formdata != NULL )
220 {
221 while( *p != ' ' )
222 p++;
223 *p = 0;
223 } 224 }
224 225
225 HTTPD_DIAG("Request filename >%s< formdata >%s<\n",filename,formdata?formdata:"-NULL-"); 226 HTTPD_DIAG("Request filename >%s< formdata >%s<\n",filename,formdata?formdata:"-NULL-");
226 227
227 HTTPD_DIAG("table: %08x...%08x\n",cyg_httpd_table, cyg_httpd_table_end); 228 HTTPD_DIAG("table: %08x...%08x\n",cyg_httpd_table, cyg_httpd_table_end);
228 229
229 /* Now scan the table for a matching entry. If we find one 230 /* Now scan the table for a matching entry. If we find one
230 * call the handler routine. If that returns true then we 231 * call the handler routine. If that returns true then we
231 * terminate the scan, otherwise we keep looking. 232 * terminate the scan, otherwise we keep looking.
232 */ 233 */
233 while( entry != cyg_httpd_table_end ) 234 while( entry != cyg_httpd_table_end )
234 { 235 {
235 HTTPD_DIAG("try %08x: %s\n", entry, entry->pattern); 236 HTTPD_DIAG("try %08x: %s\n", entry, entry->pattern);
236 237
237 if( match( filename, entry->pattern ) ) 238 if( match( filename, entry->pattern ) )
238 { 239 {
239 if( (success = entry->handler( client, filename, formdata, entry->arg )) ) 240 if( (success = entry->handler( client, filename, formdata, entry->arg )) )
240 break; 241 break;
241 } 242 }
242 243
243 entry++; 244 entry++;
244 } 245 }
245 246
246 /* If we failed to find a match in the table, send a "not 247 /* If we failed to find a match in the table, send a "not
247 * found" response. 248 * found" response.
248 * TODO: add an optional fallback to go look for files in 249 * TODO: add an optional fallback to go look for files in
249 * some filesystem, somewhere. 250 * some filesystem, somewhere.
250 */ 251 */
251 if( !success ) 252 if( !success )
252 cyg_httpd_send_html( client, NULL, NULL, cyg_httpd_not_found ); 253 cyg_httpd_send_html( client, NULL, NULL, cyg_httpd_not_found );
253 254
254 fclose(client); 255 fclose(client);
255 } 256 }
256 257
257 /* ================================================================= */ 258 /* ================================================================= */
258 /* Main HTTP server 259 /* Main HTTP server
259 * 260 *
283 #endif 284 #endif
284 select(n,&readfds,NULL,NULL,NULL); 285 select(n,&readfds,NULL,NULL,NULL);
285 if (FD_ISSET(server_socket, &readfds)) { 286 if (FD_ISSET(server_socket, &readfds)) {
286 client_socket = accept( server_socket, &client_address, &calen ); 287 client_socket = accept( server_socket, &client_address, &calen );
287 cyg_httpd_process(client_socket, &client_address); 288 cyg_httpd_process(client_socket, &client_address);
288 err = close( client_socket );
289 CYG_ASSERT( err == 0, "fclose() returned error");
290 } 289 }
291 #ifdef CYGPKG_NET_INET6 290 #ifdef CYGPKG_NET_INET6
292 if (FD_ISSET(server_socket6, &readfds)) { 291 if (FD_ISSET(server_socket6, &readfds)) {
293 client_socket = accept( server_socket6, &client_address, &calen ); 292 client_socket = accept( server_socket6, &client_address, &calen );
294 cyg_httpd_process(client_socket, &client_address); 293 cyg_httpd_process(client_socket, &client_address);
295 err = close( client_socket );
296 CYG_ASSERT( err == 0, "fclose(AF_INET6) returned error");
297 } 294 }
298 #endif 295 #endif
299 } while(1); 296 } while(1);
300 } 297 }
301 298