| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- #include "HttpHandler.h"
- #include "hbase.h"
- #include "http_page.h"
- int HttpHandler::HandleHttpRequest() {
- // preprocessor -> api -> web -> postprocessor
- int ret = 0;
- http_api_handler api = NULL;
- req.ParseUrl();
- req.client_addr.ip = ip;
- req.client_addr.port = port;
- preprocessor:
- if (service->preprocessor) {
- ret = service->preprocessor(&req, &res);
- if (ret != 0) {
- goto make_http_status_page;
- }
- }
- if (service->api_handlers.size() != 0) {
- service->GetApi(&req, &api);
- }
- if (api) {
- // api service
- ret = api(&req, &res);
- if (ret != 0) {
- goto make_http_status_page;
- }
- }
- else if (service->document_root.size() != 0 &&
- (req.method == HTTP_GET || req.method == HTTP_HEAD)) {
- // web service
- // path safe check
- const char* req_path = req.path.c_str();
- if (*req_path != '/' || strstr(req_path, "/../")) {
- res.status_code = HTTP_STATUS_BAD_REQUEST;
- goto make_http_status_page;
- }
- std::string filepath = service->document_root;
- filepath += req_path;
- if (req_path[1] == '\0') {
- filepath += service->home_page;
- }
- bool is_dir = filepath.c_str()[filepath.size()-1] == '/';
- bool is_index_of = false;
- if (service->index_of.size() != 0 && strstartswith(req_path, service->index_of.c_str())) {
- is_index_of = true;
- }
- if (!is_dir || is_index_of) {
- bool need_read = req.method == HTTP_HEAD ? false : true;
- fc = files->Open(filepath.c_str(), need_read, (void*)req_path);
- }
- if (fc == NULL) {
- // Not Found
- ret = HTTP_STATUS_NOT_FOUND;
- }
- else {
- // Not Modified
- auto iter = req.headers.find("if-not-match");
- if (iter != req.headers.end() &&
- strcmp(iter->second.c_str(), fc->etag) == 0) {
- ret = HTTP_STATUS_NOT_MODIFIED;
- fc = NULL;
- }
- else {
- iter = req.headers.find("if-modified-since");
- if (iter != req.headers.end() &&
- strcmp(iter->second.c_str(), fc->last_modified) == 0) {
- ret = HTTP_STATUS_NOT_MODIFIED;
- fc = NULL;
- }
- }
- }
- }
- else {
- // Not Implemented
- ret = HTTP_STATUS_NOT_IMPLEMENTED;
- }
- make_http_status_page:
- if (ret >= 100 && ret < 600) {
- res.status_code = (http_status)ret;
- }
- if (res.status_code >= 400 && res.body.size() == 0) {
- // error page
- if (service->error_page.size() != 0) {
- std::string filepath = service->document_root;
- filepath += '/';
- filepath += service->error_page;
- fc = files->Open(filepath.c_str(), true, NULL);
- }
- // status page
- if (fc == NULL && res.body.size() == 0) {
- res.content_type = TEXT_HTML;
- make_http_status_page(res.status_code, res.body);
- }
- }
- if (fc) {
- res.content_length = fc->filebuf.len;
- if (fc->content_type && *fc->content_type != '\0') {
- res.headers["Content-Type"] = fc->content_type;
- }
- res.headers["Last-Modified"] = fc->last_modified;
- res.headers["Etag"] = fc->etag;
- if (req.method == HTTP_HEAD) {
- res.headers["Accept-Ranges"] = "bytes";
- res.content = NULL;
- fc = NULL;
- } else {
- res.content = fc->filebuf.base;
- }
- }
- postprocessor:
- if (service->postprocessor) {
- ret = service->postprocessor(&req, &res);
- }
- return ret;
- }
|