Skip to content

Commit

Permalink
recreate Content-Type request header for multipart/form-data requests
Browse files Browse the repository at this point in the history
  • Loading branch information
i-rinat committed Jan 15, 2019
1 parent fecfec5 commit add646e
Show file tree
Hide file tree
Showing 6 changed files with 601 additions and 8 deletions.
48 changes: 48 additions & 0 deletions tempesta_fw/http.c
Original file line number Diff line number Diff line change
Expand Up @@ -2114,6 +2114,45 @@ tfw_http_set_loc_hdrs(TfwHttpMsg *hm, TfwHttpReq *req)
return 0;
}

static int
tfw_http_recreate_content_type_multipart_hdr(TfwHttpReq *req)
{
TfwStr replacement = {
.ptr = (TfwStr []) {
TFW_STR_FROM("Content-Type"),
TFW_STR_FROM(": "),
TFW_STR_FROM("multipart/form-data; boundary="),
req->multipart_boundary_raw,
},
.flags = 4 << TFW_STR_CN_SHIFT,
};
TfwStr *c = replacement.ptr;

BUG_ON(!TFW_STR_PLAIN(&req->multipart_boundary_raw));
replacement.len = c[0].len + c[1].len + c[2].len + c[3].len;
return tfw_http_msg_hdr_xfrm_str((TfwHttpMsg *)req, &replacement,
TFW_HTTP_HDR_CONTENT_TYPE, false);
}

static bool
tfw_http_should_validate_post_req(TfwHttpReq *req)
{
if (req->location && req->location->validate_post_req)
return true;

if (!req->vhost)
return false;

if (req->vhost->loc_dflt && req->vhost->loc_dflt->validate_post_req)
return true;

if (req->vhost->vhost_dflt &&
req->vhost->vhost_dflt->loc_dflt->validate_post_req)
return true;

return false;
}

/**
* Adjust the request before proxying it to real server.
*/
Expand Down Expand Up @@ -2143,6 +2182,15 @@ tfw_http_adjust_req(TfwHttpReq *req)
if (r < 0)
return r;

if (req->method == TFW_HTTP_METH_POST &&
test_bit(TFW_HTTP_B_CT_MULTIPART, req->flags) &&
tfw_http_should_validate_post_req(req))
{
r = tfw_http_recreate_content_type_multipart_hdr(req);
if (r)
return r;
}

return tfw_http_set_hdr_connection(hm, BIT(TFW_HTTP_B_CONN_KA));
}

Expand Down
8 changes: 8 additions & 0 deletions tempesta_fw/http.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,10 @@ enum {
TFW_HTTP_B_CONN_EXTRA,
/* Chunked transfer encoding. */
TFW_HTTP_B_CHUNKED,
/* Media type is multipart/form-data. */
TFW_HTTP_B_CT_MULTIPART,
/* Multipart/form-data request have boundary parameter. */
TFW_HTTP_B_CT_MULTIPART_HAS_BOUNDARY,
/* Singular header presents more than once. */
TFW_HTTP_B_FIELD_DUPENTRY,

Expand Down Expand Up @@ -369,6 +373,8 @@ typedef struct {
* @host - host in URI, may differ from Host header;
* @uri_path - path + query + fragment from URI (RFC3986.3);
* @mark - special hash mark for redirects handling in session module;
* @multipart_boundary_raw - multipart boundary as is, maybe with escaped chars;
* @multipart_boundary - decoded multipart boundary;
* @fwd_list - member in the queue of forwarded/backlogged requests;
* @nip_list - member in the queue of non-idempotent requests;
* @method - HTTP request method, one of GET/PORT/HEAD/etc;
Expand All @@ -394,6 +400,8 @@ struct tfw_http_req_t {
TfwStr host;
TfwStr uri_path;
TfwStr mark;
TfwStr multipart_boundary_raw;
TfwStr multipart_boundary;
struct list_head fwd_list;
struct list_head nip_list;
unsigned char method;
Expand Down
Loading

0 comments on commit add646e

Please sign in to comment.