2008-10-25 12:53:57 +00:00
|
|
|
#ifndef _LIGHTTPD_VIRTUALREQUEST_H_
|
|
|
|
#define _LIGHTTPD_VIRTUALREQUEST_H_
|
|
|
|
|
2008-10-28 21:11:50 +00:00
|
|
|
#ifndef _LIGHTTPD_BASE_H_
|
2008-11-16 20:33:53 +00:00
|
|
|
#error Please include <lighttpd/base.h> instead of this file
|
2008-10-28 21:11:50 +00:00
|
|
|
#endif
|
|
|
|
|
2008-10-25 12:53:57 +00:00
|
|
|
typedef enum {
|
|
|
|
/* waiting for request headers */
|
|
|
|
VRS_CLEAN,
|
|
|
|
|
|
|
|
/* all headers received, now handling them, set up input filters
|
|
|
|
* this state is set by the previous vrequest after VRS_WROTE_RESPONSE_HEADERS (or the main connection),
|
|
|
|
* and the handle_request function is called (which execute the action stack by default)
|
|
|
|
*/
|
|
|
|
VRS_HANDLE_REQUEST_HEADERS,
|
|
|
|
|
|
|
|
/* request headers handled, input filters ready; now content is accepted
|
|
|
|
* this state is set via handle_indirect (handle_direct skips to VRS_HANDLE_RESPONSE_HEADERS
|
|
|
|
*/
|
|
|
|
VRS_READ_CONTENT,
|
|
|
|
|
|
|
|
/* all response headers written, now set up output filters */
|
|
|
|
VRS_HANDLE_RESPONSE_HEADERS,
|
|
|
|
|
|
|
|
/* output filters ready, content can be written */
|
|
|
|
VRS_WRITE_CONTENT,
|
|
|
|
|
|
|
|
/* request done */
|
2008-11-18 10:03:59 +00:00
|
|
|
/* VRS_END, */
|
2008-10-25 12:53:57 +00:00
|
|
|
|
|
|
|
VRS_ERROR
|
|
|
|
} vrequest_state;
|
|
|
|
|
2009-03-12 20:08:27 +00:00
|
|
|
typedef handler_t (*filter_handler)(vrequest *vr, filter *f);
|
|
|
|
typedef void (*filter_free)(vrequest *vr, filter *f);
|
2008-10-25 12:53:57 +00:00
|
|
|
typedef handler_t (*vrequest_handler)(vrequest *vr);
|
2009-01-01 15:44:42 +00:00
|
|
|
typedef handler_t (*vrequest_plugin_handler)(vrequest *vr, plugin *p);
|
2008-10-25 12:53:57 +00:00
|
|
|
|
|
|
|
struct filter {
|
|
|
|
chunkqueue *in, *out;
|
2009-03-12 20:08:27 +00:00
|
|
|
filter_handler handle_data;
|
|
|
|
filter_free handle_free;
|
|
|
|
gpointer param;
|
2008-10-25 12:53:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct filters {
|
|
|
|
GPtrArray *queue;
|
|
|
|
chunkqueue *in, *out;
|
2009-03-11 15:57:07 +00:00
|
|
|
guint skip_ndx;
|
2008-10-25 12:53:57 +00:00
|
|
|
};
|
|
|
|
|
2009-04-14 16:18:25 +00:00
|
|
|
struct vrequest_ref {
|
|
|
|
guint refcount;
|
|
|
|
vrequest *vr; /* This is only accesible by the worker thread the vrequest belongs to, and it may be NULL if the vrequest is already reset */
|
|
|
|
};
|
|
|
|
|
2008-10-25 12:53:57 +00:00
|
|
|
struct vrequest {
|
2009-04-14 16:18:25 +00:00
|
|
|
connection *con;
|
2009-04-15 10:34:06 +00:00
|
|
|
worker *wrk;
|
2009-04-14 16:18:25 +00:00
|
|
|
vrequest_ref *ref;
|
2008-10-25 12:53:57 +00:00
|
|
|
|
2008-12-30 00:21:03 +00:00
|
|
|
option_value *options;
|
|
|
|
|
2008-10-25 12:53:57 +00:00
|
|
|
vrequest_state state;
|
|
|
|
|
|
|
|
vrequest_handler
|
2009-01-01 15:44:42 +00:00
|
|
|
handle_request_headers,
|
2008-10-25 12:53:57 +00:00
|
|
|
handle_response_headers, handle_response_body,
|
|
|
|
handle_response_error; /* this is _not_ for 500 - internal error */
|
|
|
|
|
|
|
|
GPtrArray *plugin_ctx;
|
2009-01-01 15:44:42 +00:00
|
|
|
plugin *backend;
|
2008-10-25 12:53:57 +00:00
|
|
|
|
|
|
|
request request;
|
|
|
|
physical physical;
|
|
|
|
response response;
|
|
|
|
|
2009-02-15 17:55:27 +00:00
|
|
|
/* environment entries will be passed to the backends */
|
2008-12-31 15:23:00 +00:00
|
|
|
environment env;
|
|
|
|
|
2008-10-25 12:53:57 +00:00
|
|
|
/* -> vr_in -> filters_in -> in -> handle -> out -> filters_out -> vr_out -> */
|
|
|
|
gboolean cq_memory_limit_hit; /* stop feeding chunkqueues with memory chunks */
|
|
|
|
filters filters_in, filters_out;
|
|
|
|
chunkqueue *vr_in, *vr_out;
|
|
|
|
chunkqueue *in, *out;
|
|
|
|
|
|
|
|
action_stack action_stack;
|
|
|
|
gboolean actions_wait_for_response;
|
2008-12-30 20:55:00 +00:00
|
|
|
|
2009-04-14 16:18:25 +00:00
|
|
|
gint queued;
|
|
|
|
GList job_queue_link;
|
2009-03-01 20:16:58 +00:00
|
|
|
|
2009-03-26 22:05:17 +00:00
|
|
|
GPtrArray *stat_cache_entries;
|
2008-10-25 12:53:57 +00:00
|
|
|
};
|
|
|
|
|
2008-12-31 01:57:27 +00:00
|
|
|
#define VREQUEST_WAIT_FOR_RESPONSE_HEADERS(vr) \
|
|
|
|
do { \
|
|
|
|
if (vr->state == VRS_HANDLE_REQUEST_HEADERS) { \
|
|
|
|
VR_ERROR(vr, "%s", "Cannot wait for response headers as no backend handler found - fix your config"); \
|
|
|
|
return HANDLER_ERROR; \
|
|
|
|
} else if (vr->state < VRS_HANDLE_RESPONSE_HEADERS) { \
|
|
|
|
return HANDLER_WAIT_FOR_EVENT; \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
2008-10-25 12:53:57 +00:00
|
|
|
LI_API vrequest* vrequest_new(struct connection *con, vrequest_handler handle_response_headers, vrequest_handler handle_response_body, vrequest_handler handle_response_error, vrequest_handler handle_request_headers);
|
|
|
|
LI_API void vrequest_free(vrequest *vr);
|
|
|
|
LI_API void vrequest_reset(vrequest *vr);
|
|
|
|
|
2009-04-14 16:18:25 +00:00
|
|
|
LI_API vrequest_ref* vrequest_acquire_ref(vrequest *vr);
|
|
|
|
LI_API vrequest* vrequest_release_ref(vrequest_ref *vr_ref);
|
|
|
|
|
2009-03-12 20:08:27 +00:00
|
|
|
LI_API void vrequest_add_filter_in(vrequest *vr, filter_handler handle_data, filter_free handle_free, gpointer param);
|
|
|
|
LI_API void vrequest_add_filter_out(vrequest *vr, filter_handler handle_data, filter_free handle_free, gpointer param);
|
2009-03-11 15:57:07 +00:00
|
|
|
|
2009-01-04 20:59:56 +00:00
|
|
|
/* Signals an internal error; handles the error in the _next_ loop */
|
2008-10-25 12:53:57 +00:00
|
|
|
LI_API void vrequest_error(vrequest *vr);
|
|
|
|
|
2008-12-31 13:36:24 +00:00
|
|
|
LI_API void vrequest_backend_overloaded(vrequest *vr);
|
|
|
|
LI_API void vrequest_backend_dead(vrequest *vr);
|
|
|
|
LI_API void vrequest_backend_error(vrequest *vr, backend_error berror);
|
|
|
|
|
2008-10-25 12:53:57 +00:00
|
|
|
/* received all request headers */
|
|
|
|
LI_API void vrequest_handle_request_headers(vrequest *vr);
|
|
|
|
/* received (partial) request content */
|
|
|
|
LI_API void vrequest_handle_request_body(vrequest *vr);
|
|
|
|
/* received all response headers/status code - call once from your indirect handler */
|
|
|
|
LI_API void vrequest_handle_response_headers(vrequest *vr);
|
|
|
|
/* received (partial) response content - call from your indirect handler */
|
|
|
|
LI_API void vrequest_handle_response_body(vrequest *vr);
|
|
|
|
|
|
|
|
/* response completely ready */
|
|
|
|
LI_API gboolean vrequest_handle_direct(vrequest *vr);
|
|
|
|
/* handle request over time */
|
2009-01-01 15:44:42 +00:00
|
|
|
LI_API gboolean vrequest_handle_indirect(vrequest *vr, plugin *p);
|
2009-03-17 10:42:50 +00:00
|
|
|
LI_API gboolean vrequest_is_handled(vrequest *vr);
|
2008-10-25 12:53:57 +00:00
|
|
|
|
|
|
|
LI_API void vrequest_state_machine(vrequest *vr);
|
|
|
|
LI_API void vrequest_joblist_append(vrequest *vr);
|
2009-04-14 16:18:25 +00:00
|
|
|
LI_API void vrequest_joblist_append_async(vrequest *vr);
|
2008-10-25 12:53:57 +00:00
|
|
|
|
2009-01-05 21:24:54 +00:00
|
|
|
LI_API gboolean vrequest_stat(vrequest *vr);
|
|
|
|
|
2009-03-01 20:16:58 +00:00
|
|
|
LI_API gboolean vrequest_redirect(vrequest *vr, GString *uri);
|
|
|
|
|
2008-10-25 12:53:57 +00:00
|
|
|
#endif
|