Fixed close problem win _open_oshandle on Windows.

This commit is contained in:
yhirose 2015-01-27 16:45:11 -05:00
parent efc579b14e
commit 79bb0be0ca

View File

@ -110,7 +110,7 @@ public:
private: private:
typedef std::vector<std::pair<std::regex, Handler>> Handlers; typedef std::vector<std::pair<std::regex, Handler>> Handlers;
void process_request(socket_t sock); void process_request(FILE* fp_read, FILE* fp_write);
bool read_request_line(FILE* fp, Request& req); bool read_request_line(FILE* fp, Request& req);
bool routing(Request& req, Response& res); bool routing(Request& req, Response& res);
bool handle_file_request(Request& req, Response& res); bool handle_file_request(Request& req, Response& res);
@ -164,16 +164,30 @@ void split(const char* b, const char* e, char d, Fn fn)
} }
} }
inline void get_flie_pointers(int fd, FILE*& fp_read, FILE*& fp_write) template <typename T>
inline bool read_and_close_socket(socket_t sock, T callback)
{ {
FILE* fp_read;
FILE* fp_write;
#ifdef _MSC_VER #ifdef _MSC_VER
int osfhandle = _open_osfhandle(fd, _O_RDONLY); int osfhandle = _open_osfhandle(sock, _O_RDONLY);
fp_read = _fdopen(osfhandle, "rb"); fp_read = _fdopen(osfhandle, "rb");
fp_write = _fdopen(osfhandle, "wb"); fp_write = _fdopen(osfhandle, "wb");
#else #else
fp_read = fdopen(fd, "rb"); fp_read = fdopen(sock, "rb");
fp_write = fdopen(fd, "wb"); fp_write = fdopen(sock, "wb");
#endif #endif
auto ret = callback(fp_read, fp_write);
#ifdef _MSC_VER
sock = osfhandle;
#else
fclose(fp_read);
fclose(fp_write);
#endif
return ret;
} }
inline int shutdown_socket(socket_t sock) inline int shutdown_socket(socket_t sock)
@ -694,9 +708,10 @@ inline bool Server::listen(const char* host, int port)
} }
// TODO: should be async // TODO: should be async
process_request(sock); detail::read_and_close_socket(sock, [this](FILE* fp_read, FILE* fp_write) {
detail::shutdown_socket(sock); process_request(fp_read, fp_write);
detail::close_socket(sock); return true;
});
} }
return ret; return ret;
@ -786,12 +801,8 @@ inline bool Server::dispatch_request(Request& req, Response& res, Handlers& hand
return false; return false;
} }
inline void Server::process_request(socket_t sock) inline void Server::process_request(FILE* fp_read, FILE* fp_write)
{ {
FILE* fp_read;
FILE* fp_write;
detail::get_flie_pointers(sock, fp_read, fp_write);
Request req; Request req;
Response res; Response res;
@ -825,10 +836,6 @@ inline void Server::process_request(socket_t sock)
detail::write_response(fp_write, req, res); detail::write_response(fp_write, req, res);
fflush(fp_write); fflush(fp_write);
// NOTE: The following code causes problem on Windows...
//fclose(fp_read);
//fclose(fp_write);
if (logger_) { if (logger_) {
logger_(req, res); logger_(req, res);
} }
@ -866,33 +873,24 @@ inline bool Client::send(const Request& req, Response& res)
return false; return false;
} }
FILE* fp_read; return detail::read_and_close_socket(sock, [&](FILE* fp_read, FILE* fp_write) {
FILE* fp_write; // Send request
detail::get_flie_pointers(sock, fp_read, fp_write); detail::write_request(fp_write, req);
fflush(fp_write);
// Send request // Receive response
detail::write_request(fp_write, req); if (!read_response_line(fp_read, res) ||
fflush(fp_write); !detail::read_headers(fp_read, res.headers)) {
return false;
}
if (req.method != "HEAD") {
if (!detail::read_content(res, fp_read)) {
return false;
}
}
// Receive response return true;
if (!read_response_line(fp_read, res) || });
!detail::read_headers(fp_read, res.headers)) {
return false;
}
if (req.method != "HEAD") {
if (!detail::read_content(res, fp_read)) {
return false;
}
}
// NOTE: The following code causes problem on Windows...
//fclose(fp_read);
//fclose(fp_write);
detail::shutdown_socket(sock);
detail::close_socket(sock);
return true;
} }
inline std::shared_ptr<Response> Client::get(const char* url) inline std::shared_ptr<Response> Client::get(const char* url)