Coverage Report

Created: 2024-11-22 12:31

/root/doris/be/src/http/http_request.cpp
Line
Count
Source (jump to first uncovered line)
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#include "http/http_request.h"
19
20
#include <event2/buffer.h>
21
#include <event2/http.h>
22
#include <event2/http_struct.h>
23
#include <event2/keyvalq_struct.h>
24
25
#include <sstream>
26
#include <string>
27
#include <unordered_map>
28
#include <utility>
29
30
#include "http/http_handler.h"
31
32
namespace doris {
33
34
static std::string s_empty = "";
35
36
59
HttpRequest::HttpRequest(evhttp_request* evhttp_request) : _ev_req(evhttp_request) {}
37
38
59
HttpRequest::~HttpRequest() {
39
59
    if (_handler_ctx != nullptr) {
40
0
        DCHECK(_handler != nullptr);
41
0
        _handler->free_handler_ctx(_handler_ctx);
42
0
    }
43
59
}
44
45
50
int HttpRequest::init_from_evhttp() {
46
50
    _method = to_http_method(evhttp_request_get_command(_ev_req));
47
50
    if (_method == HttpMethod::UNKNOWN) {
48
0
        LOG(WARNING) << "unknown method of HTTP request, method="
49
0
                     << evhttp_request_get_command(_ev_req);
50
0
        return -1;
51
0
    }
52
50
    _uri = evhttp_request_get_uri(_ev_req);
53
    // conver header
54
50
    auto headers = evhttp_request_get_input_headers(_ev_req);
55
194
    for (auto header = headers->tqh_first; header != nullptr; header = header->next.tqe_next) {
56
144
        _headers.emplace(header->key, header->value);
57
144
    }
58
    // parse
59
50
    auto ev_uri = evhttp_request_get_evhttp_uri(_ev_req);
60
50
    _raw_path = evhttp_uri_get_path(ev_uri);
61
50
    auto query = evhttp_uri_get_query(ev_uri);
62
50
    if (query == nullptr || *query == '\0') {
63
45
        return 0;
64
45
    }
65
5
    struct evkeyvalq params;
66
5
    auto res = evhttp_parse_query_str(query, &params);
67
5
    if (res < 0) {
68
0
        LOG(WARNING) << "parse query str failed, query=" << query;
69
0
        return res;
70
0
    }
71
14
    for (auto param = params.tqh_first; param != nullptr; param = param->next.tqe_next) {
72
9
        _query_params.emplace(param->key, param->value);
73
9
    }
74
5
    _params.insert(_query_params.begin(), _query_params.end());
75
5
    evhttp_clear_headers(&params);
76
5
    return 0;
77
5
}
78
79
21
std::string HttpRequest::debug_string() const {
80
21
    std::stringstream ss;
81
21
    ss << "HttpRequest: \n"
82
21
       << "method:" << _method << "\n"
83
21
       << "uri:" << _uri << "\n"
84
21
       << "raw_path:" << _raw_path << "\n"
85
21
       << "headers: \n";
86
56
    for (auto& iter : _headers) {
87
56
        ss << "key=" << iter.first << ", value=" << iter.second << "\n";
88
56
    }
89
21
    ss << "params: \n";
90
21
    for (auto& iter : _params) {
91
18
        ss << "key=" << iter.first << ", value=" << iter.second << "\n";
92
18
    }
93
94
21
    return ss.str();
95
21
}
96
97
149
const std::string& HttpRequest::header(const std::string& key) const {
98
149
    auto iter = _headers.find(key);
99
149
    if (iter == _headers.end()) {
100
120
        return s_empty;
101
120
    }
102
29
    return iter->second;
103
149
}
104
105
32
const std::string& HttpRequest::param(const std::string& key) const {
106
32
    auto iter = _params.find(key);
107
32
    if (iter == _params.end()) {
108
21
        return s_empty;
109
21
    }
110
11
    return iter->second;
111
32
}
112
113
18
void HttpRequest::add_output_header(const char* key, const char* value) {
114
18
    evhttp_add_header(evhttp_request_get_output_headers(_ev_req), key, value);
115
18
}
116
117
1
std::string HttpRequest::get_request_body() {
118
1
    if (!_request_body.empty()) {
119
0
        return _request_body;
120
0
    }
121
    // read buf
122
1
    auto evbuf = evhttp_request_get_input_buffer(_ev_req);
123
1
    if (evbuf == nullptr) {
124
0
        return _request_body;
125
0
    }
126
1
    auto length = evbuffer_get_length(evbuf);
127
1
    _request_body.resize(length);
128
1
    evbuffer_remove(evbuf, (char*)_request_body.data(), length);
129
1
    return _request_body;
130
1
}
131
132
32
const char* HttpRequest::remote_host() const {
133
32
    return _ev_req->remote_host;
134
32
}
135
136
} // namespace doris