8 wrz 2009

Serwer ssl wykorzystujący boost::asio zawsze korzysta z jednego wątka

Napisałem serwer wykorzystujący boost::asio::ssl, który zawierał pulę 10 wątków obsługujących żądania klientów.
Szybko jednak okazało się, że żądania od klientów zawsze są obsługiwane w jednym wątku roboczym:
jeśli wątek ten wykonywał długą operację, to request od innego klienta czekał aż operacja w pierwszym wątku zakończy się.

Dokładną przyczynę tego błędu opisałem na grupie boost-users w poście:
"[asio] SSL enabled http server3 example is blocking"

Rozwiązanie problemu jest dość proste:
nie wykonywać długich operacji bezpośrednio w handlerze wywoływanym przez async_read(), async_write(). Zamiast tego handler powinien wysłać tę operację do io_serwis, aby wykonała się asynchoriniczie.

Przykład handlera wywyoływanego po asynchronicznym odczycie danych (requestu od klienta):

void Request::readHeaderHandler( const boost::system::error_code
&error, std::size_t bytesTransferred )
{
m_ioService.post( boost::bind
( &Request::executeCommandHandler::executeCommandHandler,
shared_from_this() ) );

}

void Request::executeCommandHandler()
{
// long running operation
char c;

}

1 wrz 2009

Jak serwer ssl z obiektu boost::asio::stream może uzyskać adres IP klienta?

// definicja stream-u ssl opartego na sockecie tcp
typedef boost::asio::ssl::stream ssl_socket;

// kod inicjujący nasłuch serwera na sockecie zakończony wywołaniem: async_accept() / accept()

// jak już klient się połączył, to mamy obiekt ssl_socket:
ssl_socket m_socket;

// z, którego można pobrać IP klienta:
const boost::asio::ip::tcp::endpoint &endpoint = m_socket.lowest_layer().remote_endpoint();
const boost::asio::ip::address &addr = endpoint.address();

std::cout << "client: " << addr.to_string() << std::endl;

Jak odczytywać certyfikaty X509 za pomocą openssl?

Ano tak:
http://kahdev.wordpress.com