.begin = "Last-Modified",
.len = 13
};
-static gsize rspamd_http_global_max_size = 0;
static void rspamd_http_message_storage_cleanup (struct rspamd_http_message *msg);
static gboolean rspamd_http_message_grow_body (struct rspamd_http_message *msg,
priv->flags &= ~RSPAMD_HTTP_CONN_FLAG_NEW_HEADER;
}
- if (conn->type == RSPAMD_HTTP_SERVER &&
- rspamd_http_global_max_size > 0 &&
- parser->content_length > rspamd_http_global_max_size) {
- /* Too large message */
- priv->flags |= RSPAMD_HTTP_CONN_FLAG_TOO_LARGE;
- return -1;
- }
+ /*
+ * HTTP parser sets content length to (-1) when it doesn't know the real
+ * length, for example, in case of chunked encoding.
+ *
+ * Hence, we skip body setup here
+ */
+ if (parser->content_length != ULLONG_MAX) {
+ if (conn->max_size > 0 &&
+ parser->content_length > conn->max_size) {
+ /* Too large message */
+ priv->flags |= RSPAMD_HTTP_CONN_FLAG_TOO_LARGE;
+ return -1;
+ }
- if (!rspamd_http_message_set_body (msg, NULL, parser->content_length)) {
- return -1;
+ if (!rspamd_http_message_set_body (msg, NULL, parser->content_length)) {
+ return -1;
+ }
}
if (parser->flags & F_SPAMC) {
pbuf = priv->buf;
p = at;
- if (conn->type == RSPAMD_HTTP_SERVER &&
- rspamd_http_global_max_size > 0 &&
- msg->body_buf.len + length > rspamd_http_global_max_size) {
+ if (!(msg->flags & RSPAMD_HTTP_FLAG_HAS_BODY)) {
+ if (!rspamd_http_message_set_body (msg, NULL, parser->content_length)) {
+ return -1;
+ }
+ }
+
+ if (conn->max_size > 0 &&
+ msg->body_buf.len + length > conn->max_size) {
/* Body length overflow */
priv->flags |= RSPAMD_HTTP_CONN_FLAG_TOO_LARGE;
return -1;
d, r) != (size_t)r || priv->parser.http_errno != 0) {
if (priv->flags & RSPAMD_HTTP_CONN_FLAG_TOO_LARGE) {
err = g_error_new (HTTP_ERROR, 413,
- "Request entity too large");
+ "Request entity too large: %zu",
+ (size_t)priv->parser.content_length);
}
else {
err = g_error_new (HTTP_ERROR, priv->parser.http_errno,
msg->body_buf.allocated_len = storage->normal->allocated;
}
+ msg->flags |= RSPAMD_HTTP_FLAG_HAS_BODY;
+
return TRUE;
}
}
void
-rspamd_http_message_set_max_size (gsize sz)
+rspamd_http_connection_set_max_size (struct rspamd_http_connection *conn,
+ gsize sz)
{
- rspamd_http_global_max_size = sz;
+ conn->max_size = sz;
}
void
* Use tls for this message
*/
#define RSPAMD_HTTP_FLAG_SSL (1 << 4)
+/**
+ * Body has been set for a message
+ */
+#define RSPAMD_HTTP_FLAG_HAS_BODY (1 << 5)
/**
* Options for HTTP connection
rspamd_http_finish_handler_t finish_handler;
struct rspamd_keypair_cache *cache;
gpointer ud;
+ gsize max_size;
unsigned opts;
enum rspamd_http_connection_type type;
gboolean finished;
* Sets global maximum size for HTTP message being processed
* @param sz
*/
-void rspamd_http_message_set_max_size (gsize sz);
+void rspamd_http_connection_set_max_size (struct rspamd_http_connection *conn,
+ gsize sz);
/**
* Increase refcount for shared file (if any) to prevent early memory unlinking