Skip to content

Commit 56e0889

Browse files
Merge pull request #1060 from tempesta-tech/ao-1058
Fix #1058: Protocol/port persistence support during redirection.
2 parents f686e49 + c618c65 commit 56e0889

File tree

4 files changed

+32
-28
lines changed

4 files changed

+32
-28
lines changed

tempesta_fw/connection.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ typedef struct {
106106
} TfwConn;
107107

108108
#define TFW_CONN_TYPE(c) ((c)->proto.type)
109+
#define TFW_CONN_PROTO(c) TFW_CONN_TYPE2IDX(TFW_CONN_TYPE(c))
109110

110111
/*
111112
* Queues in client and server connections provide support for correct

tempesta_fw/http.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ static struct {
5959

6060
#define S_CRLFCRLF "\r\n\r\n"
6161
#define S_HTTP "http://"
62+
#define S_HTTPS "https://"
6263

6364
#define S_0 "HTTP/1.1 "
6465
#define S_200 "HTTP/1.1 200 OK"
@@ -343,6 +344,7 @@ unsigned long tfw_hash_str(const TfwStr *str);
343344
#define S_REDIR_KEEP S_CRLF S_F_CONNECTION S_V_CONN_KA S_CRLF
344345
#define S_REDIR_CLOSE S_CRLF S_F_CONNECTION S_V_CONN_CLOSE S_CRLF
345346
#define S_REDIR_C_LEN S_F_CONTENT_LENGTH "0" S_CRLFCRLF
347+
346348
/**
347349
* The response redirects the client to the same URI as the original request,
348350
* but it includes 'Set-Cookie:' header field that sets Tempesta sticky cookie.
@@ -390,6 +392,11 @@ tfw_http_prep_redirect(TfwHttpMsg *resp, unsigned short status, TfwStr *rmark,
390392
.ptr = S_REDIR_CLOSE, .len = SLEN(S_REDIR_CLOSE) };
391393
static TfwStr c_len_crlf = {
392394
.ptr = S_REDIR_C_LEN, .len = SLEN(S_REDIR_C_LEN) };
395+
static TfwStr protos[] = {
396+
{ .ptr = S_HTTP, .len = SLEN(S_HTTP) },
397+
{ .ptr = S_HTTPS, .len = SLEN(S_HTTPS) },
398+
};
399+
TfwStr *proto = &protos[TFW_CONN_PROTO(req->conn) == TFW_FSM_HTTPS];
393400
TfwStr host, *rh, *cookie_crlf = &crlf, *r_end;
394401

395402
if (status == 302) {
@@ -405,10 +412,11 @@ tfw_http_prep_redirect(TfwHttpMsg *resp, unsigned short status, TfwStr *rmark,
405412
else
406413
r_end = &c_len_crlf;
407414

408-
tfw_http_msg_clnthdr_val(&req->h_tbl->tbl[TFW_HTTP_HDR_HOST],
409-
TFW_HTTP_HDR_HOST, &host);
410-
if (TFW_STR_EMPTY(&host))
415+
if (req->host.len)
411416
host = req->host;
417+
else
418+
tfw_http_msg_clnthdr_val(&req->h_tbl->tbl[TFW_HTTP_HDR_HOST],
419+
TFW_HTTP_HDR_HOST, &host);
412420

413421
/* Set "Connection:" header field if needed. */
414422
if (conn_flag == TFW_HTTP_F_CONN_CLOSE)
@@ -418,7 +426,7 @@ tfw_http_prep_redirect(TfwHttpMsg *resp, unsigned short status, TfwStr *rmark,
418426

419427
/* Add variable part of data length to get the total */
420428
data_len = rh->len + h_common_1.len;
421-
data_len += host.len ? host.len + SLEN(S_HTTP) : 0;
429+
data_len += host.len ? host.len + proto->len : 0;
422430
data_len += rmark->len;
423431
data_len += req->uri_path.len + h_common_2.len + cookie->len;
424432
data_len += cookie_crlf->len + r_end->len;
@@ -436,8 +444,7 @@ tfw_http_prep_redirect(TfwHttpMsg *resp, unsigned short status, TfwStr *rmark,
436444
* See RFC 1945 9.3 and RFC 7231 7.1.2.
437445
*/
438446
if (host.len) {
439-
static TfwStr proto = { .ptr = S_HTTP, .len = SLEN(S_HTTP) };
440-
ret |= tfw_http_msg_write(&it, resp, &proto);
447+
ret |= tfw_http_msg_write(&it, resp, proto);
441448
ret |= tfw_http_msg_write(&it, resp, &host);
442449
}
443450

@@ -2766,7 +2773,6 @@ tfw_http_req_process(TfwConn *conn, const TfwFsmData *data)
27662773
if ((req->vhost = tfw_http_tbl_vhost((TfwMsg *)req, &block)))
27672774
req->location = tfw_location_match(req->vhost,
27682775
&req->uri_path);
2769-
27702776
r = tfw_gfsm_move(&conn->state, TFW_HTTP_FSM_REQ_MSG,
27712777
&data_up);
27722778
TFW_DBG3("TFW_HTTP_FSM_REQ_MSG return code %d\n", r);

tempesta_fw/http_parser.c

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3280,6 +3280,8 @@ tfw_http_parse_req(void *req_data, unsigned char *data, size_t len)
32803280
}
32813281

32823282
__FSM_STATE(Req_UriAuthorityEnd) {
3283+
if (c == ':')
3284+
__FSM_MOVE_f(Req_UriPort, &req->host);
32833285
/* Authority End */
32843286
__msg_field_finish(&req->host, p);
32853287
TFW_DBG3("Userinfo len = %i, host len = %i\n",
@@ -3290,27 +3292,21 @@ tfw_http_parse_req(void *req_data, unsigned char *data, size_t len)
32903292
else if (c == ' ') {
32913293
__FSM_MOVE_nofixup(Req_HttpVer);
32923294
}
3293-
else if (c == ':') {
3294-
__FSM_MOVE_nofixup(Req_UriPort);
3295-
}
3296-
else {
3297-
TFW_PARSER_BLOCK(Req_UriAuthorityEnd);
3298-
}
3295+
TFW_PARSER_BLOCK(Req_UriAuthorityEnd);
32993296
}
33003297

33013298
/* Host port in URI */
33023299
__FSM_STATE(Req_UriPort) {
33033300
if (likely(isdigit(c)))
3304-
__FSM_MOVE_nofixup(Req_UriPort);
3305-
else if (likely(c == '/')) {
3301+
__FSM_MOVE_f(Req_UriPort, &req->host);
3302+
__msg_field_finish(&req->host, p);
3303+
if (likely(c == '/')) {
33063304
__FSM_JMP(Req_UriMark);
33073305
}
33083306
else if (c == ' ') {
33093307
__FSM_MOVE_nofixup(Req_HttpVer);
33103308
}
3311-
else {
3312-
TFW_PARSER_BLOCK(Req_UriPort);
3313-
}
3309+
TFW_PARSER_BLOCK(Req_UriPort);
33143310
}
33153311

33163312
__FSM_STATE(Req_UriMark) {

tempesta_fw/t/unit/test_http_parser.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -435,9 +435,10 @@ TEST(http_parser, parses_req_uri)
435435
"/a/b/c/dir/?foo=1&bar=2#abcd");
436436
}
437437

438-
/* Absolute URI. */
439-
/* NOTE: we don't include port to the req->host */
440-
438+
/*
439+
* Absolute URI.
440+
* NOTE: we combine host and port URI parts into one field 'req->host'.
441+
*/
441442
FOR_REQ("GET http://natsys-lab.com/ HTTP/1.1\r\n\r\n") {
442443
EXPECT_TFWSTR_EQ(&req->host, "natsys-lab.com");
443444
EXPECT_TFWSTR_EQ(&req->uri_path, "/");
@@ -449,12 +450,12 @@ TEST(http_parser, parses_req_uri)
449450
}
450451

451452
FOR_REQ("GET http://natsys-lab.com:8080/ HTTP/1.1\r\n\r\n") {
452-
EXPECT_TFWSTR_EQ(&req->host, "natsys-lab.com");
453+
EXPECT_TFWSTR_EQ(&req->host, "natsys-lab.com:8080");
453454
EXPECT_TFWSTR_EQ(&req->uri_path, "/");
454455
}
455456

456457
FOR_REQ("GET http://natsys-lab.com:8080 HTTP/1.1\r\n\r\n") {
457-
EXPECT_TFWSTR_EQ(&req->host, "natsys-lab.com");
458+
EXPECT_TFWSTR_EQ(&req->host, "natsys-lab.com:8080");
458459
EXPECT_TFWSTR_EQ(&req->uri_path, "");
459460
}
460461

@@ -466,7 +467,7 @@ TEST(http_parser, parses_req_uri)
466467
FOR_REQ("GET http://natsys-lab.com:8080/cgi-bin/show.pl?entry=tempesta"
467468
" HTTP/1.1\r\n\r\n")
468469
{
469-
EXPECT_TFWSTR_EQ(&req->host, "natsys-lab.com");
470+
EXPECT_TFWSTR_EQ(&req->host, "natsys-lab.com:8080");
470471
EXPECT_TFWSTR_EQ(&req->uri_path,
471472
"/cgi-bin/show.pl?entry=tempesta");
472473
}
@@ -511,7 +512,7 @@ TEST(http_parser, parses_enforce_ext_req)
511512
"Accept: */*\r\n"
512513
"\r\n")
513514
{
514-
EXPECT_TFWSTR_EQ(&req->host, "natsys-lab.com");
515+
EXPECT_TFWSTR_EQ(&req->host, "natsys-lab.com:8080");
515516
EXPECT_TFWSTR_EQ(&req->uri_path, "/cgi-bin/show.pl");
516517
}
517518
}
@@ -558,19 +559,19 @@ TEST(http_parser, parses_enforce_ext_req_rmark)
558559
}
559560

560561
FOR_REQ("GET " AUTH RMARK URI_1 " HTTP/1.1\r\n\r\n") {
561-
EXPECT_TFWSTR_EQ(&req->host, HOST);
562+
EXPECT_TFWSTR_EQ(&req->host, HOST ":" PORT);
562563
EXPECT_TFWSTR_EQ(&req->mark, RMARK);
563564
EXPECT_TFWSTR_EQ(&req->uri_path, URI_1);
564565
}
565566

566567
FOR_REQ("GET " AUTH RMARK URI_3 " HTTP/1.1\r\n\r\n") {
567-
EXPECT_TFWSTR_EQ(&req->host, HOST);
568+
EXPECT_TFWSTR_EQ(&req->host, HOST ":" PORT);
568569
EXPECT_TFWSTR_EQ(&req->mark, RMARK);
569570
EXPECT_TFWSTR_EQ(&req->uri_path, URI_3);
570571
}
571572

572573
FOR_REQ("GET " AUTH RMARK URI_4 " HTTP/1.1\r\n\r\n") {
573-
EXPECT_TFWSTR_EQ(&req->host, HOST);
574+
EXPECT_TFWSTR_EQ(&req->host, HOST ":" PORT);
574575
EXPECT_TFWSTR_EQ(&req->mark, RMARK);
575576
EXPECT_TFWSTR_EQ(&req->uri_path, URI_4);
576577
}

0 commit comments

Comments
 (0)