get_remote_address() now works on SSL sockets accepted through SSLListener

Post/get/... data is no longer case insensitive.
This commit is contained in:
Fred Nicolson 2017-08-02 17:32:16 +01:00
parent 0c7d37a8e3
commit 0bd41ec6bd
4 changed files with 49 additions and 40 deletions

View File

@ -138,7 +138,7 @@ namespace fr
* @param key The name of the GET variable * @param key The name of the GET variable
* @return A reference to the GET variable * @return A reference to the GET variable
*/ */
std::string &get(std::string &&key); std::string &get(const std::string &key);
/*! /*!
* Returns a reference to a POST variable. * Returns a reference to a POST variable.
@ -149,7 +149,7 @@ namespace fr
* @param key The name of the POST variable * @param key The name of the POST variable
* @return A reference to the POST variable * @return A reference to the POST variable
*/ */
std::string &post(std::string &&key); std::string &post(const std::string &key);
/*! /*!
* Returns a reference to a header. * Returns a reference to a header.
@ -160,7 +160,7 @@ namespace fr
* @param key The name of the header * @param key The name of the header
* @return A reference to the header * @return A reference to the header
*/ */
std::string &header(std::string &&key); std::string &header(const std::string &key);
/*! /*!
@ -169,7 +169,7 @@ namespace fr
* @param key The name of the GET variable * @param key The name of the GET variable
* @return True if it does. False otherwise. * @return True if it does. False otherwise.
*/ */
bool get_exists(std::string &&key) const; bool get_exists(const std::string &key) const;
/*! /*!
* Checks to see if a given POST variable exists * Checks to see if a given POST variable exists
@ -177,16 +177,15 @@ namespace fr
* @param key The name of the POST variable * @param key The name of the POST variable
* @return True if it does. False otherwise. * @return True if it does. False otherwise.
*/ */
bool post_exists(std::string &&key) const; bool post_exists(const std::string &key) const;
/*! /*!
* Checks to see if a given header exists. * Checks to see if a given header exists.
* Note: key will be converted to lower case
* *
* @param key The name of the header * @param key The name of the header
* @return True if it does. False otherwise. * @return True if it does. False otherwise.
*/ */
bool header_exists(std::string &&key) const; bool header_exists(const std::string &key) const;
/*! /*!
* Returns the requested URI * Returns the requested URI

View File

@ -48,30 +48,37 @@ namespace fr
body = body_; body = body_;
} }
std::string &Http::get(std::string &&key) std::string &Http::get(const std::string &key)
{ {
std::transform(key.begin(), key.end(), key.begin(), ::tolower);
return get_data[key]; return get_data[key];
} }
std::string &Http::post(std::string &&key) std::string &Http::post(const std::string &key)
{ {
std::transform(key.begin(), key.end(), key.begin(), ::tolower);
return post_data[key]; return post_data[key];
} }
bool Http::get_exists(std::string &&key) const bool Http::get_exists(const std::string &key) const
{ {
std::transform(key.begin(), key.end(), key.begin(), ::tolower);
return get_data.find(key) != get_data.end(); return get_data.find(key) != get_data.end();
} }
bool Http::post_exists(std::string &&key) const bool Http::post_exists(const std::string &key) const
{ {
std::transform(key.begin(), key.end(), key.begin(), ::tolower);
return post_data.find(key) != post_data.end(); return post_data.find(key) != post_data.end();
} }
std::string &Http::header(const std::string &key)
{
return header_data[key];
}
bool Http::header_exists(const std::string &key) const
{
return header_data.find(key) != header_data.end();
}
const std::string &Http::get_uri() const const std::string &Http::get_uri() const
{ {
return uri; return uri;
@ -155,18 +162,6 @@ namespace fr
return result; return result;
} }
std::string &Http::header(std::string &&key)
{
std::transform(key.begin(), key.end(), key.begin(), ::tolower);
return header_data[key];
}
bool Http::header_exists(std::string &&key) const
{
std::transform(key.begin(), key.end(), key.begin(), ::tolower);
return header_data.find(key) != header_data.end();
}
std::vector<std::pair<std::string, std::string>> Http::parse_argument_list(const std::string &str) std::vector<std::pair<std::string, std::string>> Http::parse_argument_list(const std::string &str)
{ {
std::vector<std::pair<std::string, std::string>> list; std::vector<std::pair<std::string, std::string>> list;
@ -229,7 +224,6 @@ namespace fr
std::string header_name = str.substr(0, colon_pos); std::string header_name = str.substr(0, colon_pos);
std::string header_value = str.substr(data_begin, data_len); std::string header_value = str.substr(data_begin, data_len);
std::transform(header_name.begin(), header_name.end(), header_name.begin(), ::tolower);
header_data.emplace(std::move(header_name), std::move(header_value)); header_data.emplace(std::move(header_name), std::move(header_value));
} }

View File

@ -4,7 +4,8 @@
#include <chrono> #include <chrono>
#include <utility> #include <utility>
#include <frnetlib/TcpListener.h> #include "frnetlib/NetworkEncoding.h"
#include "frnetlib/TcpListener.h"
#include "frnetlib/SSLListener.h" #include "frnetlib/SSLListener.h"
#ifdef SSL_ENABLED #ifdef SSL_ENABLED
@ -110,7 +111,9 @@ namespace fr
} }
//Accept a connection //Accept a connection
if((error = mbedtls_net_accept(&listen_fd, client_fd.get(), nullptr, 0, nullptr)) != 0) char client_ip[INET6_ADDRSTRLEN] = {0};
size_t ip_len = 0;
if((error = mbedtls_net_accept(&listen_fd, client_fd.get(), client_ip, sizeof(client_ip), &ip_len)) != 0)
{ {
std::cout << "Accept error: " << error << std::endl; std::cout << "Accept error: " << error << std::endl;
free_contexts(); free_contexts();
@ -130,8 +133,21 @@ namespace fr
} }
} }
//Get remote address and port. We could get the IP from the accept args, but we also want the port
//Which mbedtls doesn't provide
//Get printable address. If we failed then set it as just 'unknown'
char client_printable_addr[INET6_ADDRSTRLEN];
struct sockaddr_storage socket_address{};
socklen_t socket_length;
error = getpeername(client_fd->fd, (struct sockaddr*)&socket_address, &socket_length);
if(error == 0)
error = getnameinfo((sockaddr*)&socket_address, socket_length, client_printable_addr, sizeof(client_printable_addr), nullptr,0,NI_NUMERICHOST);
if(error != 0)
strcpy(client_printable_addr, "unknown");
client.set_ssl_context(std::move(ssl)); client.set_ssl_context(std::move(ssl));
client.set_net_context(std::move(client_fd)); client.set_net_context(std::move(client_fd));
client.set_remote_address(client_printable_addr);
return Socket::Success; return Socket::Success;
} }

View File

@ -23,16 +23,16 @@ TEST(HttpRequestTest, get_request_parse)
ASSERT_EQ(request.get_uri(), "/index.html"); ASSERT_EQ(request.get_uri(), "/index.html");
//Test that headers exist //Test that headers exist
ASSERT_EQ(request.header_exists("host"), true); ASSERT_EQ(request.header_exists("Host"), true);
ASSERT_EQ(request.header_exists("contEnt-type"), true); ASSERT_EQ(request.header_exists("Content-Type"), true);
ASSERT_EQ(request.header_exists("my-HeadEr"), true); ASSERT_EQ(request.header_exists("My-Header"), true);
ASSERT_EQ(request.header_exists("my-other-header"), true); ASSERT_EQ(request.header_exists("My-Other-Header"), true);
ASSERT_EQ(request.header_exists("cache-control"), true); ASSERT_EQ(request.header_exists("Cache-Control"), true);
ASSERT_EQ(request.header_exists("non-existant"), false); ASSERT_EQ(request.header_exists("non-existant"), false);
//Check that headers are intact //Check that headers are intact
ASSERT_EQ(request.header("host"), "frednicolson.co.uk"); ASSERT_EQ(request.header("Host"), "frednicolson.co.uk");
ASSERT_EQ(request.header("content-type"), "application/x-www-form-urlencoded"); ASSERT_EQ(request.header("Content-Type"), "application/x-www-form-urlencoded");
ASSERT_EQ(request.header("My-Other-Header"), "header2"); ASSERT_EQ(request.header("My-Other-Header"), "header2");
ASSERT_EQ(request.header("My-Header"), "header1"); ASSERT_EQ(request.header("My-Header"), "header1");
@ -66,11 +66,11 @@ TEST(HttpRequestTest, post_request_parse)
//Parse code is the same for GET, so skip header checks. Test if POST data exists. //Parse code is the same for GET, so skip header checks. Test if POST data exists.
ASSERT_EQ(request.post_exists("post_data"), true); ASSERT_EQ(request.post_exists("post_data"), true);
ASSERT_EQ(request.post_exists("some_mOre_posT_data"), true); ASSERT_EQ(request.post_exists("some_more_post_data"), true);
ASSERT_EQ(request.post_exists("non_existant"), false); ASSERT_EQ(request.post_exists("non_existant"), false);
//Check that the POST data is valid //Check that the POST data is valid
ASSERT_EQ(request.post("post_dAta"), "data1"); ASSERT_EQ(request.post("post_data"), "data1");
ASSERT_EQ(request.post("some_more_post_data"), "data23"); ASSERT_EQ(request.post("some_more_post_data"), "data23");
} }