struct http_request req;
pool_t pool;
unsigned int refcount;
+ unsigned int id;
enum http_server_request_state state;
static inline const char *
http_server_request_label(struct http_server_request *req)
{
- if (req->req.method == NULL || req->req.target_raw == NULL)
- return "[INVALID]";
- return t_strdup_printf("[%s %s]", req->req.method, req->req.target_raw);
+ if (req->req.method == NULL) {
+ if (req->req.target_raw == NULL)
+ return t_strdup_printf("[Req%u: <NEW>]", req->id);
+ return t_strdup_printf("[Req%u: %s <INCOMPLETE>]",
+ req->id, req->req.method);
+ }
+ return t_strdup_printf("[Req%u: %s %s]", req->id,
+ req->req.method, req->req.target_raw);
}
static inline const char *
#include "http-server-private.h"
+/*
+ * Logging
+ */
+
+static inline void
+http_server_request_debug(struct http_server_request *req,
+ const char *format, ...) ATTR_FORMAT(2, 3);
+
+static inline void
+http_server_request_debug(struct http_server_request *req,
+ const char *format, ...)
+{
+ struct http_server *server = req->server;
+ va_list args;
+
+ if (server->set.debug) {
+ va_start(args, format);
+ i_debug("http-server: request %s: %s",
+ http_server_request_label(req),
+ t_strdup_vprintf(format, args));
+ va_end(args);
+ }
+}
+
+/*
+ * Request
+ */
+
struct http_server_request *
http_server_request_new(struct http_server_connection *conn)
{
+ static unsigned int id_counter = 0;
pool_t pool;
struct http_server_request *req;
req->refcount = 1;
req->conn = conn;
req->server = conn->server;
+ req->id = ++id_counter;
http_server_connection_add_request(conn, req);
return req;
if (--req->refcount > 0)
return TRUE;
+ http_server_request_debug(req, "Free");
+
if (req->state < HTTP_SERVER_REQUEST_STATE_FINISHED) {
req->state = HTTP_SERVER_REQUEST_STATE_ABORTED;
http_server_connection_remove_request(conn, req);
{
struct http_server_request *req = *_req;
+ http_server_request_debug(req, "Destroy");
+
if (req->delay_destroy) {
req->destroy_pending = TRUE;
} else if (req->destroy_callback != NULL) {
struct http_server_request *req = *_req;
struct http_server_connection *conn = req->conn;
+ http_server_request_debug(req, "Abort");
+
if (req->state < HTTP_SERVER_REQUEST_STATE_FINISHED) {
req->state = HTTP_SERVER_REQUEST_STATE_ABORTED;
http_server_connection_remove_request(conn, req);
http_server_tunnel_callback_t tunnel_callback = resp->tunnel_callback;
void *tunnel_context = resp->tunnel_context;
+ http_server_request_debug(req, "Finished");
+
i_assert(req->state < HTTP_SERVER_REQUEST_STATE_FINISHED);
req->state = HTTP_SERVER_REQUEST_STATE_FINISHED;