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
19 changes: 10 additions & 9 deletions src/handler/static_file_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,10 @@ StaticFileHandler::StaticFileHandler(const std::string& path,
req_(req),
out_off_(0),
file_size_(0),
fd_(-1)
fd_(-1),
done_(false)

{
LOG(DEBUG) << "req_.path = " << req_.path;
struct ResolveResult r;
resolve_path(r);
if (r.kind == kNotFound) {
Expand All @@ -207,7 +207,7 @@ StaticFileHandler::StaticFileHandler(const std::string& path,
HttpResponse::kStatusOk, "text/html; charset=UTF-8", html, req_);

out_buf_ = res_.to_string();
fd_ = -1;
done_ = true;
return;
}

Expand Down Expand Up @@ -245,11 +245,16 @@ size_t StaticFileHandler::read_output(char* buf, size_t n)
}
}
if (fd_ == -1) // safeguard
{
done_ = true;
return copied;
}

ssize_t bytes = read(fd_, buf + copied, n - copied);
if (bytes == 0) {
close(fd_);
fd_ = -1;
done_ = true;
return copied;
}
if (bytes < 0) {
Expand All @@ -271,18 +276,14 @@ void StaticFileHandler::set_error(const HttpResponse::Status code)
{
res_ = HttpResponse::make_error(code, rc_.shared.error_pages, req_);
out_buf_ = res_.to_string();
if (fd_ != -1) {
close(fd_);
fd_ = -1;
}
done_ = true;
}

void StaticFileHandler::set_redirect(const HttpResponse::Status code,
const std::string& redirect_path)
{
res_ = HttpResponse::make_response_headers_only(code, "", 0, req_);
// LOG(DEBUG) << "redirect location = " << redirect_path;
res_.location = redirect_path;
out_buf_ = res_.to_string();
fd_ = -1;
done_ = true;
}
3 changes: 2 additions & 1 deletion src/handler/static_file_handler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class StaticFileHandler : public Handler {
virtual bool is_regular_file() const { return true; }
virtual bool has_output() const { return out_off_ < out_buf_.size() || fd_ != -1; }
virtual bool needs_input() const { return false; };
virtual bool is_done() const { return out_off_ >= out_buf_.size() && fd_ == -1; }
virtual bool is_done() const { return done_ && out_off_ >= out_buf_.size() && fd_ == -1; }

virtual int cgi_read_fd() const { return -1; };
virtual int cgi_write_fd() const { return -1; };
Expand All @@ -52,6 +52,7 @@ class StaticFileHandler : public Handler {
// other handler specifc variables
off_t file_size_;
int fd_;
bool done_;
};

#endif
99 changes: 99 additions & 0 deletions tests/static_file_handler_unittest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,102 @@ UTEST(StaticFileHandlerTest, SmallBuffer)
EXPECT_TRUE(str_contains(response, "<!DOCTYPE html>"
"<html><head><title>Example</title></head></html>\n"));
}

UTEST(StaticFileHandlerTest, is_done)
{
RouteConfig rc;
HttpRequest req;
StaticFileHandler test("www/example/index.html", rc, req);

char buf[1] = {0};
std::string response;

while (!test.is_done() && test.has_output()) {
test.read_output(buf, sizeof(buf));
response.append(buf, 1);
}

EXPECT_TRUE(str_contains(response, "HTTP/1.1 200 OK"));
EXPECT_TRUE(str_contains(response, "Content-Length: 64"));
EXPECT_TRUE(str_contains(response, "<!DOCTYPE html>"
"<html><head><title>Example</title></head></html>\n"));
}
UTEST(StaticFileHandlerTest, needs_input)
{
RouteConfig rc;
HttpRequest req;
StaticFileHandler test("www/example/index.html", rc, req);
EXPECT_FALSE(test.needs_input());
}

UTEST(StaticFileHandlerTest, dir_autoindex_off_with_index_file)
{
RouteConfig rc;
rc.shared.autoindex_enabled = false;
HttpRequest req;
StaticFileHandler test("www/example/", rc, req);

char buf[1] = {0};
std::string response;

while (!test.is_done() && test.has_output()) {
test.read_output(buf, sizeof(buf));
response.append(buf, 1);
}
// std::cout << response << std::endl;
EXPECT_TRUE(str_contains(response, "HTTP/1.1 200 OK"));
}

UTEST(StaticFileHandlerTest, dir_autoindex_off_no_index_file)
{
RouteConfig rc;
rc.shared.autoindex_enabled = false;
HttpRequest req;
StaticFileHandler test("www/example/bin/", rc, req);

char buf[1] = {0};
std::string response;

while (!test.is_done() && test.has_output()) {
test.read_output(buf, sizeof(buf));
response.append(buf, 1);
}
// std::cout << response << std::endl;
EXPECT_TRUE(str_contains(response, "HTTP/1.1 403 Forbidden"));
}

UTEST(StaticFileHandlerTest, dir_autoindex_on_no_index_file)
{
RouteConfig rc;
rc.shared.autoindex_enabled = true;
HttpRequest req;
StaticFileHandler test("www/example/bin/", rc, req);

char buf[1] = {0};
std::string response;

while (!test.is_done() && test.has_output()) {
test.read_output(buf, sizeof(buf));
response.append(buf, 1);
}
// std::cout << response << std::endl;
EXPECT_TRUE(str_contains(response, "HTTP/1.1 200 OK"));
}

UTEST(StaticFileHandlerTest, dir_autoindex_on_no_index_file_redirection)
{
RouteConfig rc;
rc.shared.autoindex_enabled = true;
HttpRequest req;
StaticFileHandler test("www/example/bin", rc, req);

char buf[1] = {0};
std::string response;

while (!test.is_done() && test.has_output()) {
test.read_output(buf, sizeof(buf));
response.append(buf, 1);
}
std::cout << response << std::endl;
EXPECT_TRUE(str_contains(response, "HTTP/1.1 301 Moved Permanently"));
}