Merge pull request #66 from hmagarotto/ssl-unclean-shutdown

SSL & unclean shutdown response
This commit is contained in:
Aleksandar Fabijanic 2013-01-16 21:00:41 -08:00
commit c97c444672
5 changed files with 68 additions and 0 deletions

View File

@ -170,6 +170,7 @@ protected:
void connect(const SocketAddress& address); void connect(const SocketAddress& address);
std::string proxyRequestPrefix() const; std::string proxyRequestPrefix() const;
void proxyAuthenticate(HTTPRequest& request); void proxyAuthenticate(HTTPRequest& request);
int read(char* buffer, std::streamsize length);
private: private:
HTTPSClientSession(const HTTPSClientSession&); HTTPSClientSession(const HTTPSClientSession&);

View File

@ -38,6 +38,7 @@
#include "Poco/Net/SecureStreamSocket.h" #include "Poco/Net/SecureStreamSocket.h"
#include "Poco/Net/SecureStreamSocketImpl.h" #include "Poco/Net/SecureStreamSocketImpl.h"
#include "Poco/Net/SSLManager.h" #include "Poco/Net/SSLManager.h"
#include "Poco/Net/SSLException.h"
#include "Poco/Net/HTTPRequest.h" #include "Poco/Net/HTTPRequest.h"
#include "Poco/Net/HTTPResponse.h" #include "Poco/Net/HTTPResponse.h"
#include "Poco/Net/NetException.h" #include "Poco/Net/NetException.h"
@ -190,6 +191,15 @@ void HTTPSClientSession::connect(const SocketAddress& address)
} }
int HTTPSClientSession::read(char* buffer, std::streamsize length) {
try {
return HTTPClientSession::read(buffer, length);
} catch(SSLConnectionUnexpectedlyClosedException&) {
return 0;
}
}
Session::Ptr HTTPSClientSession::sslSession() Session::Ptr HTTPSClientSession::sslSession()
{ {
return _pSession; return _pSession;

View File

@ -46,6 +46,7 @@
#include "Poco/Net/Context.h" #include "Poco/Net/Context.h"
#include "Poco/Net/Session.h" #include "Poco/Net/Session.h"
#include "Poco/Net/SSLManager.h" #include "Poco/Net/SSLManager.h"
#include "Poco/Net/SSLException.h"
#include "Poco/Util/Application.h" #include "Poco/Util/Application.h"
#include "Poco/Util/AbstractConfiguration.h" #include "Poco/Util/AbstractConfiguration.h"
#include "Poco/StreamCopier.h" #include "Poco/StreamCopier.h"
@ -434,6 +435,40 @@ void HTTPSClientSessionTest::testCachedSession()
} }
void HTTPSClientSessionTest::testUnknownContentLength()
{
HTTPSTestServer srv;
HTTPSClientSession s("localhost", srv.port());
HTTPRequest request(HTTPRequest::HTTP_GET, "/nolength");
s.sendRequest(request);
HTTPResponse response;
std::istream& rs = s.receiveResponse(response);
assert (response.getContentLength() == HTTPMessage::UNKNOWN_CONTENT_LENGTH);
assert (response.getContentType() == "text/plain");
std::ostringstream ostr;
StreamCopier::copyStream(rs, ostr);
assert (ostr.str() == HTTPSTestServer::SMALL_BODY);
}
void HTTPSClientSessionTest::testServerAbort()
{
HTTPSTestServer srv;
HTTPSClientSession s("localhost", srv.port());
HTTPRequest request(HTTPRequest::HTTP_GET, "/nolength/connection/abort");
s.sendRequest(request);
HTTPResponse response;
std::istream& rs = s.receiveResponse(response);
assert (response.getContentLength() == HTTPMessage::UNKNOWN_CONTENT_LENGTH);
assert (response.getContentType() == "text/plain");
std::ostringstream ostr;
StreamCopier::copyStream(rs, ostr);
assert (ostr.str() == HTTPSTestServer::SMALL_BODY);
assert ( dynamic_cast<const Poco::Net::SSLConnectionUnexpectedlyClosedException*>(
s.networkException()) != NULL );
}
void HTTPSClientSessionTest::setUp() void HTTPSClientSessionTest::setUp()
{ {
} }
@ -460,6 +495,8 @@ CppUnit::Test* HTTPSClientSessionTest::suite()
CppUnit_addTest(pSuite, HTTPSClientSessionTest, testInterop); CppUnit_addTest(pSuite, HTTPSClientSessionTest, testInterop);
CppUnit_addTest(pSuite, HTTPSClientSessionTest, testProxy); CppUnit_addTest(pSuite, HTTPSClientSessionTest, testProxy);
CppUnit_addTest(pSuite, HTTPSClientSessionTest, testCachedSession); CppUnit_addTest(pSuite, HTTPSClientSessionTest, testCachedSession);
CppUnit_addTest(pSuite, HTTPSClientSessionTest, testUnknownContentLength);
CppUnit_addTest(pSuite, HTTPSClientSessionTest, testServerAbort);
return pSuite; return pSuite;
} }

View File

@ -58,6 +58,9 @@ public:
void testInterop(); void testInterop();
void testProxy(); void testProxy();
void testCachedSession(); void testCachedSession();
void testUnknownContentLength();
void testServerAbort();
void setUp(); void setUp();
void tearDown(); void tearDown();

View File

@ -33,6 +33,7 @@
#include "HTTPSTestServer.h" #include "HTTPSTestServer.h"
#include "Poco/Net/SecureStreamSocket.h" #include "Poco/Net/SecureStreamSocket.h"
#include "Poco/Net/SocketAddress.h" #include "Poco/Net/SocketAddress.h"
#include "Poco/Net/SecureStreamSocketImpl.h"
#include "Poco/Timespan.h" #include "Poco/Timespan.h"
#include "Poco/NumberFormatter.h" #include "Poco/NumberFormatter.h"
#include <iostream> #include <iostream>
@ -43,6 +44,7 @@ using Poco::Net::StreamSocket;
using Poco::Net::SecureStreamSocket; using Poco::Net::SecureStreamSocket;
using Poco::Net::SecureServerSocket; using Poco::Net::SecureServerSocket;
using Poco::Net::SocketAddress; using Poco::Net::SocketAddress;
using Poco::Net::SecureStreamSocketImpl;
using Poco::NumberFormatter; using Poco::NumberFormatter;
@ -115,6 +117,10 @@ void HTTPSTestServer::run()
} }
std::string response = handleRequest(); std::string response = handleRequest();
ss.sendBytes(response.data(), (int) response.size()); ss.sendBytes(response.data(), (int) response.size());
if(_lastRequest.find("/connection/abort")!=std::string::npos) {
SecureStreamSocketImpl* sss = dynamic_cast<SecureStreamSocketImpl*>(ss.impl());
if(sss!=NULL) sss->abort();
}
Poco::Thread::sleep(1000); Poco::Thread::sleep(1000);
} }
catch (Poco::Exception& exc) catch (Poco::Exception& exc)
@ -167,6 +173,17 @@ std::string HTTPSTestServer::handleRequest() const
if (_lastRequest.substr(0, 3) == "GET") if (_lastRequest.substr(0, 3) == "GET")
response.append(body); response.append(body);
} }
else if (_lastRequest.substr(0, 13) == "GET /nolength" ||
_lastRequest.substr(0, 14) == "HEAD /nolength")
{
std::string body(SMALL_BODY);
response.append("HTTP/1.0 200 OK\r\n");
response.append("Content-Type: text/plain\r\n");
response.append("Connection: Close\r\n");
response.append("\r\n");
if (_lastRequest.substr(0, 3) == "GET")
response.append(body);
}
else if (_lastRequest.substr(0, 4) == "POST") else if (_lastRequest.substr(0, 4) == "POST")
{ {
std::string::size_type pos = _lastRequest.find("\r\n\r\n"); std::string::size_type pos = _lastRequest.find("\r\n\r\n");