123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- #include "HttpServer.h"
- #include <cppunit/extensions/HelperMacros.h>
- #include "SocketCore.h"
- #include "a2functional.h"
- namespace aria2 {
- class HttpServerTest : public CppUnit::TestFixture {
- CPPUNIT_TEST_SUITE(HttpServerTest);
- CPPUNIT_TEST(testHttpBasicAuth);
- CPPUNIT_TEST_SUITE_END();
- public:
- void testHttpBasicAuth();
- };
- CPPUNIT_TEST_SUITE_REGISTRATION(HttpServerTest);
- namespace {
- std::unique_ptr<HttpServer> performHttpRequest(SocketCore& server,
- std::string request)
- {
- auto endpoint = server.getAddrInfo();
- SocketCore client;
- client.establishConnection("localhost", endpoint.port);
- while (!client.isWritable(0)) {
- }
- auto inbound = server.acceptConnection();
- inbound->setBlockingMode();
- auto rv = make_unique<HttpServer>(inbound);
- client.writeData(request);
- while (!rv->receiveRequest()) {
- }
- return rv;
- }
- } // namespace
- void HttpServerTest::testHttpBasicAuth()
- {
- SocketCore server;
- server.bind(0);
- server.beginListen();
- server.setBlockingMode();
- {
- // Default is no auth
- auto req = performHttpRequest(
- server, "GET / HTTP/1.1\r\nUser-Agent: aria2-test\r\n\r\n");
- CPPUNIT_ASSERT(req->authenticate());
- }
- {
- // Empty user-name and password should come out as no auth.
- auto req = performHttpRequest(
- server, "GET / HTTP/1.1\r\nUser-Agent: aria2-test\r\n\r\n");
- req->setUsernamePassword("", "");
- CPPUNIT_ASSERT(req->authenticate());
- }
- {
- // Empty user-name but set password should also come out as no auth.
- auto req = performHttpRequest(
- server, "GET / HTTP/1.1\r\nUser-Agent: aria2-test\r\n\r\n");
- req->setUsernamePassword("", "pass");
- CPPUNIT_ASSERT(req->authenticate());
- }
- {
- // Client provided credentials should be ignored when there is no auth.
- auto req = performHttpRequest(server, "GET / HTTP/1.1\r\nUser-Agent: "
- "aria2-test\r\nAuthorization: Basic "
- "dXNlcjpwYXNz\r\n\r\n");
- req->setUsernamePassword("", "pass");
- CPPUNIT_ASSERT(req->authenticate());
- }
- {
- // Correct client provided credentials should match.
- auto req = performHttpRequest(server, "GET / HTTP/1.1\r\nUser-Agent: "
- "aria2-test\r\nAuthorization: Basic "
- "dXNlcjpwYXNz\r\n\r\n");
- req->setUsernamePassword("user", "pass");
- CPPUNIT_ASSERT(req->authenticate());
- }
- {
- // Correct client provided credentials should match (2).
- // Embedded nulls
- auto req = performHttpRequest(
- server, "GET / HTTP/1.1\r\nUser-Agent: aria2-test\r\nAuthorization: "
- "Basic dXNlcgBudWxsOnBhc3MAbnVsbA==\r\n\r\n");
- req->setUsernamePassword(std::string("user\0null", 9),
- std::string("pass\0null", 9));
- CPPUNIT_ASSERT(req->authenticate());
- }
- {
- // Correct client provided credentials should match (3).
- // Embedded, leading nulls
- auto req = performHttpRequest(server, "GET / HTTP/1.1\r\nUser-Agent: "
- "aria2-test\r\nAuthorization: Basic "
- "AHVzZXI6AHBhc3M=\r\n\r\n");
- req->setUsernamePassword(std::string("\0user", 5),
- std::string("\0pass", 5));
- CPPUNIT_ASSERT(req->authenticate());
- }
- {
- // Correct client provided credentials should match (3).
- // Whitespace
- auto req = performHttpRequest(server, "GET / HTTP/1.1\r\nUser-Agent: "
- "aria2-test\r\nAuthorization: Basic "
- "IHVzZXIJOgpwYXNzDQ==\r\n\r\n");
- req->setUsernamePassword(" user\t", "\npass\r");
- CPPUNIT_ASSERT(req->authenticate());
- }
- {
- // Wrong client provided credentials should NOT match.
- auto req = performHttpRequest(server, "GET / HTTP/1.1\r\nUser-Agent: "
- "aria2-test\r\nAuthorization: Basic "
- "dXNlcjpwYXNz\r\n\r\n");
- req->setUsernamePassword("user", "pass2");
- CPPUNIT_ASSERT(!req->authenticate());
- }
- {
- // Wrong client provided credentials should NOT match (2).
- auto req = performHttpRequest(server, "GET / HTTP/1.1\r\nUser-Agent: "
- "aria2-test\r\nAuthorization: Basic "
- "dXNlcjpwYXNz\r\n\r\n");
- req->setUsernamePassword("user2", "pass");
- CPPUNIT_ASSERT(!req->authenticate());
- }
- {
- // Wrong client provided credentials should NOT match (3).
- // Embedded null in pass config.
- auto req = performHttpRequest(server, "GET / HTTP/1.1\r\nUser-Agent: "
- "aria2-test\r\nAuthorization: Basic "
- "dXNlcjpwYXNz\r\n\r\n");
- req->setUsernamePassword("user", std::string("pass\0three", 10));
- CPPUNIT_ASSERT(!req->authenticate());
- }
- {
- // Wrong client provided credentials should NOT match (4).
- // Embedded null in user config.
- auto req = performHttpRequest(server, "GET / HTTP/1.1\r\nUser-Agent: "
- "aria2-test\r\nAuthorization: Basic "
- "dXNlcjpwYXNz\r\n\r\n");
- req->setUsernamePassword(std::string("user\0four", 9), "pass");
- CPPUNIT_ASSERT(!req->authenticate());
- }
- {
- // Wrong client provided credentials should NOT match (5).
- // Embedded null in http auth.
- auto req = performHttpRequest(server, "GET / HTTP/1.1\r\nUser-Agent: "
- "aria2-test\r\nAuthorization: Basic "
- "dXNlcjpwYXNzAHRocmVl\r\n\r\n");
- req->setUsernamePassword("user", "pass");
- CPPUNIT_ASSERT(!req->authenticate());
- }
- {
- // Wrong client provided credentials should NOT match (6).
- // Embedded null in http auth.
- // Embedded, leading nulls
- auto req = performHttpRequest(server, "GET / HTTP/1.1\r\nUser-Agent: "
- "aria2-test\r\nAuthorization: Basic "
- "AHVzZXI6AHBhc3M=\r\n\r\n");
- req->setUsernamePassword(std::string("\0user5", 6),
- std::string("\0pass", 5));
- CPPUNIT_ASSERT(!req->authenticate());
- }
- {
- // When there is a user and password, the client must actually provide auth.
- auto req = performHttpRequest(
- server, "GET / HTTP/1.1\r\nUser-Agent: aria2-test\r\n\r\n");
- req->setUsernamePassword("user", "pass");
- CPPUNIT_ASSERT(!req->authenticate());
- }
- }
- } // namespace aria2
|