Skip to content
This repository has been archived by the owner on Jun 12, 2018. It is now read-only.

Commit

Permalink
Response stream now subclass std::ostream. Also some cleanup of defau…
Browse files Browse the repository at this point in the history
…lt_resource example.
  • Loading branch information
eidheim committed Sep 6, 2015
1 parent 4bc5078 commit c58b7a7
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 112 deletions.
78 changes: 37 additions & 41 deletions http_examples.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,51 +84,47 @@ int main() {
server.default_resource["GET"]=[](HttpServer::Response& response, shared_ptr<HttpServer::Request> 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<char> 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<char> 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;
Expand Down
78 changes: 37 additions & 41 deletions https_examples.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,51 +84,47 @@ int main() {
server.default_resource["GET"]=[](HttpsServer::Response& response, shared_ptr<HttpsServer::Request> 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<char> 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<char> 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;
Expand Down
44 changes: 14 additions & 30 deletions server_http.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace SimpleWeb {
template <class socket_type>
class ServerBase {
public:
class Response {
class Response : public std::ostream {
friend class ServerBase<socket_type>;
private:
boost::asio::yield_context& yield;
Expand All @@ -24,37 +24,19 @@ 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]);

if(ec)
throw std::runtime_error(ec.message());
}

public:
std::ostream stream;

size_t size() {
return streambuf.size();
}

template <class T>
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) {
Expand Down Expand Up @@ -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();
Expand Down

0 comments on commit c58b7a7

Please sign in to comment.