Skip to content

Commit ea5786b

Browse files
author
Sebastiano Merlino
committed
Changed visibility of http_endpoint methods to avoid them to be called
by external applications. Avoided explicit usage of MHD constants in classes interface. Changed http_resource interface in order to avoid copy-constructor calls and improve performances. Changed answer_to_connection method in order to avoid multiple checking on methods and thus improve performances. Added a way to register personalized error pages.
1 parent 968e472 commit ea5786b

File tree

10 files changed

+553
-383
lines changed

10 files changed

+553
-383
lines changed

src/http_resource.cpp

Lines changed: 65 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -55,116 +55,123 @@ http_resource::~http_resource()
5555

5656
http_response http_resource::render(const http_request& r)
5757
{
58-
return this->render_404();
58+
return http_string_response("", http_utils::http_ok);
5959
}
6060

61-
http_response http_resource::render_404()
61+
void http_resource::render(const http_request& r, http_response** res)
6262
{
63-
return http_string_response(NOT_FOUND_ERROR, 404);
63+
route_request(r, res);
6464
}
6565

66-
http_response http_resource::render_405()
66+
http_response http_resource::route_request(const http_request& r)
6767
{
68-
return http_string_response(METHOD_ERROR, 405);
68+
string method;
69+
r.get_method(method);
70+
string_utilities::to_upper(method);
71+
if(method == MHD_HTTP_METHOD_GET)
72+
return this->render_GET(r);
73+
else if (method == MHD_HTTP_METHOD_POST)
74+
return this->render_POST(r);
75+
else if (method == MHD_HTTP_METHOD_PUT)
76+
return this->render_PUT(r);
77+
else if (method == MHD_HTTP_METHOD_DELETE)
78+
return this->render_DELETE(r);
79+
else if (method == MHD_HTTP_METHOD_HEAD)
80+
return this->render_HEAD(r);
81+
else if (method == MHD_HTTP_METHOD_TRACE)
82+
return this->render_TRACE(r);
83+
else if (method == MHD_HTTP_METHOD_OPTIONS)
84+
return this->render_OPTIONS(r);
85+
else if (method == MHD_HTTP_METHOD_CONNECT)
86+
return this->render_CONNECT(r);
87+
else
88+
return this->render(r);
6989
}
7090

71-
http_response http_resource::render_500()
91+
void http_resource::route_request(const http_request& r, http_response** res)
7292
{
73-
return http_string_response(GENERIC_ERROR, 500);
93+
http_response hr(this->route_request(r));
94+
clone_response(hr, res);
7495
}
7596

7697
http_response http_resource::render_GET(const http_request& r)
7798
{
7899
return this->render(r);
79100
}
80101

102+
void http_resource::render_GET(const http_request& r, http_response** res)
103+
{
104+
render(r, res);
105+
}
106+
81107
http_response http_resource::render_POST(const http_request& r)
82108
{
83109
return this->render(r);
84110
}
85111

112+
void http_resource::render_POST(const http_request& r, http_response** res)
113+
{
114+
render(r, res);
115+
}
116+
86117
http_response http_resource::render_PUT(const http_request& r)
87118
{
88119
return this->render(r);
89120
}
90121

122+
void http_resource::render_PUT(const http_request& r, http_response** res)
123+
{
124+
render(r, res);
125+
}
126+
91127
http_response http_resource::render_DELETE(const http_request& r)
92128
{
93129
return this->render(r);
94130
}
95131

132+
void http_resource::render_DELETE(const http_request& r, http_response** res)
133+
{
134+
render(r, res);
135+
}
136+
96137
http_response http_resource::render_HEAD(const http_request& r)
97138
{
98139
return this->render(r);
99140
}
100141

142+
void http_resource::render_HEAD(const http_request& r, http_response** res)
143+
{
144+
render(r, res);
145+
}
146+
101147
http_response http_resource::render_TRACE(const http_request& r)
102148
{
103149
return this->render(r);
104150
}
105151

152+
void http_resource::render_TRACE(const http_request& r, http_response** res)
153+
{
154+
render(r, res);
155+
}
156+
106157
http_response http_resource::render_OPTIONS(const http_request& r)
107158
{
108159
return this->render(r);
109160
}
110161

162+
void http_resource::render_OPTIONS(const http_request& r, http_response** res)
163+
{
164+
render(r, res);
165+
}
166+
111167
http_response http_resource::render_CONNECT(const http_request& r)
112168
{
113169
return this->render(r);
114170
}
115171

116-
http_response http_resource::route_request(const http_request& r)
172+
void http_resource::render_CONNECT(const http_request& r, http_response** res)
117173
{
118-
string method;
119-
r.get_method(method);
120-
string_utilities::to_upper(method);
121-
122-
http_response res;
123-
124-
if(this->is_allowed(method))
125-
{
126-
if(method == MHD_HTTP_METHOD_GET)
127-
{
128-
res = this->render_GET(r);
129-
}
130-
else if (method == MHD_HTTP_METHOD_POST)
131-
{
132-
res = this->render_POST(r);
133-
}
134-
else if (method == MHD_HTTP_METHOD_PUT)
135-
{
136-
res = this->render_PUT(r);
137-
}
138-
else if (method == MHD_HTTP_METHOD_DELETE)
139-
{
140-
res = this->render_DELETE(r);
141-
}
142-
else if (method == MHD_HTTP_METHOD_HEAD)
143-
{
144-
res = this->render_HEAD(r);
145-
}
146-
else if (method == MHD_HTTP_METHOD_TRACE)
147-
{
148-
res = this->render_TRACE(r);
149-
}
150-
else if (method == MHD_HTTP_METHOD_OPTIONS)
151-
{
152-
res = this->render_OPTIONS(r);
153-
}
154-
else if (method == MHD_HTTP_METHOD_CONNECT)
155-
{
156-
res = this->render_CONNECT(r);
157-
}
158-
else
159-
{
160-
res = this->render(r);
161-
}
162-
}
163-
else
164-
{
165-
res = this->render_405();
166-
}
167-
return res;
174+
render(r, res);
168175
}
169176

170177
};

src/http_response.cpp

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -34,22 +34,14 @@ const std::vector<std::pair<std::string, std::string> > http_response::get_heade
3434
std::vector<std::pair<std::string, std::string> > to_ret;
3535
std::map<std::string, std::string, header_comparator>::const_iterator it;
3636
for(it = headers.begin(); it != headers.end(); ++it)
37-
#ifdef USE_CPP_ZEROX
38-
to_ret.push_back(std::make_pair((*it).first,(*it).second));
39-
#else
40-
to_ret.push_back(std::make_pair<std::string, std::string>((*it).first,(*it).second));
41-
#endif
37+
to_ret.push_back(*it);
4238
return to_ret;
4339
}
4440
size_t http_response::get_headers(std::vector<std::pair<std::string, std::string> >& result)
4541
{
4642
std::map<std::string, std::string, header_comparator>::const_iterator it;
4743
for(it = headers.begin(); it != headers.end(); ++it)
48-
#ifdef USE_CPP_ZEROX
49-
result.push_back(std::make_pair((*it).first,(*it).second));
50-
#else
51-
result.push_back(std::make_pair<std::string, std::string>((*it).first,(*it).second));
52-
#endif
44+
result.push_back(*it);
5345
return result.size();
5446
}
5547
size_t http_response::get_headers(std::map<std::string, std::string, header_comparator>& result)
@@ -63,22 +55,14 @@ const std::vector<std::pair<std::string, std::string> > http_response::get_foote
6355
std::vector<std::pair<std::string, std::string> > to_ret;
6456
std::map<std::string, std::string, header_comparator>::const_iterator it;
6557
for(it = footers.begin(); it != footers.end(); ++it)
66-
#ifdef USE_CPP_ZEROX
67-
to_ret.push_back(std::make_pair((*it).first,(*it).second));
68-
#else
69-
to_ret.push_back(std::make_pair<std::string, std::string>((*it).first,(*it).second));
70-
#endif
58+
to_ret.push_back(*it);
7159
return to_ret;
7260
}
7361
size_t http_response::get_footers(std::vector<std::pair<std::string, std::string> >& result)
7462
{
7563
std::map<std::string, std::string, arg_comparator>::const_iterator it;
7664
for(it = footers.begin(); it != footers.end(); ++it)
77-
#ifdef USE_CPP_ZEROX
78-
result.push_back(std::make_pair((*it).first,(*it).second));
79-
#else
80-
result.push_back(std::make_pair<std::string, std::string>((*it).first,(*it).second));
81-
#endif
65+
result.push_back(*it);
8266
return result.size();
8367
}
8468
size_t http_response::get_footers(std::map<std::string, std::string, header_comparator>& result)
@@ -98,4 +82,45 @@ shoutCAST_response::shoutCAST_response
9882
{
9983
}
10084

85+
void http_response::get_raw_response(MHD_Response** response, bool* found)
86+
{
87+
size_t size = &(*content.end()) - &(*content.begin());
88+
*response = MHD_create_response_from_buffer(size, (void*) content.c_str(), MHD_RESPMEM_PERSISTENT);
89+
}
90+
91+
void http_file_response::get_raw_response(MHD_Response** response, bool* found)
92+
{
93+
char* page = NULL;
94+
size_t size = http::load_file(filename.c_str(), &page);
95+
if(size)
96+
*response = MHD_create_response_from_buffer(size, page, MHD_RESPMEM_MUST_FREE);
97+
else
98+
*found = false;
99+
}
100+
101+
void clone_response(const http_response& hr, http_response** dhrs)
102+
{
103+
switch(hr.response_type)
104+
{
105+
case(http_response::STRING_CONTENT):
106+
*dhrs = new http_string_response(hr);
107+
return;
108+
case(http_response::FILE_CONTENT):
109+
*dhrs = new http_file_response(hr);
110+
return;
111+
case(http_response::SHOUTCAST_CONTENT):
112+
*dhrs = new shoutCAST_response(hr);
113+
return;
114+
case(http_response::DIGEST_AUTH_FAIL):
115+
*dhrs = new http_digest_auth_fail_response(hr);
116+
return;
117+
case(http_response::BASIC_AUTH_FAIL):
118+
*dhrs = new http_basic_auth_fail_response(hr);
119+
return;
120+
case(http_response::SWITCH_PROTOCOL):
121+
*dhrs = new switch_protocol_response(hr);
122+
return;
123+
}
124+
}
125+
101126
};

src/http_utils.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <arpa/inet.h>
2525
#include <sstream>
2626
#include <iomanip>
27+
#include <fstream>
2728
#include "string_utilities.hpp"
2829
#include "http_utils.hpp"
2930

@@ -38,6 +39,7 @@ namespace httpserver {
3839
namespace http {
3940

4041
/* See also: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html */
42+
4143
const int http_utils::http_continue = MHD_HTTP_CONTINUE;
4244
const int http_utils::http_switching_protocol = MHD_HTTP_SWITCHING_PROTOCOLS;
4345
const int http_utils::http_processing = MHD_HTTP_PROCESSING;
@@ -423,6 +425,27 @@ bool ip_representation::operator <(const ip_representation& b) const
423425
return false;
424426
}
425427

428+
size_t load_file (const char* filename, char** content)
429+
{
430+
ifstream fp(filename, ios::in | ios::binary | ios::ate);
431+
if(fp.is_open())
432+
{
433+
int size = fp.tellg();
434+
*content = (char*) malloc(size * sizeof(char));
435+
fp.seekg(0, ios::beg);
436+
fp.read(*content, size);
437+
fp.close();
438+
return size;
439+
}
440+
return 0;
441+
}
442+
443+
char* load_file (const char *filename)
444+
{
445+
char* content = NULL;
446+
load_file(filename, &content);
447+
return content;
448+
}
426449

427450
};
428451
};

src/httpserver/http_endpoint.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class bad_http_endpoint : public std::exception
5555
**/
5656
class http_endpoint
5757
{
58-
public:
58+
private:
5959
/**
6060
* Copy constructor. It is useful expecially to copy regex_t structure that contains dinamically allocated data.
6161
* @param h The http_endpoint to copy
@@ -166,7 +166,6 @@ class http_endpoint
166166
result = this->chunk_positions;
167167
return result.size();
168168
}
169-
private:
170169
/**
171170
* Default constructor of the class.
172171
* @param family boolean that indicates if the endpoint is a family endpoint.
@@ -226,6 +225,8 @@ class http_endpoint
226225
**/
227226
bool reg_compiled;
228227
friend class webserver;
228+
template<typename, typename> friend struct std::pair;
229+
template<typename> friend struct std::less;
229230
};
230231

231232
};

0 commit comments

Comments
 (0)