diff --git a/http_examples.cpp b/http_examples.cpp index 6643479f..3f1b2741 100644 --- a/http_examples.cpp +++ b/http_examples.cpp @@ -84,51 +84,47 @@ int main() { server.default_resource["GET"]=[](HttpServer::Response& response, shared_ptr request) { boost::filesystem::path web_root_path("web"); if(!boost::filesystem::exists(web_root_path)) - cerr << "Could not find web root." << endl; + cerr << "Could not find web root." << endl; else { - auto path=web_root_path; - path+=request->path; - if(boost::filesystem::exists(path)) { - if(boost::filesystem::canonical(web_root_path)<=boost::filesystem::canonical(path)) { - if(boost::filesystem::is_directory(path)) - path+="/index.html"; - if(boost::filesystem::exists(path) && boost::filesystem::is_regular_file(path)) { - ifstream ifs; - ifs.open(path.string(), ifstream::in | ios::binary); - - if(ifs) { - ifs.seekg(0, ios::end); - size_t length=ifs.tellg(); - - ifs.seekg(0, ios::beg); + auto path=web_root_path; + path+=request->path; + if(boost::filesystem::exists(path)) { + if(boost::filesystem::canonical(web_root_path)<=boost::filesystem::canonical(path)) { + if(boost::filesystem::is_directory(path)) + path+="/index.html"; + if(boost::filesystem::exists(path) && boost::filesystem::is_regular_file(path)) { + ifstream ifs; + ifs.open(path.string(), ifstream::in | ios::binary); + + if(ifs) { + ifs.seekg(0, ios::end); + size_t length=ifs.tellg(); + + ifs.seekg(0, ios::beg); + + response << "HTTP/1.1 200 OK\r\nContent-Length: " << length << "\r\n\r\n"; + + //read and send 128 KB at a time + size_t buffer_size=131072; + vector buffer; + buffer.reserve(buffer_size); + size_t read_length; + try { + while((read_length=ifs.read(&buffer[0], buffer_size).gcount())>0) { + response.write(&buffer[0], read_length); + response.flush(); + } + } + catch(const exception &e) { + cerr << "Connection interrupted, closing file" << endl; + } - response << "HTTP/1.1 200 OK\r\nContent-Length: " << length << "\r\n\r\n"; - - //read and send 128 KB at a time if file-size>buffer_size - size_t buffer_size=131072; - if(length>buffer_size) { - vector buffer; - buffer.reserve(buffer_size); - size_t read_length; - try { - while((read_length=ifs.read(&buffer[0], buffer_size).gcount())>0) { - response.stream.write(&buffer[0], read_length); - response << HttpServer::flush; - } - } - catch(const exception &e) { - cerr << "Connection interrupted, closing file" << endl; - } - } - else - response << ifs.rdbuf(); - - ifs.close(); - return; + ifs.close(); + return; + } + } } - } } - } } string content="Could not open path "+request->path; response << "HTTP/1.1 400 Bad Request\r\nContent-Length: " << content.length() << "\r\n\r\n" << content; diff --git a/https_examples.cpp b/https_examples.cpp index 9aa82d52..69dd580b 100644 --- a/https_examples.cpp +++ b/https_examples.cpp @@ -84,51 +84,47 @@ int main() { server.default_resource["GET"]=[](HttpsServer::Response& response, shared_ptr request) { boost::filesystem::path web_root_path("web"); if(!boost::filesystem::exists(web_root_path)) - cerr << "Could not find web root." << endl; + cerr << "Could not find web root." << endl; else { - auto path=web_root_path; - path+=request->path; - if(boost::filesystem::exists(path)) { - if(boost::filesystem::canonical(web_root_path)<=boost::filesystem::canonical(path)) { - if(boost::filesystem::is_directory(path)) - path+="/index.html"; - if(boost::filesystem::exists(path) && boost::filesystem::is_regular_file(path)) { - ifstream ifs; - ifs.open(path.string(), ifstream::in | ios::binary); - - if(ifs) { - ifs.seekg(0, ios::end); - size_t length=ifs.tellg(); - - ifs.seekg(0, ios::beg); + auto path=web_root_path; + path+=request->path; + if(boost::filesystem::exists(path)) { + if(boost::filesystem::canonical(web_root_path)<=boost::filesystem::canonical(path)) { + if(boost::filesystem::is_directory(path)) + path+="/index.html"; + if(boost::filesystem::exists(path) && boost::filesystem::is_regular_file(path)) { + ifstream ifs; + ifs.open(path.string(), ifstream::in | ios::binary); + + if(ifs) { + ifs.seekg(0, ios::end); + size_t length=ifs.tellg(); + + ifs.seekg(0, ios::beg); + + response << "HTTP/1.1 200 OK\r\nContent-Length: " << length << "\r\n\r\n"; + + //read and send 128 KB at a time + size_t buffer_size=131072; + vector buffer; + buffer.reserve(buffer_size); + size_t read_length; + try { + while((read_length=ifs.read(&buffer[0], buffer_size).gcount())>0) { + response.write(&buffer[0], read_length); + response.flush(); + } + } + catch(const exception &e) { + cerr << "Connection interrupted, closing file" << endl; + } - response << "HTTP/1.1 200 OK\r\nContent-Length: " << length << "\r\n\r\n"; - - //read and send 128 KB at a time if file-size>buffer_size - size_t buffer_size=131072; - if(length>buffer_size) { - vector buffer; - buffer.reserve(buffer_size); - size_t read_length; - try { - while((read_length=ifs.read(&buffer[0], buffer_size).gcount())>0) { - response.stream.write(&buffer[0], read_length); - response << HttpsServer::flush; - } - } - catch(const exception &e) { - cerr << "Connection interrupted, closing file" << endl; - } - } - else - response << ifs.rdbuf(); - - ifs.close(); - return; + ifs.close(); + return; + } + } } - } } - } } string content="Could not open path "+request->path; response << "HTTP/1.1 400 Bad Request\r\nContent-Length: " << content.length() << "\r\n\r\n" << content; diff --git a/server_http.hpp b/server_http.hpp index 8a1d4afc..ac5f0a90 100644 --- a/server_http.hpp +++ b/server_http.hpp @@ -14,7 +14,7 @@ namespace SimpleWeb { template class ServerBase { public: - class Response { + class Response : public std::ostream { friend class ServerBase; private: boost::asio::yield_context& yield; @@ -24,8 +24,12 @@ namespace SimpleWeb { socket_type &socket; Response(boost::asio::io_service& io_service, socket_type &socket, boost::asio::yield_context& yield): - yield(yield), socket(socket), stream(&streambuf) {} - + std::ostream(&streambuf), yield(yield), socket(socket) {} + + public: + size_t size() { + return streambuf.size(); + } void flush() { boost::system::error_code ec; boost::asio::async_write(socket, streambuf, yield[ec]); @@ -33,28 +37,6 @@ namespace SimpleWeb { if(ec) throw std::runtime_error(ec.message()); } - - public: - std::ostream stream; - - size_t size() { - return streambuf.size(); - } - - template - Response& operator<<(const T& t) { - stream << t; - return *this; - } - - Response& operator<<(std::ostream& (*manip)(std::ostream&)) { - stream << manip; - return *this; - } - - Response& operator<<(Response& (*manip)(Response&)) { - return manip(*this); - } }; static Response& flush(Response& r) { @@ -307,11 +289,13 @@ namespace SimpleWeb { return; } - try { - response.flush(); - } - catch(const std::exception &e) { - return; + if(response.size()>0) { + try { + response.flush(); + } + catch(const std::exception &e) { + return; + } } if(timeout_content>0) timer->cancel();