123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- #include "file_service.h"
- SubTask *FileService::create_error_task(int code,
- struct FileService::ModuleCtx *ctx)
- {
- if (ctx->is_error_set == false)
- {
- ctx->resp->set_status_code(std::to_string(code));
- ctx->is_error_set = true;
- const auto it = this->error_page.find(code);
- if (it != this->error_page.end())
- return this->create_file_task(it->second, ctx);
- }
- return WFTaskFactory::create_empty_task();
- }
- void FileService::pread_callback(WFFileIOTask *task)
- {
- FileIOArgs *args = task->get_args();
- long ret = task->get_retval();
- struct ModuleCtx *ctx = (struct ModuleCtx *)series_of(task)->get_context();
- protocol::HttpResponse *resp = ctx->resp;
- if (task->get_state() == WFT_STATE_SUCCESS)
- {
- resp->append_output_body_nocopy(args->buf, ret);
- }
- else
- {
- auto *error_task = this->create_error_task(503, ctx);
- series_of(task)->push_back(error_task);
- }
- }
- SubTask *FileService::create_file_task(const std::string& path,
- struct FileService::ModuleCtx *ctx)
- {
- SubTask *task;
- struct stat st;
- std::string abs_path = this->root + path;
- if (abs_path.back() == '/')
- abs_path += "index.html";
- if (stat(abs_path.c_str(), &st) >= 0)
- {
- size_t size = st.st_size;
- void *buf = malloc(size);
- if (buf)
- {
- ctx->buf = buf;
- auto&& cb = std::bind(&FileService::pread_callback,
- this, std::placeholders::_1);
- task = WFTaskFactory::create_pread_task(abs_path, buf, size, 0, cb);
- }
- else
- {
- task = this->create_error_task(503, ctx);
- }
- }
- else
- {
- task = this->create_error_task(404, ctx);
- }
- return task;
- }
- WFModuleTask *FileService::create_module(WFHttpTask *server_task,
- const std::string& path)
- {
- fprintf(stderr, "file service get request: %s\n", path.c_str());
- struct ModuleCtx *ctx = new ModuleCtx(server_task->get_resp());
- SubTask *next = this->create_file_task(path, ctx);
- WFModuleTask *module = WFTaskFactory::create_module_task(next,
- [server_task](const WFModuleTask *mod)
- {
- struct ModuleCtx *ctx;
- ctx = (struct ModuleCtx *)mod->sub_series()->get_context();
- void *buf = ctx->buf;
- server_task->set_callback([buf](WFHttpTask *t){ free(buf); });
- delete ctx;
- });
- module->sub_series()->set_context(ctx);
- return module;
- }
- void FileService::process(WFHttpTask *server_task)
- {
- protocol::HttpRequest *req = server_task->get_req();
- protocol::HttpResponse *resp = server_task->get_resp();
- std::string path = req->get_request_uri();
- auto pos = path.find_first_of('?');
- if (pos != std::string::npos)
- path = path.substr(0, pos);
- resp->add_header_pair("Server", "SRPC HTTP File Server");
- WFModuleTask *module = this->create_module(server_task, path);
- series_of(server_task)->push_back(module);
- }
|