/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, ¶ms); |
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(¶ms); |
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 |