BHttpRequest: propagate SSL errors to listener

This way it's possible to handle them in applications.
This commit is contained in:
Adrien Destugues
2014-11-06 15:02:00 +01:00
parent c86ad7f93b
commit 5ee2151e2c
7 changed files with 146 additions and 34 deletions
+49 -5
View File
@@ -19,6 +19,7 @@
#include <new>
#include <AutoDeleter.h>
#include <Certificate.h>
#include <Debug.h>
#include <DynamicBuffer.h>
#include <File.h>
@@ -31,6 +32,35 @@
static const int32 kHttpBufferSize = 4096;
class CheckedSecureSocket: public BSecureSocket
{
public:
CheckedSecureSocket(BHttpRequest* request);
bool CertificateVerificationFailed(BCertificate& certificate,
const char* message);
private:
BHttpRequest* fRequest;
};
CheckedSecureSocket::CheckedSecureSocket(BHttpRequest* request)
:
BSecureSocket(),
fRequest(request)
{
}
bool
CheckedSecureSocket::CertificateVerificationFailed(BCertificate& certificate,
const char* message)
{
return fRequest->_CertificateVerificationFailed(certificate, message);
}
BHttpRequest::BHttpRequest(const BUrl& url, bool ssl, const char* protocolName,
BUrlProtocolListener* listener, BUrlContext* context)
:
@@ -50,7 +80,7 @@ BHttpRequest::BHttpRequest(const BUrl& url, bool ssl, const char* protocolName,
{
_ResetOptions();
if (fSSL)
fSocket = new(std::nothrow) BSecureSocket();
fSocket = new(std::nothrow) CheckedSecureSocket(this);
else
fSocket = new(std::nothrow) BSocket();
}
@@ -76,7 +106,7 @@ BHttpRequest::BHttpRequest(const BHttpRequest& other)
_ResetOptions();
// FIXME some options may be copied from other instead.
if (fSSL)
fSocket = new(std::nothrow) BSecureSocket();
fSocket = new(std::nothrow) CheckedSecureSocket(this);
else
fSocket = new(std::nothrow) BSocket();
}
@@ -791,7 +821,7 @@ BHttpRequest::_SendHeaders()
BString host = Url().Host();
if (Url().HasPort() && !_IsDefaultPort())
host << ':' << Url().Port();
outputHeaders.AddHeader("Host", host);
outputHeaders.AddHeader("Accept", "*/*");
@@ -887,7 +917,7 @@ BHttpRequest::_SendHeaders()
break;
cookieString << "; ";
}
outputHeaders.AddHeader("Cookie", cookieString);
}
}
@@ -1022,7 +1052,21 @@ BHttpRequest::_ResultStatusText()
}
bool BHttpRequest::_IsDefaultPort()
bool
BHttpRequest::_CertificateVerificationFailed(BCertificate& certificate,
const char* message)
{
if (fListener != NULL) {
return fListener->CertificateVerificationFailed(this, certificate,
message);
}
return false;
}
bool
BHttpRequest::_IsDefaultPort()
{
if (fSSL && Url().Port() == 443)
return true;
@@ -142,6 +142,20 @@ BUrlProtocolAsynchronousListener::MessageReceived(BMessage* message)
}
break;
case B_URL_PROTOCOL_CERTIFICATE_VERIFICATION_FAILED:
{
const char* error = message->FindString("url:error");
BCertificate* certificate;
message->FindPointer("url:certificate", (void**)&certificate);
bool result = CertificateVerificationFailed(caller,
*certificate, error);
BMessage reply;
reply.AddBool("url:continue", result);
message->SendReply(&reply);
}
break;
default:
PRINT(("BUrlProtocolAsynchronousListener: Unknown notification %d\n",
notification));
@@ -125,6 +125,25 @@ BUrlProtocolDispatchingListener::RequestCompleted(BUrlRequest* caller,
}
bool
BUrlProtocolDispatchingListener::CertificateVerificationFailed(
BUrlRequest* caller, BCertificate& certificate, const char* error)
{
BMessage message(B_URL_PROTOCOL_NOTIFICATION);
message.AddString("url:error", error);
message.AddPointer("url:certificate", &certificate);
message.AddInt8(kUrlProtocolMessageType,
B_URL_PROTOCOL_CERTIFICATE_VERIFICATION_FAILED);
message.AddPointer(kUrlProtocolCaller, caller);
// Warning: synchronous reply
BMessage reply;
fMessenger.SendMessage(&message, &reply);
return reply.FindBool("url:continue");
}
void
BUrlProtocolDispatchingListener::_SendMessage(BMessage* message,
int8 notification, BUrlRequest* caller)
@@ -27,6 +27,14 @@ BUrlProtocolListener::HostnameResolved(BUrlRequest*, const char*)
}
bool
BUrlProtocolListener::CertificateVerificationFailed(BUrlRequest* caller,
BCertificate& certificate, const char* message)
{
return false;
}
void
BUrlProtocolListener::ResponseStarted(BUrlRequest*)
{