mirror of https://github.com/kiwix/libkiwix.git
HEAD request is not rejected
libmicrohttpd handles HEAD requests by dropping the body of the response (if any). Hence letting a HEAD request through into the code that processes GET requests is safe. Also added server unit-tests related to the handling of HEAD requests.
This commit is contained in:
parent
381ff186cb
commit
3d08ef43f2
|
@ -301,7 +301,8 @@ int InternalServer::handlerCallback(struct MHD_Connection* connection,
|
||||||
}
|
}
|
||||||
/* Unexpected method */
|
/* Unexpected method */
|
||||||
if (request.get_method() != RequestMethod::GET
|
if (request.get_method() != RequestMethod::GET
|
||||||
&& request.get_method() != RequestMethod::POST) {
|
&& request.get_method() != RequestMethod::POST
|
||||||
|
&& request.get_method() != RequestMethod::HEAD) {
|
||||||
printf("Reject request because of unhandled request method.\n");
|
printf("Reject request because of unhandled request method.\n");
|
||||||
printf("----------------------\n");
|
printf("----------------------\n");
|
||||||
return MHD_NO;
|
return MHD_NO;
|
||||||
|
|
|
@ -6,10 +6,25 @@
|
||||||
|
|
||||||
#include "./httplib.h"
|
#include "./httplib.h"
|
||||||
|
|
||||||
|
template<class T1, class T2>
|
||||||
|
T1 concat(T1 a, const T2& b)
|
||||||
|
{
|
||||||
|
a.insert(a.end(), b.begin(), b.end());
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef httplib::Headers Headers;
|
||||||
|
|
||||||
|
Headers invariantHeaders(Headers headers)
|
||||||
|
{
|
||||||
|
headers.erase("Date");
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class ZimFileServer
|
class ZimFileServer
|
||||||
{
|
{
|
||||||
public: // types
|
public: // types
|
||||||
typedef httplib::Headers Headers;
|
|
||||||
typedef std::shared_ptr<httplib::Response> Response;
|
typedef std::shared_ptr<httplib::Response> Response;
|
||||||
|
|
||||||
public: // functions
|
public: // functions
|
||||||
|
@ -88,7 +103,9 @@ std::ostream& operator<<(std::ostream& out, const Resource& r)
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
Resource resources200Compressible[] = {
|
typedef std::vector<Resource> ResourceCollection;
|
||||||
|
|
||||||
|
const ResourceCollection resources200Compressible{
|
||||||
{ "/" },
|
{ "/" },
|
||||||
|
|
||||||
{ "/skin/jquery-ui/jquery-ui.structure.min.css" },
|
{ "/skin/jquery-ui/jquery-ui.structure.min.css" },
|
||||||
|
@ -110,7 +127,7 @@ Resource resources200Compressible[] = {
|
||||||
{ "/zimfile/A/Ray_Charles" },
|
{ "/zimfile/A/Ray_Charles" },
|
||||||
};
|
};
|
||||||
|
|
||||||
Resource resources200Uncompressible[] = {
|
const ResourceCollection resources200Uncompressible{
|
||||||
{ "/skin/jquery-ui/images/ui-bg_flat_0_aaaaaa_40x100.png" },
|
{ "/skin/jquery-ui/images/ui-bg_flat_0_aaaaaa_40x100.png" },
|
||||||
{ "/skin/jquery-ui/images/ui-bg_flat_75_ffffff_40x100.png" },
|
{ "/skin/jquery-ui/images/ui-bg_flat_75_ffffff_40x100.png" },
|
||||||
{ "/skin/jquery-ui/images/ui-icons_222222_256x240.png" },
|
{ "/skin/jquery-ui/images/ui-icons_222222_256x240.png" },
|
||||||
|
@ -144,13 +161,14 @@ Resource resources200Uncompressible[] = {
|
||||||
{ "/zimfile/I/m/Ray_Charles_classic_piano_pose.jpg" },
|
{ "/zimfile/I/m/Ray_Charles_classic_piano_pose.jpg" },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ResourceCollection all200Resources()
|
||||||
|
{
|
||||||
|
return concat(resources200Compressible, resources200Uncompressible);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ServerTest, 200)
|
TEST_F(ServerTest, 200)
|
||||||
{
|
{
|
||||||
for ( const Resource& res : resources200Compressible )
|
for ( const Resource& res : all200Resources() )
|
||||||
EXPECT_EQ(200, zfs1_->GET(res.url)->status) << "res.url: " << res.url;
|
|
||||||
|
|
||||||
for ( const Resource& res : resources200Uncompressible )
|
|
||||||
EXPECT_EQ(200, zfs1_->GET(res.url)->status) << "res.url: " << res.url;
|
EXPECT_EQ(200, zfs1_->GET(res.url)->status) << "res.url: " << res.url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,3 +239,24 @@ TEST_F(ServerTest, BookMainPageIsRedirectedToArticleIndex)
|
||||||
ASSERT_TRUE(g->has_header("Location"));
|
ASSERT_TRUE(g->has_header("Location"));
|
||||||
ASSERT_EQ("/zimfile/A/index", g->get_header_value("Location"));
|
ASSERT_EQ("/zimfile/A/index", g->get_header_value("Location"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ServerTest, HeadMethodIsSupported)
|
||||||
|
{
|
||||||
|
for ( const Resource& res : all200Resources() )
|
||||||
|
EXPECT_EQ(200, zfs1_->HEAD(res.url)->status) << res;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ServerTest, TheResponseToHeadRequestHasNoBody)
|
||||||
|
{
|
||||||
|
for ( const Resource& res : all200Resources() )
|
||||||
|
EXPECT_TRUE(zfs1_->HEAD(res.url)->body.empty()) << res;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ServerTest, HeadersAreTheSameInResponsesToHeadAndGetRequests)
|
||||||
|
{
|
||||||
|
for ( const Resource& res : all200Resources() ) {
|
||||||
|
httplib::Headers g = zfs1_->GET(res.url)->headers;
|
||||||
|
httplib::Headers h = zfs1_->HEAD(res.url)->headers;
|
||||||
|
EXPECT_EQ(invariantHeaders(g), invariantHeaders(h)) << res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue