Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion be/src/common/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,6 @@ namespace config {

// Whether to continue to start be when load tablet from header failed.
CONF_Bool(ignore_load_tablet_failure, "false");

} // namespace config

} // namespace doris
Expand Down
8 changes: 4 additions & 4 deletions be/src/http/default_path_handlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,10 @@ void mem_usage_handler(MemTracker* mem_tracker, const WebPageHandler::ArgumentMa
}

void add_default_path_handlers(WebPageHandler* web_page_handler, MemTracker* process_mem_tracker) {
web_page_handler->register_page("/logs", logs_handler);
web_page_handler->register_page("/varz", config_handler);
web_page_handler->register_page(
"/memz", boost::bind<void>(&mem_usage_handler, process_mem_tracker, _1, _2));
web_page_handler->register_page("/logs", "Logs", logs_handler, true /* is_on_nav_bar */);
web_page_handler->register_page("/varz", "Configs", config_handler, true /* is_on_nav_bar */);
web_page_handler->register_page("/memz", "Memory",
boost::bind<void>(&mem_usage_handler, process_mem_tracker, _1, _2), true /* is_on_nav_bar */);
}

} // namespace doris
81 changes: 1 addition & 80 deletions be/src/http/download_action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
#include "http/download_action.h"

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include <string>
Expand All @@ -32,6 +30,7 @@
#include "http/http_request.h"
#include "http/http_response.h"
#include "http/http_status.h"
#include "http/utils.h"
#include "runtime/exec_env.h"
#include "util/file_utils.h"
#include "util/filesystem_util.h"
Expand Down Expand Up @@ -134,84 +133,6 @@ void DownloadAction::handle(HttpRequest *req) {
LOG(INFO) << "deal with download requesst finished! ";
}

void DownloadAction::do_dir_response(
const std::string& dir_path, HttpRequest *req) {
std::vector<std::string> files;
Status status = FileUtils::list_files(Env::Default(), dir_path, &files);
if (!status.ok()) {
LOG(WARNING) << "Failed to scan dir. dir=" << dir_path;
HttpChannel::send_error(req, HttpStatus::INTERNAL_SERVER_ERROR);
}

const std::string FILE_DELIMETER_IN_DIR_RESPONSE = "\n";

std::stringstream result;
for (const std::string& file_name : files) {
result << file_name << FILE_DELIMETER_IN_DIR_RESPONSE;
}

std::string result_str = result.str();
HttpChannel::send_reply(req, result_str);
return;
}

void DownloadAction::do_file_response(const std::string& file_path, HttpRequest *req) {
// read file content and send response
int fd = open(file_path.c_str(), O_RDONLY);
if (fd < 0) {
LOG(WARNING) << "Failed to open file: " << file_path;
HttpChannel::send_error(req, HttpStatus::NOT_FOUND);
return;
}
struct stat st;
auto res = fstat(fd, &st);
if (res < 0) {
close(fd);
LOG(WARNING) << "Failed to open file: " << file_path;
HttpChannel::send_error(req, HttpStatus::NOT_FOUND);
return;
}

int64_t file_size = st.st_size;

// TODO(lingbin): process "IF_MODIFIED_SINCE" header
// TODO(lingbin): process "RANGE" header
const std::string& range_header = req->header(HttpHeaders::RANGE);
if (!range_header.empty()) {
// analyse range header
}

req->add_output_header(HttpHeaders::CONTENT_TYPE, get_content_type(file_path).c_str());

if (req->method() == HttpMethod::HEAD) {
close(fd);
req->add_output_header(HttpHeaders::CONTENT_LENGTH, std::to_string(file_size).c_str());
HttpChannel::send_reply(req);
return;
}

HttpChannel::send_file(req, fd, 0, file_size);
}

// Do a simple decision, only deal a few type
std::string DownloadAction::get_content_type(const std::string& file_name) {
std::string file_ext = path_util::file_extension(file_name);
LOG(INFO) << "file_name: " << file_name << "; file extension: [" << file_ext << "]";
if (file_ext == std::string(".html")
|| file_ext == std::string(".htm")) {
return std::string("text/html; charset=utf-8");
} else if (file_ext == std::string(".js")) {
return std::string("application/javascript; charset=utf-8");
} else if (file_ext == std::string(".css")) {
return std::string("text/css; charset=utf-8");
} else if (file_ext == std::string(".txt")) {
return std::string("text/plain; charset=utf-8");
} else {
return "text/plain; charset=utf-8";
}
return "";
}

Status DownloadAction::check_token(HttpRequest *req) {
const std::string& token_str = req->param(TOKEN_PARAMETER);
if (token_str.empty()) {
Expand Down
17 changes: 1 addition & 16 deletions be/src/http/download_action.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,28 +54,13 @@ class DownloadAction : public HttpHandler {
Status check_log_path_is_allowed(const std::string& file_path);

void handle_normal(HttpRequest *req, const std::string& file_param);
void handle_error_log(
HttpRequest *req,
const std::string& file_param);

void do_file_response(const std::string& dir_path, HttpRequest *req);
void do_dir_response(const std::string& dir_path, HttpRequest *req);

Status get_file_content(
FILE* fp, char* buffer, int32_t buffer_size,
int32_t* readed_size, bool* eos);

int64_t get_file_size(FILE* fp);

std::string get_content_type(const std::string& file_name);
void handle_error_log(HttpRequest *req, const std::string& file_param);

ExecEnv* _exec_env;
DOWNLOAD_TYPE _download_type;

std::vector<std::string> _allow_paths;
std::string _error_log_root_dir;


}; // end class DownloadAction

} // end namespace doris
Expand Down
12 changes: 12 additions & 0 deletions be/src/http/ev_http_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,14 @@ bool EvHttpServer::register_handler(
return result;
}

void EvHttpServer::register_static_file_handler(HttpHandler* handler) {
DCHECK(handler != nullptr);
DCHECK(_static_file_handler == nullptr);
pthread_rwlock_wrlock(&_rw_lock);
_static_file_handler = handler;
pthread_rwlock_unlock(&_rw_lock);
}

int EvHttpServer::on_header(struct evhttp_request* ev_req) {
std::unique_ptr<HttpRequest> request(new HttpRequest(ev_req));
auto res = request->init_from_evhttp();
Expand Down Expand Up @@ -247,6 +255,10 @@ HttpHandler* EvHttpServer::_find_handler(HttpRequest* req) {
switch (req->method()) {
case GET:
_get_handlers.retrieve(path, &handler, req->params());
// Static file handler is a fallback handler
if (handler == nullptr) {
handler = _static_file_handler;
}
break;
case PUT:
_put_handlers.retrieve(path, &handler, req->params());
Expand Down
4 changes: 4 additions & 0 deletions be/src/http/ev_http_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ class EvHttpServer {
// register handler for an a path-method pair
bool register_handler(
const HttpMethod& method, const std::string& path, HttpHandler* handler);

void register_static_file_handler(HttpHandler* handler);

Status start();
void stop();
void join();
Expand Down Expand Up @@ -69,6 +72,7 @@ class EvHttpServer {
pthread_rwlock_t _rw_lock;

PathTrie<HttpHandler*> _get_handlers;
HttpHandler* _static_file_handler = nullptr;
PathTrie<HttpHandler*> _put_handlers;
PathTrie<HttpHandler*> _post_handlers;
PathTrie<HttpHandler*> _delete_handlers;
Expand Down
97 changes: 96 additions & 1 deletion be/src/http/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,21 @@
// specific language governing permissions and limitations
// under the License.

#include <http/utils.h>
#include "http/utils.h"

#include <fcntl.h>
#include <sys/stat.h>

#include "common/logging.h"
#include "common/status.h"
#include "common/utils.h"
#include "env/env.h"
#include "util/file_utils.h"
#include "http/http_common.h"
#include "http/http_channel.h"
#include "http/http_headers.h"
#include "http/http_request.h"
#include "util/path_util.h"
#include "util/url_coding.h"

namespace doris {
Expand Down Expand Up @@ -78,4 +86,91 @@ bool parse_basic_auth(const HttpRequest& req, AuthInfo* auth) {
return true;
}

// Do a simple decision, only deal a few type
std::string get_content_type(const std::string& file_name) {
std::string file_ext = path_util::file_extension(file_name);
LOG(INFO) << "file_name: " << file_name << "; file extension: [" << file_ext << "]";
if (file_ext == std::string(".html")
|| file_ext == std::string(".htm")) {
return std::string("text/html; charset=utf-8");
} else if (file_ext == std::string(".js")) {
return std::string("application/javascript; charset=utf-8");
} else if (file_ext == std::string(".css")) {
return std::string("text/css; charset=utf-8");
} else if (file_ext == std::string(".txt")) {
return std::string("text/plain; charset=utf-8");
} else if (file_ext == std::string(".png")) {
return std::string("image/png");
} else if (file_ext == std::string(".ico")) {
return std::string("image/x-icon");
} else {
return "text/plain; charset=utf-8";
}
return "";
}

void do_file_response(const std::string& file_path, HttpRequest *req) {
if (file_path.find("..") != std::string::npos) {
LOG(WARNING) << "Not allowed to read relative path: " << file_path;
HttpChannel::send_error(req, HttpStatus::FORBIDDEN);
return;
}

// read file content and send response
int fd = open(file_path.c_str(), O_RDONLY);
if (fd < 0) {
LOG(WARNING) << "Failed to open file: " << file_path;
HttpChannel::send_error(req, HttpStatus::NOT_FOUND);
return;
}
struct stat st;
auto res = fstat(fd, &st);
if (res < 0) {
close(fd);
LOG(WARNING) << "Failed to open file: " << file_path;
HttpChannel::send_error(req, HttpStatus::NOT_FOUND);
return;
}

int64_t file_size = st.st_size;

// TODO(lingbin): process "IF_MODIFIED_SINCE" header
// TODO(lingbin): process "RANGE" header
const std::string& range_header = req->header(HttpHeaders::RANGE);
if (!range_header.empty()) {
// analyse range header
}

req->add_output_header(HttpHeaders::CONTENT_TYPE, get_content_type(file_path).c_str());

if (req->method() == HttpMethod::HEAD) {
close(fd);
req->add_output_header(HttpHeaders::CONTENT_LENGTH, std::to_string(file_size).c_str());
HttpChannel::send_reply(req);
return;
}

HttpChannel::send_file(req, fd, 0, file_size);
}

void do_dir_response(const std::string& dir_path, HttpRequest *req) {
std::vector<std::string> files;
Status status = FileUtils::list_files(Env::Default(), dir_path, &files);
if (!status.ok()) {
LOG(WARNING) << "Failed to scan dir. dir=" << dir_path;
HttpChannel::send_error(req, HttpStatus::INTERNAL_SERVER_ERROR);
}

const std::string FILE_DELIMETER_IN_DIR_RESPONSE = "\n";

std::stringstream result;
for (const std::string& file_name : files) {
result << file_name << FILE_DELIMETER_IN_DIR_RESPONSE;
}

std::string result_str = result.str();
HttpChannel::send_reply(req, result_str);
return;
}

}
6 changes: 6 additions & 0 deletions be/src/http/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include "common/utils.h"
#include "http/http_common.h"
#include "http/http_request.h"

namespace doris {

Expand All @@ -34,4 +35,9 @@ bool parse_basic_auth(const HttpRequest& req, std::string* user, std::string* pa

bool parse_basic_auth(const HttpRequest& req, AuthInfo* auth);

void do_file_response(const std::string& dir_path, HttpRequest *req);

void do_dir_response(const std::string& dir_path, HttpRequest *req);

std::string get_content_type(const std::string& file_name);
}
Loading