mirror of https://github.com/aria2/aria2
				
				
				
			
		
			
				
	
	
		
			189 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			189 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C++
		
	
	
#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)
 | 
						|
  {
 | 
						|
    std::pair<std::string, uint16_t> addr;
 | 
						|
    server.getAddrInfo(addr);
 | 
						|
 | 
						|
    SocketCore client;
 | 
						|
    client.establishConnection("localhost", addr.second);
 | 
						|
    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
 |