Skip to content

Commit 79fdcc3

Browse files
authored
Merge pull request #121 from asciphx/master
support: windows
2 parents 2522588 + 28fa9f0 commit 79fdcc3

File tree

3 files changed

+44
-18
lines changed

3 files changed

+44
-18
lines changed

libraries/http_server/http_server/http_ctx.hh

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -361,33 +361,47 @@ template <typename FIBER> struct generic_http_ctx {
361361
close(fd);
362362

363363
#else // Windows impl with basic read write.
364+
size_t ext_pos = std::string_view(path).rfind('.');
365+
std::string_view content_type;
366+
if (ext_pos != std::string::npos) {
367+
auto type_itr = content_types.find(std::string_view(path).substr(ext_pos + 1).data());
368+
if (type_itr != content_types.end()) {
369+
content_type = type_itr->second; set_header("Content-Type", content_type);
370+
set_header("Cache-Control", "max-age=54000,immutable");
371+
}
372+
}
364373

365374
// Open file.
366-
FILE* fd = fopen(path, "r");
367-
if (fd == nullptr)
368-
throw http_error::not_found("File not found.");
375+
FILE* fd;
376+
if( (fd = fopen(path, "r" )) == NULL ) // C4996
377+
throw http_error::not_found("File not found.");
378+
fseek(fd, 0L, SEEK_END);
369379

370380
// Get file size.
371-
DWORD file_size = 0;
372-
GetFileSize(fd, &file_size);
381+
long file_size = ftell(fd);
373382
// Writing the http headers.
374383
response_written_ = true;
375384
format_top_headers(output_stream);
376385
headers_stream.flush(); // flushes to output_stream.
377386
output_stream << "Content-Length: " << file_size << "\r\n\r\n"; // Add body
378387
output_stream.flush();
379388

389+
rewind(fd);
380390
// Read the file and write it to the socket.
381391
size_t nread = 1;
382392
size_t offset = 0;
383393
while (nread != 0) {
384394
char buffer[4096];
385-
nread = _fread_nolock(buffer, sizeof(buffer), file_size - offset, fd);
386-
offset += nread;
387-
this->fiber.write(buffer, nread);
395+
nread = _fread_nolock(buffer, sizeof(buffer), 1, fd);
396+
offset += sizeof(buffer);
397+
this->fiber.write(buffer, sizeof(buffer));
388398
}
389-
if (!feof(fd))
390-
throw http_error::not_found("Internal error: Could not reach the end of file.");
399+
char buffer[4096];
400+
nread = _fread_nolock(buffer, file_size - offset, 1, fd);
401+
this->fiber.write(buffer, file_size - offset);
402+
fclose(fd);
403+
// if (!feof(fd))
404+
// throw http_error::not_found("Internal error: Could not reach the end of file.");
391405

392406
#endif
393407
}

libraries/http_server/http_server/serve_directory.hh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ inline auto serve_file(const std::string& root, std::string_view path, http_resp
5252
if (!path.empty() && path[0] == slash) {
5353
path = std::string_view(path.data() + 1, path.size() - 1); // erase(0, 1);
5454
}
55+
if (path[0] == ' ') path = "index.html";
5556

5657
// Directory listing not supported.
5758
std::string full_path(root + std::string(path));
@@ -87,9 +88,15 @@ inline auto serve_directory(const std::string& root) {
8788

8889
// Ensure the root ends with a /
8990
std::string real_root(realpath_out);
91+
#if _WIN32
92+
if (real_root.back() != '\\') {
93+
real_root.push_back('\\');
94+
}
95+
#else
9096
if (real_root.back() != '/') {
9197
real_root.push_back('/');
9298
}
99+
#endif
93100

94101
http_api api;
95102
api.get("/{{path...}}") = [real_root](http_request& request, http_response& response) {

libraries/http_server/http_server/tcp_server.hh

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ struct async_reactor {
285285

286286
#if defined _WIN32
287287
typedef HANDLE epoll_handle_t;
288+
u_long iMode = 0;
288289
#else
289290
typedef int epoll_handle_t;
290291
#endif
@@ -445,8 +446,9 @@ struct async_reactor {
445446
}
446447
// Handle new connections.
447448
else if (listen_fd == event_fd) {
449+
#ifndef _WIN32
448450
while (true) {
449-
451+
#endif
450452
// ============================================
451453
// ACCEPT INCOMMING CONNECTION
452454
sockaddr_storage in_addr_storage;
@@ -466,6 +468,13 @@ struct async_reactor {
466468
}
467469
// ============================================
468470

471+
// ============================================
472+
// Subscribe epoll to the socket file descriptor.
473+
#if _WIN32
474+
if (ioctlsocket(socket_fd, FIONBIO, &iMode) != NO_ERROR) continue;
475+
#else
476+
if (-1 == ::fcntl(socket_fd, F_SETFL, fcntl(socket_fd, F_GETFL, 0) | O_NONBLOCK)) continue;
477+
#endif
469478
// ============================================
470479
// Find a free fiber for this new connection.
471480
int fiber_idx = 0;
@@ -475,12 +484,6 @@ struct async_reactor {
475484
fibers.resize((fibers.size() + 1) * 2);
476485
assert(fiber_idx < fibers.size());
477486
// ============================================
478-
479-
// ============================================
480-
// Subscribe epoll to the socket file descriptor.
481-
// FIXME Duplicate ??
482-
// if (-1 == fcntl(socket_fd, F_SETFL, fcntl(socket_fd, F_GETFL, 0) | O_NONBLOCK))
483-
// continue;
484487
#if __linux__
485488
this->epoll_add(socket_fd, EPOLLIN | EPOLLOUT | EPOLLRDHUP | EPOLLET, fiber_idx);
486489
#elif _WIN32
@@ -528,7 +531,9 @@ struct async_reactor {
528531
return std::move(ctx.sink);
529532
});
530533
// =============================================
531-
}
534+
#ifndef _WIN32
535+
}
536+
#endif
532537
} else // Data available on existing sockets. Wake up the fiber associated with
533538
// event_fd.
534539
{

0 commit comments

Comments
 (0)