| /** @file | |
| A brief file description | |
| @section license License | |
| Licensed to the Apache Software Foundation (ASF) under one | |
| or more contributor license agreements. See the NOTICE file | |
| distributed with this work for additional information | |
| regarding copyright ownership. The ASF licenses this file | |
| to you under the Apache License, Version 2.0 (the | |
| "License"); you may not use this file except in compliance | |
| with the License. You may obtain a copy of the License at | |
| http://www.apache.org/licenses/LICENSE-2.0 | |
| Unless required by applicable law or agreed to in writing, software | |
| distributed under the License is distributed on an "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| See the License for the specific language governing permissions and | |
| limitations under the License. | |
| */ | |
| #include "tscore/Regression.h" | |
| #include "proxy/http/HttpTransact.h" | |
| #include "proxy/http/HttpSM.h" | |
| #include <string_view> | |
| using namespace std::literals; | |
| void | |
| forceLinkRegressionHttpTransact() | |
| { | |
| } | |
| static void | |
| init_sm(HttpSM *sm) | |
| { | |
| sm->init(); | |
| sm->t_state.hdr_info.client_request.create(HTTPType::REQUEST, HTTP_1_1, nullptr); | |
| } | |
| static void | |
| setup_client_request(HttpSM *sm, std::string_view scheme, const char *request) | |
| { | |
| init_sm(sm); | |
| MIOBuffer *read_buffer = new_MIOBuffer(HTTP_HEADER_BUFFER_SIZE_INDEX); | |
| IOBufferReader *buffer_reader = read_buffer->alloc_reader(); | |
| read_buffer->write(request, strlen(request)); | |
| HTTPParser httpParser; | |
| http_parser_init(&httpParser); | |
| int bytes_used = 0; | |
| sm->t_state.hdr_info.client_request.parse_req(&httpParser, buffer_reader, &bytes_used, true /* eos */); | |
| sm->t_state.hdr_info.client_request.url_get()->scheme_set(scheme); | |
| sm->t_state.method = sm->t_state.hdr_info.client_request.method_get_wksidx(); | |
| free_MIOBuffer(read_buffer); | |
| } | |
| /* | |
| pstatus return values | |
| REGRESSION_TEST_PASSED | |
| REGRESSION_TEST_INPROGRESS | |
| REGRESSION_TEST_FAILED | |
| REGRESSION_TEST_NOT_RUN | |
| */ | |
| REGRESSION_TEST(HttpTransact_is_request_valid)(RegressionTest *t, int /* level */, int *pstatus) | |
| { | |
| HttpTransact transaction; | |
| HttpSM sm; | |
| *pstatus = REGRESSION_TEST_PASSED; | |
| struct { | |
| std::string_view scheme; | |
| const char *req; | |
| bool result; | |
| } requests[] = { | |
| // missing host header | |
| {"http"sv, "GET / HTTP/1.1\r\n\r\n", false}, | |
| // good get request | |
| {"http"sv, "GET / HTTP/1.1\r\nHost: abc.com\r\n\r\n", true }, | |
| // good trace request | |
| {"http"sv, "TRACE / HTTP/1.1\r\nHost: abc.com\r\n\r\n", true }, | |
| // content len < 0 | |
| {"http"sv, "POST / HTTP/1.1\r\nHost: abc.com\r\nContent-Length: -1\r\n\r\n", false}, | |
| {"http"sv, "PUSH / HTTP/1.1\r\nHost: abc.com\r\nContent-Length: -1\r\n\r\n", false}, | |
| {"http"sv, "PUT / HTTP/1.1\r\nHost: abc.com\r\nContent-Length: -1\r\n\r\n", false}, | |
| // valid content len | |
| {"http"sv, "POST / HTTP/1.1\r\nHost: abc.com\r\nContent-Length: 10\r\n\r\n", true }, | |
| {"http"sv, "PUSH / HTTP/1.1\r\nHost: abc.com\r\nContent-Length: 10\r\n\r\n", true }, | |
| {"http"sv, "PUT / HTTP/1.1\r\nHost: abc.com\r\nContent-Length: 10\r\n\r\n", true }, | |
| // Content Length missing | |
| {"http"sv, "POST / HTTP/1.1\r\nHost: abc.com\r\n\r\n", false}, | |
| {"http"sv, "PUSH / HTTP/1.1\r\nHost: abc.com\r\n\r\n", false}, | |
| {"http"sv, "PUT / HTTP/1.1\r\nHost: abc.com\r\n\r\n", false}, | |
| {""sv, nullptr, false} | |
| }; | |
| for (int i = 0; requests[i].req; i++) { | |
| setup_client_request(&sm, requests[i].scheme, requests[i].req); | |
| if (requests[i].result != transaction.is_request_valid(&sm.t_state, &sm.t_state.hdr_info.client_request)) { | |
| rprintf(t, "HttpTransact::is_request_valid - failed for request = '%s'. Expected result was %s request\n", requests[i].req, | |
| (requests[i].result ? "valid" : "invalid")); | |
| *pstatus = REGRESSION_TEST_FAILED; | |
| } | |
| } | |
| } | |
| REGRESSION_TEST(HttpTransact_handle_trace_and_options_requests)(RegressionTest *t, int /* level */, int *pstatus) | |
| { | |
| HttpTransact transaction; | |
| HttpSM sm; | |
| *pstatus = REGRESSION_TEST_PASSED; | |
| struct { | |
| const char *scheme; | |
| const char *req; | |
| bool result; | |
| } requests[] = { | |
| // good trace request | |
| {"http", "TRACE www.abc.com/ HTTP/1.1\r\nHost: abc.com\r\nMax-Forwards: 0\r\n\r\n", true }, | |
| {nullptr, nullptr, false} | |
| }; | |
| for (int i = 0; requests[i].req; i++) { | |
| setup_client_request(&sm, requests[i].scheme, requests[i].req); | |
| if (requests[i].result != transaction.is_request_valid(&sm.t_state, &sm.t_state.hdr_info.client_request)) { | |
| rprintf(t, "HttpTransact::is_request_valid - failed for request = '%s'. Expected result was %s request\n", requests[i].req, | |
| (requests[i].result ? "valid" : "invalid")); | |
| *pstatus = REGRESSION_TEST_FAILED; | |
| } | |
| if (requests[i].result != transaction.handle_trace_and_options_requests(&sm.t_state, &sm.t_state.hdr_info.client_request)) { | |
| rprintf(t, "HttpTransact::handle_trace_and_options - failed for request = '%s'. Expected result was %s request\n", | |
| requests[i].req, (requests[i].result ? "true" : "false")); | |
| *pstatus = REGRESSION_TEST_FAILED; | |
| } | |
| } | |
| } | |
| REGRESSION_TEST(HttpTransact_handle_request)(RegressionTest * /* t */, int /* level */, int *pstatus) | |
| { | |
| // To be added.. | |
| *pstatus = REGRESSION_TEST_PASSED; | |
| } |