Skip to content

Commit

Permalink
Bind service to specific IP address.
Browse files Browse the repository at this point in the history
  • Loading branch information
ben-crowhurst committed Aug 22, 2015
1 parent 5caa529 commit 41b77e1
Show file tree
Hide file tree
Showing 12 changed files with 108 additions and 7 deletions.
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,20 @@ Restbed is a comprehensive and consistent programming model for building applica
| Comet Support | Long polling model to allow long-held HTTP requests for pushing data from the server to client. |
| [SSL/TLS](https://github.com/Corvusoft/restbed/blob/master/example/https_service/source/example.cpp) | Secure over the wire communication allowing you to transmit private data online. |
| [Path Parameters](https://github.com/Corvusoft/restbed/blob/master/example/path_parameters/source/example.cpp) | Annotate URIs with custom path parameters such as resource keys, revisions, etc... |
| Query Parameters | Automated query parameter parsings. |
| Query Parameters | Automated query parameter parsing. |
| [Header Filters](https://github.com/Corvusoft/restbed/blob/master/example/resource_filtering/source/example.cpp) | Filter incoming HTTP requests by headers. |
| [Logging](https://github.com/Corvusoft/restbed/blob/master/example/logging/source/example.cpp) | Customise how and where log entries are created. |
| [Multi-Path Resources](https://github.com/Corvusoft/restbed/blob/master/example/publishing_multipath_resources/source/example.cpp) | Give a resource multiple paths for improved readability. |
| [Customisable Methods](https://github.com/Corvusoft/restbed/blob/master/example/custom_methods/source/example.cpp) | Add your own custom HTTP methods. |
| [Compression](https://github.com/Corvusoft/restbed/blob/master/example/compression/source/example.cpp) | Adaptability to address any form of compression GZip, Deflate, etc... |
| Encoding | Adaptability to address any form of encoding UTF-32, ASCII, etc... |
| [Rules Engine](https://github.com/Corvusoft/restbed/blob/master/example/rules_engine/source/example.cpp) | Reduce complexity by processing incoming requests as readable units of code. |
| [Rules Engine](https://github.com/Corvusoft/restbed/blob/master/example/rules_engine/source/example.cpp) | Reduce complexity by processing incoming requests with readable units of code. |
| IPv4/IPv6 | Internet Protocol Version 4/6 Network Support. |
| Architecture | Asynchronous [single](https://github.com/Corvusoft/restbed/blob/master/example/publishing_resources/source/example.cpp) or [multi-threaded](https://github.com/Corvusoft/restbed/blob/master/example/multithreaded_service/source/example.cpp) architecture, capable of addressing the C10K problem. |
| Converters | Built-in Path, Query, and Header conversions for string, int, long, and float data types. |
| [Authentication](https://github.com/Corvusoft/restbed/blob/master/example/authentication/source/example.cpp) | Seperate Service and/or Resource level authentication. |
| [Error Handling](https://github.com/Corvusoft/restbed/blob/master/example/error_handling/source/example.cpp) | Seperate Service and/or Resource level error handling . |
| [Error Handling](https://github.com/Corvusoft/restbed/blob/master/example/error_handling/source/example.cpp) | Seperate Service and/or Resource level error handling. |
| [Address Binding](https://github.com/Corvusoft/restbed/blob/master/example/bind_service_address/source/example.cpp) | Bind HTTP and/or HTTPS services to separate IP addresses. |
| Compliance | Flexibility to address HTTP 1.0/1.1+ compliance. |
| Mature | Secure, Stable, and extensively tested over 3+ years. |
| Community | Active, vibrant and energetic open source community. |
Expand Down Expand Up @@ -132,8 +133,8 @@ You will now find all required components installed in the distribution folder.
| 3.0 | Rules Engine | complete |
| 3.5 | Schedule Tasks on Service run-loop | complete |
| 3.5 | Multi-Threaded service capability | complete |
| 3.5 | Bind Service to specific Address | in-development |
| 3.5 | Session Management | pending |
| 3.5 | Bind Service to specific Address | complete |
| 3.5 | Session Management | in-development |
| 4.0 | Resource Caching | pending |
| 4.0 | Web Sockets | pending |
| 5.0 | HTTP 2.0 compliance | pending |
Expand Down
3 changes: 3 additions & 0 deletions example/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ target_link_libraries( multithreaded_service ${CMAKE_PROJECT_NAME} )
add_executable( schedule_work_on_service_runloop schedule_work_on_service_runloop/source/example.cpp )
target_link_libraries( schedule_work_on_service_runloop ${CMAKE_PROJECT_NAME} )

add_executable( bind_service_address bind_service_address/source/example.cpp )
target_link_libraries( bind_service_address ${CMAKE_PROJECT_NAME} )

if ( PAM_FOUND )
add_executable( pam_authentication pam_authentication/source/example.cpp )
target_link_libraries( pam_authentication ${CMAKE_PROJECT_NAME} pam )
Expand Down
39 changes: 39 additions & 0 deletions example/bind_service_address/source/example.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Example illustrating binding service to specific address.
*
* Server Usage:
* ./distribution/example/bind_service_address
*
* Client Usage:
* curl -w'\n' -v -XGET 'http://127.0.0.1:1984/resource'
*/

#include <memory>
#include <cstdlib>
#include <restbed>

using namespace std;
using namespace restbed;

void get_method_handler( const shared_ptr< Session >& session )
{
session->close( OK, "Hello, World!", { { "Content-Length", "13" } } );
}

int main( const int, const char** )
{
auto resource = make_shared< Resource >( );
resource->set_path( "/resource" );
resource->set_method_handler( "GET", get_method_handler );

auto settings = make_shared< Settings >( );
settings->set_port( 1984 );
settings->set_bind_address( "127.0.0.1" );
settings->set_default_header( "Connection", "close" );

Service service;
service.publish( resource );
service.start( settings );

return EXIT_SUCCESS;
}
24 changes: 22 additions & 2 deletions source/corvusoft/restbed/detail/service_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ using std::regex_constants::icase;
using asio::ip::tcp;
using asio::io_service;
using asio::error_code;
using asio::ip::address;
using asio::socket_base;
using asio::system_error;

Expand Down Expand Up @@ -99,7 +100,17 @@ namespace restbed
if ( ssl_settings == nullptr or ssl_settings->has_disabled_http( ) == false )
{
#endif
acceptor = make_shared< tcp::acceptor >( *io_service, tcp::endpoint( tcp::v6( ), settings->get_port( ) ) );

if ( not settings->get_bind_address( ).empty( ) )
{
const auto address = address::from_string( settings->get_bind_address( ) );
acceptor = make_shared< tcp::acceptor >( *io_service, tcp::endpoint( address, settings->get_port( ) ) );
}
else
{
acceptor = make_shared< tcp::acceptor >( *io_service, tcp::endpoint( tcp::v6( ), settings->get_port( ) ) );
}

acceptor->set_option( socket_base::reuse_address( true ) );
acceptor->listen( settings->get_connection_limit( ) );

Expand Down Expand Up @@ -189,7 +200,16 @@ namespace restbed
options = ( ssl_settings->has_enabled_single_diffie_hellman_use( ) ) ? options | asio::ssl::context::single_dh_use : options;
ssl_context->set_options( options );

ssl_acceptor = make_shared< tcp::acceptor >( *io_service, tcp::endpoint( tcp::v6( ), ssl_settings->get_port( ) ) );
if ( not ssl_settings->get_bind_address( ).empty( ) )
{
const auto address = address::from_string( ssl_settings->get_bind_address( ) );
ssl_acceptor = make_shared< tcp::acceptor >( *io_service, tcp::endpoint( address, ssl_settings->get_port( ) ) );
}
else
{
ssl_acceptor = make_shared< tcp::acceptor >( *io_service, tcp::endpoint( tcp::v6( ), ssl_settings->get_port( ) ) );
}

ssl_acceptor->set_option( socket_base::reuse_address( true ) );
ssl_acceptor->listen( settings->get_connection_limit( ) );

Expand Down
2 changes: 2 additions & 0 deletions source/corvusoft/restbed/detail/settings_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ namespace restbed

uint32_t connection_limit = 128;

std::string bind_address = "";

bool case_insensitive_uris = true;

std::map< std::string, std::string > properties { };
Expand Down
2 changes: 2 additions & 0 deletions source/corvusoft/restbed/detail/ssl_settings_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ namespace restbed

bool single_diffie_hellman_use_enabled = true;

std::string bind_address = "";

std::string passphrase = "";

std::string private_key = "";
Expand Down
10 changes: 10 additions & 0 deletions source/corvusoft/restbed/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ namespace restbed
return m_pimpl->connection_limit;
}

string Settings::get_bind_address( void ) const
{
return m_pimpl->bind_address;
}

bool Settings::get_case_insensitive_uris( void ) const
{
return m_pimpl->case_insensitive_uris;
Expand Down Expand Up @@ -115,6 +120,11 @@ namespace restbed
m_pimpl->connection_limit = value;
}

void Settings::set_bind_address( const string& value )
{
m_pimpl->bind_address = value;
}

void Settings::set_case_insensitive_uris( const bool value )
{
m_pimpl->case_insensitive_uris = value;
Expand Down
4 changes: 4 additions & 0 deletions source/corvusoft/restbed/settings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ namespace restbed

int32_t get_connection_limit( void ) const;

std::string get_bind_address( void ) const;

bool get_case_insensitive_uris( void ) const;

std::chrono::milliseconds get_connection_timeout( void ) const;
Expand All @@ -80,6 +82,8 @@ namespace restbed

void set_connection_limit( const int32_t value );

void set_bind_address( const std::string& value );

void set_case_insensitive_uris( const bool value );

void set_connection_timeout( const std::chrono::milliseconds& value );
Expand Down
10 changes: 10 additions & 0 deletions source/corvusoft/restbed/ssl_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ namespace restbed
return m_pimpl->port;
}

string SSLSettings::get_bind_address( void ) const
{
return m_pimpl->bind_address;
}

string SSLSettings::get_certificate( void ) const
{
return m_pimpl->certificate;
Expand Down Expand Up @@ -122,6 +127,11 @@ namespace restbed
m_pimpl->port = value;
}

void SSLSettings::set_bind_address( const string& value )
{
m_pimpl->bind_address = value;
}

void SSLSettings::set_http_disabled( const bool value )
{
m_pimpl->http_disabled = value;
Expand Down
4 changes: 4 additions & 0 deletions source/corvusoft/restbed/ssl_settings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ namespace restbed
//Getters
uint16_t get_port( void ) const;

std::string get_bind_address( void ) const;

std::string get_certificate( void ) const;

std::string get_passphrase( void ) const;
Expand All @@ -80,6 +82,8 @@ namespace restbed
//Setters
void set_port( const uint16_t value );

void set_bind_address( const std::string& value );

void set_http_disabled( const bool value );

void set_sslv2_enabled( const bool value );
Expand Down
3 changes: 3 additions & 0 deletions test/unit/source/settings_suite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ TEST_CASE( "validate default instance values", "[settings]" )
REQUIRE( settings.get_root( ) == "/" );
REQUIRE( settings.get_worker_limit( ) == 0 );
REQUIRE( settings.get_properties( ).empty( ) );
REQUIRE( settings.get_bind_address( ).empty( ) );
REQUIRE( settings.get_connection_limit( ) == 128 );
REQUIRE( settings.get_default_headers( ).empty( ) );
REQUIRE( settings.get_case_insensitive_uris( ) == true );
Expand Down Expand Up @@ -116,6 +117,7 @@ TEST_CASE( "validate setters modify default values", "[settings]" )
settings.set_worker_limit( 4 );
settings.set_root( "/resources" );
settings.set_connection_limit( 1 );
settings.set_bind_address( "::1" );
settings.set_case_insensitive_uris( false );
settings.set_connection_timeout( milliseconds( 30 ) );
settings.set_properties( { { "name", "value" } } );
Expand All @@ -124,6 +126,7 @@ TEST_CASE( "validate setters modify default values", "[settings]" )
REQUIRE( settings.get_port( ) == 1984 );
REQUIRE( settings.get_root( ) == "/resources" );
REQUIRE( settings.get_worker_limit( ) == 4 );
REQUIRE( settings.get_bind_address( ) == "::1" );
REQUIRE( settings.get_connection_limit( ) == 1 );
REQUIRE( settings.get_case_insensitive_uris( ) == false );
REQUIRE( settings.get_connection_timeout( ) == milliseconds( 30 ) );
Expand Down
3 changes: 3 additions & 0 deletions test/unit/source/ssl_settings_suite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ TEST_CASE( "validate default instance values", "[ssl-settings]" )
REQUIRE( settings.has_enabled_compression( ) );
REQUIRE( settings.has_enabled_default_workarounds( ) );
REQUIRE( settings.has_enabled_single_diffie_hellman_use( ) );
REQUIRE( settings.get_bind_address( ).empty( ) );
REQUIRE( settings.get_passphrase( ).empty( ) );
REQUIRE( settings.get_certificate( ).empty( ) );
REQUIRE( settings.get_private_key( ).empty( ) );
Expand Down Expand Up @@ -62,6 +63,7 @@ TEST_CASE( "validate setters modify default values", "[settings]" )
settings.set_compression_enabled( false );
settings.set_default_workarounds_enabled( false );
settings.set_single_diffie_hellman_use_enabled( false );
settings.set_bind_address( "127.0.0.1" );
settings.set_passphrase( "my-passphrase" );

REQUIRE( settings.get_port( ) == 8080 );
Expand All @@ -73,6 +75,7 @@ TEST_CASE( "validate setters modify default values", "[settings]" )
REQUIRE( not settings.has_enabled_compression( ) );
REQUIRE( not settings.has_enabled_default_workarounds( ) );
REQUIRE( not settings.has_enabled_single_diffie_hellman_use( ) );
REQUIRE( settings.get_bind_address( ) == "127.0.0.1" );
REQUIRE( settings.get_passphrase( ) == "my-passphrase" );
REQUIRE( settings.has_disabled_http( ) == true );
}

0 comments on commit 41b77e1

Please sign in to comment.