140 lines
4.2 KiB
C++
140 lines
4.2 KiB
C++
// 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 "http/http_request.h"
|
|
|
|
#include <event2/buffer.h>
|
|
#include <event2/bufferevent.h>
|
|
#include <event2/http.h>
|
|
#include <event2/http_struct.h>
|
|
#include <event2/keyvalq_struct.h>
|
|
|
|
#include <boost/algorithm/string.hpp>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "common/logging.h"
|
|
#include "http/http_handler.h"
|
|
#include "util/url_coding.h"
|
|
|
|
namespace doris {
|
|
|
|
static std::string s_empty = "";
|
|
|
|
HttpRequest::HttpRequest(evhttp_request* evhttp_request) : _ev_req(evhttp_request) {}
|
|
|
|
HttpRequest::~HttpRequest() {
|
|
if (_handler_ctx != nullptr) {
|
|
DCHECK(_handler != nullptr);
|
|
_handler->free_handler_ctx(_handler_ctx);
|
|
}
|
|
}
|
|
|
|
int HttpRequest::init_from_evhttp() {
|
|
_method = to_http_method(evhttp_request_get_command(_ev_req));
|
|
if (_method == HttpMethod::UNKNOWN) {
|
|
LOG(WARNING) << "unknown method of HTTP request, method="
|
|
<< evhttp_request_get_command(_ev_req);
|
|
return -1;
|
|
}
|
|
_uri = evhttp_request_get_uri(_ev_req);
|
|
// conver header
|
|
auto headers = evhttp_request_get_input_headers(_ev_req);
|
|
for (auto header = headers->tqh_first; header != nullptr; header = header->next.tqe_next) {
|
|
_headers.emplace(header->key, header->value);
|
|
}
|
|
// parse
|
|
auto ev_uri = evhttp_request_get_evhttp_uri(_ev_req);
|
|
_raw_path = evhttp_uri_get_path(ev_uri);
|
|
auto query = evhttp_uri_get_query(ev_uri);
|
|
if (query == nullptr || *query == '\0') {
|
|
return 0;
|
|
}
|
|
struct evkeyvalq params;
|
|
auto res = evhttp_parse_query_str(query, ¶ms);
|
|
if (res < 0) {
|
|
LOG(WARNING) << "parse query str failed, query=" << query;
|
|
return res;
|
|
}
|
|
for (auto param = params.tqh_first; param != nullptr; param = param->next.tqe_next) {
|
|
_query_params.emplace(param->key, param->value);
|
|
}
|
|
_params.insert(_query_params.begin(), _query_params.end());
|
|
evhttp_clear_headers(¶ms);
|
|
return 0;
|
|
}
|
|
|
|
std::string HttpRequest::debug_string() const {
|
|
std::stringstream ss;
|
|
ss << "HttpRequest: \n"
|
|
<< "method:" << _method << "\n"
|
|
<< "uri:" << _uri << "\n"
|
|
<< "raw_path:" << _raw_path << "\n"
|
|
<< "headers: \n";
|
|
for (auto& iter : _headers) {
|
|
ss << "key=" << iter.first << ", value=" << iter.second << "\n";
|
|
}
|
|
ss << "params: \n";
|
|
for (auto& iter : _params) {
|
|
ss << "key=" << iter.first << ", value=" << iter.second << "\n";
|
|
}
|
|
|
|
return ss.str();
|
|
}
|
|
|
|
const std::string& HttpRequest::header(const std::string& key) const {
|
|
auto iter = _headers.find(key);
|
|
if (iter == _headers.end()) {
|
|
return s_empty;
|
|
}
|
|
return iter->second;
|
|
}
|
|
|
|
const std::string& HttpRequest::param(const std::string& key) const {
|
|
auto iter = _params.find(key);
|
|
if (iter == _params.end()) {
|
|
return s_empty;
|
|
}
|
|
return iter->second;
|
|
}
|
|
|
|
void HttpRequest::add_output_header(const char* key, const char* value) {
|
|
evhttp_add_header(evhttp_request_get_output_headers(_ev_req), key, value);
|
|
}
|
|
|
|
std::string HttpRequest::get_request_body() {
|
|
if (!_request_body.empty()) {
|
|
return _request_body;
|
|
}
|
|
// read buf
|
|
auto evbuf = evhttp_request_get_input_buffer(_ev_req);
|
|
if (evbuf == nullptr) {
|
|
return _request_body;
|
|
}
|
|
auto length = evbuffer_get_length(evbuf);
|
|
_request_body.resize(length);
|
|
evbuffer_remove(evbuf, (char*)_request_body.data(), length);
|
|
return _request_body;
|
|
}
|
|
|
|
const char* HttpRequest::remote_host() const {
|
|
return _ev_req->remote_host;
|
|
}
|
|
|
|
} // namespace doris
|