BHttpRequest: propagate SSL errors to listener
This way it's possible to handle them in applications.
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
|
#include <Certificate.h>
|
||||||
#include <HttpForm.h>
|
#include <HttpForm.h>
|
||||||
#include <HttpHeaders.h>
|
#include <HttpHeaders.h>
|
||||||
#include <HttpResult.h>
|
#include <HttpResult.h>
|
||||||
@@ -74,6 +75,12 @@ private:
|
|||||||
void _SetResultStatusCode(int32 statusCode);
|
void _SetResultStatusCode(int32 statusCode);
|
||||||
BString& _ResultStatusText();
|
BString& _ResultStatusText();
|
||||||
|
|
||||||
|
// SSL failure management
|
||||||
|
friend class CheckedSecureSocket;
|
||||||
|
bool _CertificateVerificationFailed(
|
||||||
|
BCertificate& certificate,
|
||||||
|
const char* message);
|
||||||
|
|
||||||
// Utility methods
|
// Utility methods
|
||||||
bool _IsDefaultPort();
|
bool _IsDefaultPort();
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ enum {
|
|||||||
B_URL_PROTOCOL_DATA_RECEIVED,
|
B_URL_PROTOCOL_DATA_RECEIVED,
|
||||||
B_URL_PROTOCOL_DOWNLOAD_PROGRESS,
|
B_URL_PROTOCOL_DOWNLOAD_PROGRESS,
|
||||||
B_URL_PROTOCOL_UPLOAD_PROGRESS,
|
B_URL_PROTOCOL_UPLOAD_PROGRESS,
|
||||||
B_URL_PROTOCOL_REQUEST_COMPLETED
|
B_URL_PROTOCOL_REQUEST_COMPLETED,
|
||||||
|
B_URL_PROTOCOL_CERTIFICATE_VERIFICATION_FAILED
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -52,6 +53,10 @@ public:
|
|||||||
ssize_t bytesSent, ssize_t bytesTotal);
|
ssize_t bytesSent, ssize_t bytesTotal);
|
||||||
virtual void RequestCompleted(BUrlRequest* caller,
|
virtual void RequestCompleted(BUrlRequest* caller,
|
||||||
bool success);
|
bool success);
|
||||||
|
virtual bool CertificateVerificationFailed(
|
||||||
|
BUrlRequest* caller,
|
||||||
|
BCertificate& certificate,
|
||||||
|
const char* message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _SendMessage(BMessage* message,
|
void _SendMessage(BMessage* message,
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
|
||||||
|
class BCertificate;
|
||||||
class BUrlRequest;
|
class BUrlRequest;
|
||||||
|
|
||||||
|
|
||||||
@@ -117,6 +119,19 @@ public:
|
|||||||
virtual void DebugMessage(BUrlRequest* caller,
|
virtual void DebugMessage(BUrlRequest* caller,
|
||||||
BUrlProtocolDebugMessage type,
|
BUrlProtocolDebugMessage type,
|
||||||
const char* text);
|
const char* text);
|
||||||
|
|
||||||
|
/**
|
||||||
|
CertificateVerificationFailed(certificate, message)
|
||||||
|
Frequency: Once
|
||||||
|
Parameters: certificate SSL certificate which coulnd't be validated
|
||||||
|
message error message describing the problem
|
||||||
|
|
||||||
|
Return true to proceed anyway, false to abort the connection
|
||||||
|
*/
|
||||||
|
virtual bool CertificateVerificationFailed(
|
||||||
|
BUrlRequest* caller,
|
||||||
|
BCertificate& certificate,
|
||||||
|
const char* message);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _B_URL_PROTOCOL_LISTENER_H_
|
#endif // _B_URL_PROTOCOL_LISTENER_H_
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
#include <AutoDeleter.h>
|
#include <AutoDeleter.h>
|
||||||
|
#include <Certificate.h>
|
||||||
#include <Debug.h>
|
#include <Debug.h>
|
||||||
#include <DynamicBuffer.h>
|
#include <DynamicBuffer.h>
|
||||||
#include <File.h>
|
#include <File.h>
|
||||||
@@ -31,6 +32,35 @@
|
|||||||
static const int32 kHttpBufferSize = 4096;
|
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,
|
BHttpRequest::BHttpRequest(const BUrl& url, bool ssl, const char* protocolName,
|
||||||
BUrlProtocolListener* listener, BUrlContext* context)
|
BUrlProtocolListener* listener, BUrlContext* context)
|
||||||
:
|
:
|
||||||
@@ -50,7 +80,7 @@ BHttpRequest::BHttpRequest(const BUrl& url, bool ssl, const char* protocolName,
|
|||||||
{
|
{
|
||||||
_ResetOptions();
|
_ResetOptions();
|
||||||
if (fSSL)
|
if (fSSL)
|
||||||
fSocket = new(std::nothrow) BSecureSocket();
|
fSocket = new(std::nothrow) CheckedSecureSocket(this);
|
||||||
else
|
else
|
||||||
fSocket = new(std::nothrow) BSocket();
|
fSocket = new(std::nothrow) BSocket();
|
||||||
}
|
}
|
||||||
@@ -76,7 +106,7 @@ BHttpRequest::BHttpRequest(const BHttpRequest& other)
|
|||||||
_ResetOptions();
|
_ResetOptions();
|
||||||
// FIXME some options may be copied from other instead.
|
// FIXME some options may be copied from other instead.
|
||||||
if (fSSL)
|
if (fSSL)
|
||||||
fSocket = new(std::nothrow) BSecureSocket();
|
fSocket = new(std::nothrow) CheckedSecureSocket(this);
|
||||||
else
|
else
|
||||||
fSocket = new(std::nothrow) BSocket();
|
fSocket = new(std::nothrow) BSocket();
|
||||||
}
|
}
|
||||||
@@ -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)
|
if (fSSL && Url().Port() == 443)
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -142,6 +142,20 @@ BUrlProtocolAsynchronousListener::MessageReceived(BMessage* message)
|
|||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
PRINT(("BUrlProtocolAsynchronousListener: Unknown notification %d\n",
|
PRINT(("BUrlProtocolAsynchronousListener: Unknown notification %d\n",
|
||||||
notification));
|
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
|
void
|
||||||
BUrlProtocolDispatchingListener::_SendMessage(BMessage* message,
|
BUrlProtocolDispatchingListener::_SendMessage(BMessage* message,
|
||||||
int8 notification, BUrlRequest* caller)
|
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
|
void
|
||||||
BUrlProtocolListener::ResponseStarted(BUrlRequest*)
|
BUrlProtocolListener::ResponseStarted(BUrlRequest*)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user