]> granicus.if.org Git - apache/blob - modules/http/http_request.c
Initial pass at refactoring some files to eliminate our 150K C source behemoths.
[apache] / modules / http / http_request.c
1 /* Copyright 1999-2004 The Apache Software Foundation
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 /*
17  * http_request.c: functions to get and process requests
18  *
19  * Rob McCool 3/21/93
20  *
21  * Thoroughly revamped by rst for Apache.  NB this file reads
22  * best from the bottom up.
23  *
24  */
25
26 #include "apr_strings.h"
27 #include "apr_file_io.h"
28 #include "apr_fnmatch.h"
29
30 #define APR_WANT_STRFUNC
31 #include "apr_want.h"
32
33 #define CORE_PRIVATE
34 #include "ap_config.h"
35 #include "httpd.h"
36 #include "http_config.h"
37 #include "http_request.h"
38 #include "http_core.h"
39 #include "http_protocol.h"
40 #include "http_log.h"
41 #include "http_main.h"
42 #include "util_filter.h"
43 #include "util_charset.h"
44 #include "scoreboard.h"
45
46 #include "mod_core.h"
47
48 #if APR_HAVE_STDARG_H
49 #include <stdarg.h>
50 #endif
51
52 /*****************************************************************
53  *
54  * Mainline request processing...
55  */
56
57 /* XXX A cleaner and faster way to do this might be to pass the request_rec 
58  * down the filter chain as a parameter.  It would need to change for 
59  * subrequest vs. main request filters; perhaps the subrequest filter could 
60  * make the switch.
61  */
62 static void update_r_in_filters(ap_filter_t *f, 
63                                 request_rec *from,
64                                 request_rec *to)
65 {
66     while (f) {
67         if (f->r == from) {
68             f->r = to;
69         }
70         f = f->next;
71     }
72 }
73
74 AP_DECLARE(void) ap_die(int type, request_rec *r)
75 {
76     int error_index = ap_index_of_response(type);
77     char *custom_response = ap_response_code_string(r, error_index);
78     int recursive_error = 0;
79     request_rec *r_1st_err = r;
80
81     if (type == AP_FILTER_ERROR) {
82         return;
83     }
84
85     if (type == DONE) {
86         ap_finalize_request_protocol(r);
87         return;
88     }
89
90     /*
91      * The following takes care of Apache redirects to custom response URLs
92      * Note that if we are already dealing with the response to some other
93      * error condition, we just report on the original error, and give up on
94      * any attempt to handle the other thing "intelligently"...
95      */
96     if (r->status != HTTP_OK) {
97         recursive_error = type;
98
99         while (r_1st_err->prev && (r_1st_err->prev->status != HTTP_OK))
100             r_1st_err = r_1st_err->prev;  /* Get back to original error */
101
102         if (r_1st_err != r) {
103             /* The recursive error was caused by an ErrorDocument specifying
104              * an internal redirect to a bad URI.  ap_internal_redirect has
105              * changed the filter chains to point to the ErrorDocument's 
106              * request_rec.  Back out those changes so we can safely use the 
107              * original failing request_rec to send the canned error message.
108              *
109              * ap_send_error_response gets rid of existing resource filters
110              * on the output side, so we can skip those.
111              */
112             update_r_in_filters(r_1st_err->proto_output_filters, r, r_1st_err);
113             update_r_in_filters(r_1st_err->input_filters, r, r_1st_err);
114         }
115
116         custom_response = NULL; /* Do NOT retry the custom thing! */
117     }
118
119     r->status = type;
120
121     /*
122      * This test is done here so that none of the auth modules needs to know
123      * about proxy authentication.  They treat it like normal auth, and then
124      * we tweak the status.
125      */
126     if (HTTP_UNAUTHORIZED == r->status && PROXYREQ_PROXY == r->proxyreq) {
127         r->status = HTTP_PROXY_AUTHENTICATION_REQUIRED;
128     }
129
130     /* If we don't want to keep the connection, make sure we mark that the
131      * connection is not eligible for keepalive.  If we want to keep the
132      * connection, be sure that the request body (if any) has been read.
133      */
134     if (ap_status_drops_connection(r->status)) {
135         r->connection->keepalive = AP_CONN_CLOSE;
136     }
137
138     /*
139      * Two types of custom redirects --- plain text, and URLs. Plain text has
140      * a leading '"', so the URL code, here, is triggered on its absence
141      */
142
143     if (custom_response && custom_response[0] != '"') {
144
145         if (ap_is_url(custom_response)) {
146             /*
147              * The URL isn't local, so lets drop through the rest of this
148              * apache code, and continue with the usual REDIRECT handler.
149              * But note that the client will ultimately see the wrong
150              * status...
151              */
152             r->status = HTTP_MOVED_TEMPORARILY;
153             apr_table_setn(r->headers_out, "Location", custom_response);
154         }
155         else if (custom_response[0] == '/') {
156             const char *error_notes;
157             r->no_local_copy = 1;       /* Do NOT send HTTP_NOT_MODIFIED for
158                                          * error documents! */
159             /*
160              * This redirect needs to be a GET no matter what the original
161              * method was.
162              */
163             apr_table_setn(r->subprocess_env, "REQUEST_METHOD", r->method);
164
165             /*
166              * Provide a special method for modules to communicate
167              * more informative (than the plain canned) messages to us.
168              * Propagate them to ErrorDocuments via the ERROR_NOTES variable:
169              */
170             if ((error_notes = apr_table_get(r->notes, 
171                                              "error-notes")) != NULL) {
172                 apr_table_setn(r->subprocess_env, "ERROR_NOTES", error_notes);
173             }
174             r->method = apr_pstrdup(r->pool, "GET");
175             r->method_number = M_GET;
176             ap_internal_redirect(custom_response, r);
177             return;
178         }
179         else {
180             /*
181              * Dumb user has given us a bad url to redirect to --- fake up
182              * dying with a recursive server error...
183              */
184             recursive_error = HTTP_INTERNAL_SERVER_ERROR;
185             ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
186                         "Invalid error redirection directive: %s",
187                         custom_response);
188         }
189     }
190     ap_send_error_response(r_1st_err, recursive_error);
191 }
192
193 static void check_pipeline_flush(request_rec *r)
194 {
195     apr_bucket *e;
196     apr_bucket_brigade *bb;
197     conn_rec *c = r->connection;
198     /* ### if would be nice if we could PEEK without a brigade. that would
199        ### allow us to defer creation of the brigade to when we actually
200        ### need to send a FLUSH. */
201     bb = apr_brigade_create(r->pool, c->bucket_alloc);
202
203     /* Flush the filter contents if:
204      *
205      *   1) the connection will be closed
206      *   2) there isn't a request ready to be read
207      */
208     /* ### shouldn't this read from the connection input filters? */
209     /* ### is zero correct? that means "read one line" */
210     if (r->connection->keepalive != AP_CONN_CLOSE) {
211         if (ap_get_brigade(r->input_filters, bb, AP_MODE_EATCRLF, 
212                        APR_NONBLOCK_READ, 0) != APR_SUCCESS) {
213             c->data_in_input_filters = 0;  /* we got APR_EOF or an error */
214         }
215         else {
216             c->data_in_input_filters = 1;
217             return;    /* don't flush */
218         }
219     }
220
221         e = apr_bucket_flush_create(c->bucket_alloc);
222
223         /* We just send directly to the connection based filters.  At
224          * this point, we know that we have seen all of the data
225          * (request finalization sent an EOS bucket, which empties all
226          * of the request filters). We just want to flush the buckets
227          * if something hasn't been sent to the network yet.
228          */
229         APR_BRIGADE_INSERT_HEAD(bb, e);
230         ap_pass_brigade(r->connection->output_filters, bb);
231 }
232
233 void ap_process_request(request_rec *r)
234 {
235     int access_status;
236
237     /* Give quick handlers a shot at serving the request on the fast
238      * path, bypassing all of the other Apache hooks.
239      *
240      * This hook was added to enable serving files out of a URI keyed 
241      * content cache ( e.g., Mike Abbott's Quick Shortcut Cache, 
242      * described here: http://oss.sgi.com/projects/apache/mod_qsc.html )
243      *
244      * It may have other uses as well, such as routing requests directly to
245      * content handlers that have the ability to grok HTTP and do their
246      * own access checking, etc (e.g. servlet engines). 
247      * 
248      * Use this hook with extreme care and only if you know what you are 
249      * doing.
250      */
251     access_status = ap_run_quick_handler(r, 0);  /* Not a look-up request */
252     if (access_status == DECLINED) {
253         access_status = ap_process_request_internal(r);
254         if (access_status == OK) {
255             access_status = ap_invoke_handler(r);
256         }
257     }
258
259     if (access_status == DONE) {
260         /* e.g., something not in storage like TRACE */
261         access_status = OK;
262     }
263
264     if (access_status == OK) {
265         ap_finalize_request_protocol(r);
266     }
267     else {
268         ap_die(access_status, r);
269     }
270     
271     /*
272      * We want to flush the last packet if this isn't a pipelining connection
273      * *before* we start into logging.  Suppose that the logging causes a DNS
274      * lookup to occur, which may have a high latency.  If we hold off on
275      * this packet, then it'll appear like the link is stalled when really
276      * it's the application that's stalled.
277      */
278     check_pipeline_flush(r);
279     ap_update_child_status(r->connection->sbh, SERVER_BUSY_LOG, r);
280     ap_run_log_transaction(r);
281 }
282
283 static apr_table_t *rename_original_env(apr_pool_t *p, apr_table_t *t)
284 {
285     const apr_array_header_t *env_arr = apr_table_elts(t);
286     const apr_table_entry_t *elts = (const apr_table_entry_t *) env_arr->elts;
287     apr_table_t *new = apr_table_make(p, env_arr->nalloc);
288     int i;
289
290     for (i = 0; i < env_arr->nelts; ++i) {
291         if (!elts[i].key)
292             continue;
293         apr_table_setn(new, apr_pstrcat(p, "REDIRECT_", elts[i].key, NULL),
294                   elts[i].val);
295     }
296
297     return new;
298 }
299
300 static request_rec *internal_internal_redirect(const char *new_uri,
301                                                request_rec *r) {
302     int access_status;
303     request_rec *new;
304
305     if (ap_is_recursion_limit_exceeded(r)) {
306         ap_die(HTTP_INTERNAL_SERVER_ERROR, r);
307         return NULL;
308     }
309
310     new = (request_rec *) apr_pcalloc(r->pool, sizeof(request_rec));
311
312     new->connection = r->connection;
313     new->server     = r->server;
314     new->pool       = r->pool;
315
316     /*
317      * A whole lot of this really ought to be shared with http_protocol.c...
318      * another missing cleanup.  It's particularly inappropriate to be
319      * setting header_only, etc., here.
320      */
321
322     new->method          = r->method;
323     new->method_number   = r->method_number;
324     new->allowed_methods = ap_make_method_list(new->pool, 2);
325     ap_parse_uri(new, new_uri);
326
327     new->request_config = ap_create_request_config(r->pool);
328
329     new->per_dir_config = r->server->lookup_defaults;
330
331     new->prev = r;
332     r->next   = new;
333
334     /* Must have prev and next pointers set before calling create_request
335      * hook.
336      */
337     ap_run_create_request(new);
338
339     /* Inherit the rest of the protocol info... */
340
341     new->the_request = r->the_request;
342
343     new->allowed         = r->allowed;
344
345     new->status          = r->status;
346     new->assbackwards    = r->assbackwards;
347     new->header_only     = r->header_only;
348     new->protocol        = r->protocol;
349     new->proto_num       = r->proto_num;
350     new->hostname        = r->hostname;
351     new->request_time    = r->request_time;
352     new->main            = r->main;
353
354     new->headers_in      = r->headers_in;
355     new->headers_out     = apr_table_make(r->pool, 12);
356     new->err_headers_out = r->err_headers_out;
357     new->subprocess_env  = rename_original_env(r->pool, r->subprocess_env);
358     new->notes           = apr_table_make(r->pool, 5);
359     new->allowed_methods = ap_make_method_list(new->pool, 2);
360
361     new->htaccess        = r->htaccess;
362     new->no_cache        = r->no_cache;
363     new->expecting_100   = r->expecting_100;
364     new->no_local_copy   = r->no_local_copy;
365     new->read_length     = r->read_length;     /* We can only read it once */
366     new->vlist_validator = r->vlist_validator;
367
368     new->proto_output_filters  = r->proto_output_filters;
369     new->proto_input_filters   = r->proto_input_filters;
370
371     new->output_filters  = new->proto_output_filters;
372     new->input_filters   = new->proto_input_filters;
373
374     if (new->main) {
375         /* Add back the subrequest filter, which we lost when
376          * we set output_filters to include only the protocol
377          * output filters from the original request.
378          */
379         ap_add_output_filter_handle(ap_subreq_core_filter_handle,
380                                     NULL, new, new->connection);
381     }
382     
383     update_r_in_filters(new->input_filters, r, new);
384     update_r_in_filters(new->output_filters, r, new);
385
386     apr_table_setn(new->subprocess_env, "REDIRECT_STATUS",
387                    apr_itoa(r->pool, r->status));
388
389     /*
390      * XXX: hmm.  This is because mod_setenvif and mod_unique_id really need
391      * to do their thing on internal redirects as well.  Perhaps this is a
392      * misnamed function.
393      */
394     if ((access_status = ap_run_post_read_request(new))) {
395         ap_die(access_status, new);
396         return NULL;
397     }
398
399     return new;
400 }
401
402 /* XXX: Is this function is so bogus and fragile that we deep-6 it? */
403 AP_DECLARE(void) ap_internal_fast_redirect(request_rec *rr, request_rec *r)
404 {
405     /* We need to tell POOL_DEBUG that we're guaranteeing that rr->pool
406      * will exist as long as r->pool.  Otherwise we run into troubles because
407      * some values in this request will be allocated in r->pool, and others in
408      * rr->pool.
409      */
410     apr_pool_join(r->pool, rr->pool);
411     r->proxyreq = rr->proxyreq;
412     r->no_cache = (r->no_cache && rr->no_cache);
413     r->no_local_copy = (r->no_local_copy && rr->no_local_copy);
414     r->mtime = rr->mtime;
415     r->uri = rr->uri;
416     r->filename = rr->filename;
417     r->canonical_filename = rr->canonical_filename;
418     r->path_info = rr->path_info;
419     r->args = rr->args;
420     r->finfo = rr->finfo;
421     r->handler = rr->handler;
422     ap_set_content_type(r, rr->content_type);
423     r->content_encoding = rr->content_encoding;
424     r->content_languages = rr->content_languages;
425     r->per_dir_config = rr->per_dir_config;
426     /* copy output headers from subrequest, but leave negotiation headers */
427     r->notes = apr_table_overlay(r->pool, rr->notes, r->notes);
428     r->headers_out = apr_table_overlay(r->pool, rr->headers_out,
429                                        r->headers_out);
430     r->err_headers_out = apr_table_overlay(r->pool, rr->err_headers_out,
431                                            r->err_headers_out);
432     r->subprocess_env = apr_table_overlay(r->pool, rr->subprocess_env,
433                                           r->subprocess_env);
434
435     r->output_filters = rr->output_filters;
436     r->input_filters = rr->input_filters;
437
438     if (r->main) {
439         ap_add_output_filter_handle(ap_subreq_core_filter_handle,
440                                     NULL, r, r->connection);
441     }
442     else if (r->output_filters->frec == ap_subreq_core_filter_handle) {
443         ap_remove_output_filter(r->output_filters);
444         r->output_filters = r->output_filters->next;
445     }
446
447     /* If any filters pointed at the now-defunct rr, we must point them
448      * at our "new" instance of r.  In particular, some of rr's structures
449      * will now be bogus (say rr->headers_out).  If a filter tried to modify
450      * their f->r structure when it is pointing to rr, the real request_rec
451      * will not get updated.  Fix that here.
452      */
453     update_r_in_filters(r->input_filters, rr, r);
454     update_r_in_filters(r->output_filters, rr, r);
455 }
456
457 AP_DECLARE(void) ap_internal_redirect(const char *new_uri, request_rec *r)
458 {
459     request_rec *new = internal_internal_redirect(new_uri, r);
460     int access_status;
461
462     /* ap_die was already called, if an error occured */
463     if (!new) {
464         return;
465     }
466
467     access_status = ap_run_quick_handler(new, 0);  /* Not a look-up request */
468     if (access_status == DECLINED) {
469         access_status = ap_process_request_internal(new);
470         if (access_status == OK) {
471             access_status = ap_invoke_handler(new);
472         }
473     }
474     if (access_status == OK) {
475         ap_finalize_request_protocol(new);
476     }
477     else {
478         ap_die(access_status, new);
479     }
480 }
481
482 /* This function is designed for things like actions or CGI scripts, when
483  * using AddHandler, and you want to preserve the content type across
484  * an internal redirect.
485  */
486 AP_DECLARE(void) ap_internal_redirect_handler(const char *new_uri, request_rec *r)
487 {
488     int access_status;
489     request_rec *new = internal_internal_redirect(new_uri, r);
490
491     /* ap_die was already called, if an error occured */
492     if (!new) {
493         return;
494     }
495
496     if (r->handler)
497         ap_set_content_type(new, r->content_type);
498     access_status = ap_process_request_internal(new);
499     if (access_status == OK) {
500         if ((access_status = ap_invoke_handler(new)) != 0) {
501             ap_die(access_status, new);
502             return;
503         }
504         ap_finalize_request_protocol(new);
505     }
506     else {
507         ap_die(access_status, new);
508     }
509 }
510
511 AP_DECLARE(void) ap_allow_methods(request_rec *r, int reset, ...) 
512 {
513     const char *method;
514     va_list methods;
515
516     /*
517      * Get rid of any current settings if requested; not just the
518      * well-known methods but any extensions as well.
519      */
520     if (reset) {
521         ap_clear_method_list(r->allowed_methods);
522     }
523
524     va_start(methods, reset);
525     while ((method = va_arg(methods, const char *)) != NULL) {
526         ap_method_list_add(r->allowed_methods, method);
527     }
528 }
529
530 AP_DECLARE(void) ap_allow_standard_methods(request_rec *r, int reset, ...)
531 {
532     int method;
533     va_list methods;
534     apr_int64_t mask;
535
536     /*
537      * Get rid of any current settings if requested; not just the
538      * well-known methods but any extensions as well.
539      */
540     if (reset) {
541         ap_clear_method_list(r->allowed_methods);
542     }
543
544     mask = 0;
545     va_start(methods, reset);
546     while ((method = va_arg(methods, int)) != -1) {
547         mask |= (AP_METHOD_BIT << method);
548     }
549     va_end(methods);
550
551     r->allowed_methods->method_mask |= mask;
552 }