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
|
|
|
|
|
2010-09-05 11:21:42 +00:00
|
|
|
#include <lighttpd/jobqueue.h>
|
|
|
|
|
2008-10-25 12:53:57 +00:00
|
|
|
typedef enum {
|
|
|
|
/* waiting for request headers */
|
2009-07-08 19:06:07 +00:00
|
|
|
LI_VRS_CLEAN,
|
2008-10-25 12:53:57 +00:00
|
|
|
|
|
|
|
/* 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)
|
|
|
|
*/
|
2009-07-08 19:06:07 +00:00
|
|
|
LI_VRS_HANDLE_REQUEST_HEADERS,
|
2008-10-25 12:53:57 +00:00
|
|
|
|
|
|
|
/* request headers handled, input filters ready; now content is accepted
|
2009-07-08 19:06:07 +00:00
|
|
|
* this state is set via handle_indirect (handle_direct skips to LI_VRS_HANDLE_RESPONSE_HEADERS
|
2008-10-25 12:53:57 +00:00
|
|
|
*/
|
2009-07-08 19:06:07 +00:00
|
|
|
LI_VRS_READ_CONTENT,
|
2008-10-25 12:53:57 +00:00
|
|
|
|
|
|
|
/* all response headers written, now set up output filters */
|
2009-07-08 19:06:07 +00:00
|
|
|
LI_VRS_HANDLE_RESPONSE_HEADERS,
|
2008-10-25 12:53:57 +00:00
|
|
|
|
|
|
|
/* output filters ready, content can be written */
|
2009-07-08 19:06:07 +00:00
|
|
|
LI_VRS_WRITE_CONTENT,
|
2008-10-25 12:53:57 +00:00
|
|
|
|
|
|
|
/* request done */
|
2008-11-18 10:03:59 +00:00
|
|
|
/* VRS_END, */
|
2008-10-25 12:53:57 +00:00
|
|
|
|
2009-07-08 19:06:07 +00:00
|
|
|
LI_VRS_ERROR
|
|
|
|
} liVRequestState;
|
2008-10-25 12:53:57 +00:00
|
|
|
|
2013-05-22 15:26:33 +00:00
|
|
|
typedef void (*liVRequestHandlerCB)(liVRequest *vr);
|
2013-05-21 15:16:44 +00:00
|
|
|
typedef liThrottleState* (*liVRequestThrottleCB)(liVRequest *vr);
|
2013-05-25 21:51:46 +00:00
|
|
|
typedef void (*liVRequestConnectionUpgradeCB)(liVRequest *vr, liStream *backend_drain, liStream *backend_source);
|
2010-07-31 12:44:45 +00:00
|
|
|
|
|
|
|
struct liConCallbacks {
|
2013-05-22 15:26:33 +00:00
|
|
|
liVRequestHandlerCB handle_response_error; /* this is _not_ for 500 - internal error */
|
2013-05-21 15:16:44 +00:00
|
|
|
liVRequestThrottleCB throttle_out, throttle_in;
|
2013-05-25 21:51:46 +00:00
|
|
|
liVRequestConnectionUpgradeCB connection_upgrade;
|
2010-07-31 12:44:45 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* this data "belongs" to a vrequest, but is updated by the connection code */
|
|
|
|
struct liConInfo {
|
|
|
|
const liConCallbacks *callbacks;
|
|
|
|
|
|
|
|
liSocketAddress remote_addr, local_addr;
|
|
|
|
GString *remote_addr_str, *local_addr_str;
|
|
|
|
gboolean is_ssl;
|
|
|
|
gboolean keep_alive;
|
2013-05-22 15:26:33 +00:00
|
|
|
gboolean aborted; /* network aborted connection before response was sent completely */
|
|
|
|
|
|
|
|
liStream *req;
|
|
|
|
liStream *resp;
|
2010-07-31 12:44:45 +00:00
|
|
|
|
|
|
|
/* bytes in our "raw-io-out-queue" that hasn't be sent yet. (whatever "sent" means - in ssl buffer, kernel, ...) */
|
|
|
|
goffset out_queue_length;
|
|
|
|
|
|
|
|
/* use li_vrequest_update_stats_{in,out} to update this */
|
|
|
|
struct {
|
|
|
|
guint64 bytes_in; /* total number of bytes received */
|
|
|
|
guint64 bytes_out; /* total number of bytes sent */
|
2013-05-25 12:37:09 +00:00
|
|
|
li_tstamp last_avg;
|
2010-07-31 12:44:45 +00:00
|
|
|
guint64 bytes_in_5s; /* total number of bytes received at last 5s interval */
|
|
|
|
guint64 bytes_out_5s; /* total number of bytes sent at last 5s interval */
|
|
|
|
guint64 bytes_in_5s_diff; /* diff between bytes received at 5s interval n and interval n-1 */
|
|
|
|
guint64 bytes_out_5s_diff; /* diff between bytes sent at 5s interval n and interval n-1 */
|
|
|
|
} stats;
|
|
|
|
};
|
2008-10-25 12:53:57 +00:00
|
|
|
|
2009-07-08 19:06:07 +00:00
|
|
|
struct liVRequest {
|
2010-07-31 12:44:45 +00:00
|
|
|
liConInfo *coninfo;
|
2009-07-08 19:06:07 +00:00
|
|
|
liWorker *wrk;
|
2008-10-25 12:53:57 +00:00
|
|
|
|
2009-07-08 19:06:07 +00:00
|
|
|
liOptionValue *options;
|
2010-01-24 20:30:41 +00:00
|
|
|
liOptionPtrValue **optionptrs;
|
2008-12-30 00:21:03 +00:00
|
|
|
|
2012-03-17 14:52:19 +00:00
|
|
|
liLogContext log_context;
|
|
|
|
|
2009-07-08 19:06:07 +00:00
|
|
|
liVRequestState state;
|
2008-10-25 12:53:57 +00:00
|
|
|
|
2013-05-25 12:37:09 +00:00
|
|
|
li_tstamp ts_started;
|
2010-01-03 16:39:26 +00:00
|
|
|
|
2008-10-25 12:53:57 +00:00
|
|
|
GPtrArray *plugin_ctx;
|
|
|
|
|
2009-07-08 19:06:07 +00:00
|
|
|
liRequest request;
|
|
|
|
liPhysical physical;
|
|
|
|
liResponse response;
|
2008-10-25 12:53:57 +00:00
|
|
|
|
2009-02-15 17:55:27 +00:00
|
|
|
/* environment entries will be passed to the backends */
|
2009-07-08 19:06:07 +00:00
|
|
|
liEnvironment env;
|
2008-12-31 15:23:00 +00:00
|
|
|
|
2009-12-19 21:18:10 +00:00
|
|
|
/* -> vr_in -> filters_in -> in_memory ->(buffer_on_disk) -> in -> handle -> out -> filters_out -> vr_out -> */
|
2013-05-22 15:26:33 +00:00
|
|
|
GPtrArray *filters;
|
|
|
|
liStream *filters_in_last, *filters_out_last;
|
|
|
|
liStream *filters_in_first, *filters_out_first;
|
|
|
|
|
2013-05-23 10:00:44 +00:00
|
|
|
liStream *in_buffer_on_disk_stream, *wait_for_request_body_stream;
|
2008-10-25 12:53:57 +00:00
|
|
|
|
2013-05-22 15:26:33 +00:00
|
|
|
liPlugin *backend;
|
|
|
|
liStream *backend_source;
|
|
|
|
liStream *backend_drain;
|
|
|
|
liChunkQueue *direct_out; /* NULL for indirect responses, backend_source->out for direct responses. do not set this yourself for indirect responses! */
|
|
|
|
|
2009-07-08 19:06:07 +00:00
|
|
|
liActionStack action_stack;
|
2008-12-30 20:55:00 +00:00
|
|
|
|
2010-09-05 11:21:42 +00:00
|
|
|
liJob job;
|
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
|
|
|
};
|
|
|
|
|
2013-05-23 10:00:44 +00:00
|
|
|
#define LI_VREQUEST_WAIT_FOR_REQUEST_BODY(vr) \
|
|
|
|
do { \
|
|
|
|
if (!li_vrequest_wait_for_request_body(vr)) { \
|
|
|
|
return LI_HANDLER_WAIT_FOR_EVENT; \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
2013-05-22 16:42:21 +00:00
|
|
|
#define LI_VREQUEST_WAIT_FOR_RESPONSE_HEADERS(vr) \
|
2008-12-31 01:57:27 +00:00
|
|
|
do { \
|
2009-07-08 19:06:07 +00:00
|
|
|
if (vr->state == LI_VRS_HANDLE_REQUEST_HEADERS) { \
|
2008-12-31 01:57:27 +00:00
|
|
|
VR_ERROR(vr, "%s", "Cannot wait for response headers as no backend handler found - fix your config"); \
|
2009-07-08 19:06:07 +00:00
|
|
|
return LI_HANDLER_ERROR; \
|
|
|
|
} else if (vr->state < LI_VRS_HANDLE_RESPONSE_HEADERS) { \
|
|
|
|
return LI_HANDLER_WAIT_FOR_EVENT; \
|
2008-12-31 01:57:27 +00:00
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
2010-08-25 22:34:28 +00:00
|
|
|
LI_API liVRequest* li_vrequest_new(liWorker *wrk, liConInfo *coninfo);
|
2009-07-09 20:17:24 +00:00
|
|
|
LI_API void li_vrequest_free(liVRequest *vr);
|
2009-10-07 14:02:09 +00:00
|
|
|
/* if keepalive = TRUE, you either have to reset it later again with FALSE or call li_vrequest_start before reusing the vr;
|
|
|
|
* keepalive = TRUE doesn't reset the vr->request fields, so mod_status can show the last request data in the keep-alive state
|
|
|
|
*/
|
|
|
|
LI_API void li_vrequest_reset(liVRequest *vr, gboolean keepalive);
|
2008-10-25 12:53:57 +00:00
|
|
|
|
2013-05-23 10:00:44 +00:00
|
|
|
/****************************************************/
|
|
|
|
/* called by connection */
|
|
|
|
/****************************************************/
|
2009-10-07 14:02:09 +00:00
|
|
|
/* resets fields which weren't reset in favor of keep-alive tracking */
|
|
|
|
LI_API void li_vrequest_start(liVRequest *vr);
|
2008-10-25 12:53:57 +00:00
|
|
|
/* received all request headers */
|
2009-07-09 20:17:24 +00:00
|
|
|
LI_API void li_vrequest_handle_request_headers(liVRequest *vr);
|
2008-10-25 12:53:57 +00:00
|
|
|
|
2013-05-23 10:00:44 +00:00
|
|
|
/* called by connection IO handling */
|
|
|
|
LI_API void li_vrequest_update_stats_in(liVRequest *vr, goffset transferred);
|
|
|
|
LI_API void li_vrequest_update_stats_out(liVRequest *vr, goffset transferred);
|
|
|
|
|
|
|
|
/****************************************************/
|
|
|
|
/* called by actions handling the request */
|
|
|
|
/****************************************************/
|
|
|
|
/* returns TRUE if request body is present
|
|
|
|
* or shouldn't be waited for (if caching on disk is disabled and liCQLimit hit, ...)
|
|
|
|
* if it returns FALSE it will trigger li_vrequest_joblist_append later */
|
|
|
|
LI_API gboolean li_vrequest_wait_for_request_body(liVRequest *vr);
|
|
|
|
|
2013-05-22 15:26:33 +00:00
|
|
|
/* response completely ready; use this only in action callbacks */
|
2009-07-09 20:17:24 +00:00
|
|
|
LI_API gboolean li_vrequest_handle_direct(liVRequest *vr);
|
2013-05-22 15:26:33 +00:00
|
|
|
/* check whether the request is already handled */
|
|
|
|
LI_API gboolean li_vrequest_is_handled(liVRequest *vr);
|
|
|
|
|
2008-10-25 12:53:57 +00:00
|
|
|
/* handle request over time */
|
2009-07-09 20:17:24 +00:00
|
|
|
LI_API gboolean li_vrequest_handle_indirect(liVRequest *vr, liPlugin *p);
|
2013-05-22 15:26:33 +00:00
|
|
|
/* signal that backend connection is ready - after this a backend error might result in a internal error */
|
|
|
|
LI_API void li_vrequest_indirect_connect(liVRequest *vr, liStream *backend_drain, liStream *backend_source);
|
|
|
|
/* received all response headers/status code - call once from your indirect handler */
|
|
|
|
LI_API void li_vrequest_indirect_headers_ready(liVRequest *vr);
|
2008-10-25 12:53:57 +00:00
|
|
|
|
2013-05-25 21:51:46 +00:00
|
|
|
/* call instead of headers_ready */
|
|
|
|
LI_API void li_vrequest_connection_upgrade(liVRequest *vr, liStream *backend_drain, liStream *backend_source);
|
|
|
|
|
2013-05-23 10:00:44 +00:00
|
|
|
/* Signals an internal error; handles the error in the _next_ loop */
|
|
|
|
LI_API void li_vrequest_error(liVRequest *vr);
|
|
|
|
|
|
|
|
LI_API void li_vrequest_backend_overloaded(liVRequest *vr);
|
|
|
|
LI_API void li_vrequest_backend_dead(liVRequest *vr);
|
|
|
|
LI_API void li_vrequest_backend_error(liVRequest *vr, liBackendError berror);
|
|
|
|
LI_API void li_vrequest_backend_finished(liVRequest *vr); /* action.c */
|
|
|
|
|
|
|
|
|
|
|
|
|
2009-07-09 20:17:24 +00:00
|
|
|
LI_API void li_vrequest_state_machine(liVRequest *vr);
|
|
|
|
LI_API void li_vrequest_joblist_append(liVRequest *vr);
|
2010-09-05 11:21:42 +00:00
|
|
|
LI_API liJobRef* li_vrequest_get_ref(liVRequest *vr);
|
2008-10-25 12:53:57 +00:00
|
|
|
|
2009-07-09 20:17:24 +00:00
|
|
|
LI_API gboolean li_vrequest_redirect(liVRequest *vr, GString *uri);
|
2009-11-15 20:59:16 +00:00
|
|
|
LI_API gboolean li_vrequest_redirect_directory(liVRequest *vr);
|
|
|
|
|
2010-07-31 12:44:45 +00:00
|
|
|
|
2008-10-25 12:53:57 +00:00
|
|
|
#endif
|