3 * This file is part of httpd.
5 * 02/17/1996 Michael Temari <Michael@TemWare.Com>
6 * 07/07/1996 Initial Release Michael Temari <Michael@TemWare.Com>
7 * 12/29/2002 Michael Temari <Michael@TemWare.Com>
10 #include <sys/types.h>
22 #include <minix/minlib.h>
30 _PROTOTYPE(static void Timeout
, (int sig
));
31 _PROTOTYPE(static int getline
, (char *buffer
, int size
));
32 _PROTOTYPE(static void authorize
, (char *p
, struct http_request
*rq
));
33 _PROTOTYPE(static void decurl
, (char *u
));
37 static void Timeout(sig
)
43 static int getline(buffer
, size
)
52 while(p
< (buffer
+ size
- 1)) {
54 signal(SIGALRM
, Timeout
);
67 p
= &buffer
[strlen(buffer
) - 1];
68 if(p
>= buffer
&& (*p
== '\r' || *p
== '\n')) *p
-- ='\0';
69 if(p
>= buffer
&& (*p
== '\r' || *p
== '\n')) *p
-- ='\0';
71 return(strlen(buffer
));
74 static void authorize(p
, rq
)
76 struct http_request
*rq
;
80 if(toupper(*p
++) == 'B' &&
81 toupper(*p
++) == 'A' &&
82 toupper(*p
++) == 'S' &&
83 toupper(*p
++) == 'I' &&
84 toupper(*p
++) == 'C' &&
85 toupper(*p
++) == ' ') ;
91 if((p
= strchr(s
, ':')) == (char *)NULL
)
96 strncpy(rq
->authuser
, s
, sizeof(rq
->authuser
));
97 strncpy(rq
->authpass
, p
, sizeof(rq
->authpass
));
103 struct http_request
*rq
;
105 static char line
[4096];
110 /* get request, it may be simple */
112 s
= getline(line
, sizeof(line
));
116 if(dbglog
!= (FILE *)NULL
) {
117 fprintf(dbglog
, "REQUEST: %s\n", line
);
121 /* clear http_request */
122 memset(rq
, 0, sizeof(*rq
));
123 rq
->ifmodsince
= (time_t) -1;
125 /* assume simple request */
126 rq
->type
= HTTP_REQUEST_TYPE_SIMPLE
;
128 /* parse the method */
130 while(*p
&& !LWS(*p
)) {
136 if(!strcmp(line
, "GET"))
137 rq
->method
= HTTP_METHOD_GET
; else
138 if(!strcmp(line
, "HEAD"))
139 rq
->method
= HTTP_METHOD_HEAD
; else
140 if(!strcmp(line
, "POST"))
141 rq
->method
= HTTP_METHOD_POST
; else
142 if(!strcmp(line
, "PUT"))
143 rq
->method
= HTTP_METHOD_PUT
; else
145 if(!strcmp(line
, "OPTIONS"))
146 rq
->method
= HTTP_METHOD_OPTIONS
; else
147 if(!strcmp(line
, "PATCH"))
148 rq
->method
= HTTP_METHOD_PATCH
; else
149 if(!strcmp(line
, "COPY"))
150 rq
->method
= HTTP_METHOD_COPY
; else
151 if(!strcmp(line
, "MOVE"))
152 rq
->method
= HTTP_METHOD_MOVE
; else
153 if(!strcmp(line
, "DELETE"))
154 rq
->method
= HTTP_METHOD_DELETE
; else
155 if(!strcmp(line
, "LINK"))
156 rq
->method
= HTTP_METHOD_LINK
; else
157 if(!strcmp(line
, "UNLINK"))
158 rq
->method
= HTTP_METHOD_UNLINK
; else
159 if(!strcmp(line
, "TRACE"))
160 rq
->method
= HTTP_METHOD_TRACE
; else
161 if(!strcmp(line
, "WRAPPED"))
162 rq
->method
= HTTP_METHOD_WRAPPED
; else
164 rq
->method
= HTTP_METHOD_UNKNOWN
;
166 /* parse the requested URI */
168 len
= sizeof(rq
->uri
) - 1;
169 while(*p
&& !LWS(*p
) && len
> 0) {
175 /* eat up any leftovers if uri was too big */
176 while(*p
&& !LWS(*p
))
179 /* save for continued processing later */
182 /* parse the requested URL */
185 len
= sizeof(rq
->url
) - 1;
186 while(*p
&& !LWS(*p
) && *p
!= '?' && len
> 0) {
192 /* See if there is a query string */
196 len
= sizeof(rq
->query
) - 1;
197 while(*p
&& !LWS(*p
) && len
> 0) {
203 /* eat up any leftovers */
204 while(*p
&& !LWS(*p
)) p
++;
206 if(rq
->url
[0] == '\0') {
211 /* url is a decoded copy of the uri */
214 /* restore and continue processing */
217 /* if this is true it is a simple request */
221 /* parse HTTP version */
222 while(*p
&& LWS(*p
)) p
++;
223 if(toupper(*p
++) != 'H') return(0);
224 if(toupper(*p
++) != 'T') return(0);
225 if(toupper(*p
++) != 'T') return(0);
226 if(toupper(*p
++) != 'P') return(0);
227 if( *p
++ != '/') return(0);
231 while((*p
>= '0') && (*p
<= '9'))
232 rq
->vmajor
= rq
->vmajor
* 10 + (*p
++ - '0');
239 while((*p
>= '0') && (*p
<= '9'))
240 rq
->vminor
= rq
->vminor
* 10 + (*p
++ - '0');
244 rq
->type
= HTTP_REQUEST_TYPE_FULL
;
248 /* check if it is a proxy request */
249 if(toupper(*p
++) == 'H' &&
250 toupper(*p
++) == 'T' &&
251 toupper(*p
++) == 'T' &&
252 toupper(*p
++) == 'P' &&
253 toupper(*p
++) == ':')
254 rq
->type
= HTTP_REQUEST_TYPE_PROXY
;
256 /* parse any header fields */
257 while((s
= getline(line
, sizeof(line
))) > 0) {
258 if(toupper(line
[0]) == 'A' &&
259 toupper(line
[1]) == 'U')
260 if(dbglog
!= (FILE *)NULL
) {
261 fprintf(dbglog
, "REQUEST: Authorization:\n");
265 if(dbglog
!= (FILE *)NULL
) {
266 fprintf(dbglog
, "REQUEST: %s\n", line
);
270 while(*p
&& *p
!= ':') {
274 if(*p
!= ':') continue; /* bad header field, skip it */
276 while(*p
&& LWS(*p
)) p
++;
278 /* header field value parsing here */
279 if(!strcmp(line
, "HOST")) {
280 strncpy(rq
->host
, p
, sizeof(rq
->host
));
281 p2
= strrchr(rq
->host
, ':');
282 if(p2
!= (char *)NULL
) {
286 /* if unknown virtual host then exit quietly */
287 for(ph
= vhost
; ph
!= NULL
; ph
= ph
->next
) {
288 if(!strcasecmp(ph
->hname
, "*")) break;
289 if(!strcasecmp(ph
->hname
, rq
->host
)) break;
291 if(rq
->type
!= HTTP_REQUEST_TYPE_PROXY
)
292 if(ph
== NULL
&& vhost
!= NULL
) return(1);
294 if(!strcmp(line
, "USER-AGENT"))
295 strncpy(rq
->useragent
, p
, sizeof(rq
->useragent
)); else
296 if(!strcmp(line
, "CONNECTION"))
297 rq
->keepopen
= strcasecmp(p
, "Keep-Alive") ? 0 : 1; else
298 if(!strcmp(line
, "IF-MODIFIED-SINCE"))
299 rq
->ifmodsince
= httptime(p
); else
300 if(!strcmp(line
, "CONTENT-LENGTH"))
301 rq
->size
= atol(p
); else
302 if(!strcmp(line
, "AUTHORIZATION")) {
303 strncpy(rq
->wwwauth
, p
, sizeof(rq
->wwwauth
));
304 if(rq
->type
!= HTTP_REQUEST_TYPE_PROXY
)
307 if(!strcmp(line
, "PROXY-AUTHORIZATION")) {
308 if(rq
->type
== HTTP_REQUEST_TYPE_PROXY
)
311 if(!strcmp(line
, "DATE"))
312 rq
->msgdate
= httptime(p
); else
313 if(!strcmp(line
, "COOKIE")) {
314 strncpy(rq
->cookie
, p
, sizeof(rq
->cookie
)-1);
315 rq
->cookie
[sizeof(rq
->cookie
)-1] = '\0';
319 if(rq
->type
!= HTTP_REQUEST_TYPE_PROXY
)
320 if(*rq
->host
== '\0' && vhost
!= NULL
) return(1);
322 if(dbglog
!= (FILE *)NULL
&& rq
->authuser
[0] != '\0') {
323 fprintf(dbglog
, "REQUEST: AuthUser=%s\n", rq
->authuser
);
328 fprintf(stderr
, "httpd: getrequest: Error getline (header fields)\n");
335 static void decurl(u
)
360 c
= (h1
> '9') ? (10 + h1
- 'a') : (h1
- '0');
361 c
= 16 * c
+ ((h2
> '9') ? (10 + h2
- 'a') : (h2
- '0'));