/[hydra]/hydra/src/cgi_header.c
ViewVC logotype

Contents of /hydra/src/cgi_header.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (show annotations)
Mon Sep 30 17:16:54 2002 UTC (21 years, 6 months ago) by nmav
Branch: MAIN
CVS Tags: hydra_0_0_6, hydra_0_0_4, hydra_0_0_5
Changes since 1.2: +1 -1 lines
File MIME type: text/plain
Added support for multiple HIC threads.

1 /*
2 * Hydra, an http server
3 * cgi_header.c - cgi header parsing and control
4 * Copyright (C) 1997-99 Jon Nelson <jnelson@boa.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 1, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22 #include "boa.h"
23
24 /* process_cgi_header
25
26 * returns 0 -=> error or HEAD, close down.
27 * returns 1 -=> done processing
28 * leaves req->cgi_status as WRITE
29 */
30
31 /*
32 The server MUST also resolve any conflicts between header fields returned by
33 the script and header fields that it would otherwise send itself.
34
35 ...
36
37 At least one CGI-Field MUST be supplied, but no CGI field name may be used
38 more than once in a response. If a body is supplied, then a
39 "Content-type" header field MUST be supplied by the script,
40 otherwise the script MUST send a "Location" or "Status" header
41 field. If a Location CGI-Field is returned, then the script
42 MUST NOT supply any HTTP-Fields.
43 */
44
45 /* TODO:
46 We still need to cycle through the data before the end of the headers,
47 line-by-line, and check for any problems with the CGI
48 outputting overriding http responses, etc...
49 */
50
51 int process_cgi_header(request * req)
52 {
53 char *buf;
54 char *c;
55
56 if (req->cgi_status != CGI_DONE)
57 req->cgi_status = CGI_BUFFER;
58
59 buf = req->header_line;
60
61 c = strstr(buf, "\n\r\n");
62 if (c == NULL) {
63 c = strstr(buf, "\n\n");
64 if (c == NULL) {
65 log_error_time();
66 fputs("cgi_header: unable to find LFLF\n", stderr);
67 #ifdef FASCIST_LOGGING
68 log_error_time();
69 fprintf(stderr, "\"%s\"\n", buf);
70 #endif
71 send_r_bad_gateway(req);
72 return 0;
73 }
74 }
75 if (req->simple) {
76 if (*(c + 1) == '\r')
77 req->header_line = c + 2;
78 else
79 req->header_line = c + 1;
80 return 1;
81 }
82 if (!strncasecmp(buf, "Status: ", 8)) {
83 req->header_line--;
84 strcpy(req->header_line, HTTP_VERSION" ");
85 } else if (!strncasecmp(buf, "Location: ", 10)) { /* got a location header */
86 #ifdef FASCIST_LOGGING
87
88 log_error_time();
89 fprintf(stderr, "%s:%d - found Location header \"%s\"\n",
90 __FILE__, __LINE__, buf + 10);
91 #endif
92
93
94 if (buf[10] == '/') { /* virtual path */
95 log_error_time();
96 fprintf(stderr,
97 "server does not support internal redirection: " \
98 "\"%s\"\n", buf + 10);
99 send_r_bad_request(req);
100
101 /*
102 * We (I, Jon) have declined to support absolute-path parsing
103 * because I see it as a major security hole.
104 * Location: /etc/passwd or Location: /etc/shadow is not funny.
105 *
106 * Also, the below code is borked.
107 * request_uri could contain /cgi-bin/bob/extra_path
108 */
109
110 /*
111 strcpy(req->request_uri, buf + 10);
112 return internal_redirect(req);
113 */
114 } else { /* URL */
115 char *c2;
116 c2 = strchr(buf + 10, '\n');
117 /* c2 cannot ever equal NULL here because we already have found one */
118
119 --c2;
120 while (*c2 == '\r')
121 --c2;
122 ++c2;
123 /* c2 now points to a '\r' or the '\n' */
124 *c2++ = '\0'; /* end header */
125
126 /* first next header, or is at req->header_end */
127 while ((*c2 == '\n' || *c2 == '\r') && c2 < req->header_end)
128 ++c2;
129 if (c2 == req->header_end)
130 send_r_moved_temp(req, buf + 10, "");
131 else
132 send_r_moved_temp(req, buf + 10, c2);
133 }
134 req->status = DONE;
135 return 1;
136 } else { /* not location and not status */
137 char *dest;
138 int howmuch;
139 send_r_request_ok(req); /* does not terminate */
140 /* got to do special things because
141 a) we have a single buffer divided into 2 pieces
142 b) we need to merge those pieces
143 Easiest way is to memmove the cgi data backward until
144 it touches the buffered data, then reset the cgi data pointers
145 */
146 dest = req->buffer + req->buffer_end;
147 if (req->method == M_HEAD) {
148 if (*(c + 1) == '\r')
149 req->header_end = c + 2;
150 else
151 req->header_end = c + 1;
152 req->cgi_status = CGI_DONE;
153 }
154 howmuch = req->header_end - req->header_line;
155
156 if (dest + howmuch > req->buffer + BUFFER_SIZE) {
157 /* big problem */
158 log_error_time();
159 fprintf(stderr, "Too much data to move! Aborting! %s %d\n",
160 __FILE__, __LINE__);
161 /* reset buffer pointers because we already called
162 send_r_request_ok... */
163 req->buffer_start = req->buffer_end = 0;
164 send_r_error(req);
165 return 0;
166 }
167 memmove(dest, req->header_line, howmuch);
168 req->buffer_end += howmuch;
169 req->header_line = req->buffer + req->buffer_end;
170 req->header_end = req->header_line;
171 req_flush(req);
172 if (req->method == M_HEAD)
173 return 0;
174 }
175 return 1;
176 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26