Enable HTTPS connections.

Using more modern network classes:
 * BNetworkAddress instead of BNetAddress
 * BSocket and BSecureSocket instead of BNetEndpoint
This commit is contained in:
Niels Sascha Reedijk
2013-02-07 18:06:02 +00:00
committed by Hamish Morrison
parent d1b6afe678
commit 4e607e1aae
3 changed files with 64 additions and 43 deletions
+8 -4
View File
@@ -12,17 +12,21 @@
#include <HttpAuthentication.h> #include <HttpAuthentication.h>
#include <HttpForm.h> #include <HttpForm.h>
#include <HttpHeaders.h> #include <HttpHeaders.h>
#include <NetEndpoint.h>
#include <NetBuffer.h> #include <NetBuffer.h>
#include <NetworkAddress.h>
#include <UrlProtocol.h> #include <UrlProtocol.h>
class BAbstractSocket;
class BUrlProtocolHttp : public BUrlProtocol { class BUrlProtocolHttp : public BUrlProtocol {
public: public:
BUrlProtocolHttp(BUrl& url, BUrlProtocolHttp(BUrl& url, bool ssl = false,
BUrlProtocolListener* listener = NULL, BUrlProtocolListener* listener = NULL,
BUrlContext* context = NULL, BUrlContext* context = NULL,
BUrlResult* result = NULL); BUrlResult* result = NULL);
virtual ~BUrlProtocolHttp();
virtual status_t SetOption(uint32 option, void* value); virtual status_t SetOption(uint32 option, void* value);
@@ -56,8 +60,8 @@ private:
private: private:
BNetEndpoint fSocket; BAbstractSocket* fSocket;
BNetAddress fRemoteAddr; BNetworkAddress fRemoteAddr;
int8 fRequestMethod; int8 fRequestMethod;
int8 fHttpVersion; int8 fHttpVersion;
+47 -38
View File
@@ -1,9 +1,10 @@
/* /*
* Copyright 2010 Haiku Inc. All rights reserved. * Copyright 2010-2011 Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Christophe Huriaux, [email protected] * Christophe Huriaux, [email protected]
* Niels Sascha Reedijk, [email protected]
*/ */
@@ -14,6 +15,8 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#include <Debug.h> #include <Debug.h>
#include <File.h> #include <File.h>
#include <Socket.h>
#include <SecureSocket.h>
#include <UrlProtocolHttp.h> #include <UrlProtocolHttp.h>
@@ -28,14 +31,26 @@ static const char* kHttpProtocolThreadStrStatus[
}; };
BUrlProtocolHttp::BUrlProtocolHttp(BUrl& url, BUrlProtocolListener* listener, BUrlProtocolHttp::BUrlProtocolHttp(BUrl& url, bool ssl,
BUrlContext* context, BUrlResult* result) BUrlProtocolListener* listener, BUrlContext* context,
BUrlResult* result)
: :
BUrlProtocol(url, listener, context, result, "BUrlProtocol.HTTP", "HTTP"), BUrlProtocol(url, listener, context, result, "BUrlProtocol.HTTP", "HTTP"),
fRequestMethod(B_HTTP_GET), fRequestMethod(B_HTTP_GET),
fHttpVersion(B_HTTP_11) fHttpVersion(B_HTTP_11)
{ {
_ResetOptions(); _ResetOptions();
if (ssl)
fSocket = new BSecureSocket();
else
fSocket = new BSocket();
}
BUrlProtocolHttp::~BUrlProtocolHttp()
{
delete fSocket;
} }
@@ -203,11 +218,7 @@ status_t
BUrlProtocolHttp::_ProtocolLoop() BUrlProtocolHttp::_ProtocolLoop()
{ {
printf("UHP[%p]::{Loop} %s\n", this, fUrl.UrlString().String()); printf("UHP[%p]::{Loop} %s\n", this, fUrl.UrlString().String());
// Socket initialization
fSocket = BNetEndpoint(SOCK_STREAM);
if (fSocket.InitCheck() != B_OK)
return B_PROT_SOCKET_ERROR;
// Initialize the request redirection loop // Initialize the request redirection loop
int8 maxRedirs = fOptMaxRedirs; int8 maxRedirs = fOptMaxRedirs;
bool newRequest; bool newRequest;
@@ -325,23 +336,20 @@ BUrlProtocolHttp::_ResolveHostName()
fUrl.UrlString().String()); fUrl.UrlString().String());
if (fUrl.HasPort()) if (fUrl.HasPort())
fRemoteAddr = BNetAddress(fUrl.Host(), fUrl.Port()); fRemoteAddr = BNetworkAddress(fUrl.Host(), fUrl.Port());
else else
fRemoteAddr = BNetAddress(fUrl.Host(), 80); fRemoteAddr = BNetworkAddress(fUrl.Host(), 80);
if (fRemoteAddr.InitCheck() != B_OK) if (fRemoteAddr.InitCheck() != B_OK)
return false; return false;
char addr[15];
struct in_addr ip;
fRemoteAddr.GetAddr(ip);
inet_ntop(AF_INET, &ip, addr, 15);
//! ProtocolHook:HostnameResolved //! ProtocolHook:HostnameResolved
if (fListener != NULL) if (fListener != NULL)
fListener->HostnameResolved(this, const_cast<const char*>(addr)); fListener->HostnameResolved(this,
const_cast<const char*>(fRemoteAddr.ToString().String()));
_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Hostname resolved to: %s", addr); _EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Hostname resolved to: %s",
fRemoteAddr.ToString().String());
return true; return true;
} }
@@ -352,11 +360,10 @@ BUrlProtocolHttp::_MakeRequest()
{ {
_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Connection to %s.", _EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Connection to %s.",
fUrl.Authority().String()); fUrl.Authority().String());
status_t connectError = fSocket.Connect(fRemoteAddr); status_t connectError = fSocket->Connect(fRemoteAddr);
if (connectError != B_OK) { if (connectError != B_OK) {
_EmitDebug(B_URL_PROTOCOL_DEBUG_ERROR, "Connection error: %s.", _EmitDebug(B_URL_PROTOCOL_DEBUG_ERROR, "Socket connection error.");
fSocket.ErrorStr());
return B_PROT_CONNECTION_FAILED; return B_PROT_CONNECTION_FAILED;
} }
@@ -368,7 +375,7 @@ BUrlProtocolHttp::_MakeRequest()
_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Sending request (size=%d)", _EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Sending request (size=%d)",
fOutputBuffer.Length()); fOutputBuffer.Length());
fSocket.Send(fOutputBuffer.String(), fOutputBuffer.Length()); fSocket->Write(fOutputBuffer.String(), fOutputBuffer.Length());
fOutputBuffer.Truncate(0); fOutputBuffer.Truncate(0);
_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Request sent."); _EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Request sent.");
@@ -377,14 +384,14 @@ BUrlProtocolHttp::_MakeRequest()
fOutputBuffer = fOptPostFields->RawData(); fOutputBuffer = fOptPostFields->RawData();
_EmitDebug(B_URL_PROTOCOL_DEBUG_TRANSFER_OUT, _EmitDebug(B_URL_PROTOCOL_DEBUG_TRANSFER_OUT,
fOutputBuffer.String()); fOutputBuffer.String());
fSocket.Send(fOutputBuffer.String(), fOutputBuffer.Length()); fSocket->Write(fOutputBuffer.String(), fOutputBuffer.Length());
} else { } else {
for (BHttpForm::Iterator it = fOptPostFields->GetIterator(); for (BHttpForm::Iterator it = fOptPostFields->GetIterator();
const BHttpFormData* currentField = it.Next(); const BHttpFormData* currentField = it.Next();
) { ) {
_EmitDebug(B_URL_PROTOCOL_DEBUG_TRANSFER_OUT, _EmitDebug(B_URL_PROTOCOL_DEBUG_TRANSFER_OUT,
it.MultipartHeader().String()); it.MultipartHeader().String());
fSocket.Send(it.MultipartHeader().String(), fSocket->Write(it.MultipartHeader().String(),
it.MultipartHeader().Length()); it.MultipartHeader().Length());
switch (currentField->Type()) { switch (currentField->Type()) {
@@ -393,7 +400,7 @@ BUrlProtocolHttp::_MakeRequest()
break; break;
case B_HTTPFORM_STRING: case B_HTTPFORM_STRING:
fSocket.Send(currentField->String().String(), fSocket->Write(currentField->String().String(),
currentField->String().Length()); currentField->String().Length());
break; break;
@@ -406,22 +413,22 @@ BUrlProtocolHttp::_MakeRequest()
readSize = upFile.Read(readBuffer, 1024); readSize = upFile.Read(readBuffer, 1024);
while (readSize > 0) { while (readSize > 0) {
fSocket.Send(readBuffer, readSize); fSocket->Write(readBuffer, readSize);
readSize = upFile.Read(readBuffer, 1024); readSize = upFile.Read(readBuffer, 1024);
} }
} }
break; break;
case B_HTTPFORM_BUFFER: case B_HTTPFORM_BUFFER:
fSocket.Send(currentField->Buffer(), fSocket->Write(currentField->Buffer(),
currentField->BufferSize()); currentField->BufferSize());
break; break;
} }
fSocket.Send("\r\n", 2); fSocket->Write("\r\n", 2);
} }
fSocket.Send(fOptPostFields->GetMultipartFooter().String(), fSocket->Write(fOptPostFields->GetMultipartFooter().String(),
fOptPostFields->GetMultipartFooter().Length()); fOptPostFields->GetMultipartFooter().Length());
} }
} else if ((fRequestMethod == B_HTTP_POST || fRequestMethod == B_HTTP_PUT) } else if ((fRequestMethod == B_HTTP_POST || fRequestMethod == B_HTTP_PUT)
@@ -436,19 +443,17 @@ BUrlProtocolHttp::_MakeRequest()
char hexSize[16]; char hexSize[16];
size_t hexLength = sprintf(hexSize, "%ld", read); size_t hexLength = sprintf(hexSize, "%ld", read);
fSocket.Send(hexSize, hexLength); fSocket->Write(hexSize, hexLength);
fSocket.Send("\r\n", 2); fSocket->Write("\r\n", 2);
fSocket.Send(outputTempBuffer, read); fSocket->Write(outputTempBuffer, read);
fSocket.Send("\r\n", 2); fSocket->Write("\r\n", 2);
} }
} }
fSocket.Send("0\r\n\r\n", 5); fSocket->Write("0\r\n\r\n", 5);
} }
fOutputBuffer.Truncate(0, true); fOutputBuffer.Truncate(0, true);
fSocket.SetNonBlocking(false);
fStatusReceived = false; fStatusReceived = false;
fHeadersReceived = false; fHeadersReceived = false;
@@ -466,7 +471,9 @@ BUrlProtocolHttp::_MakeRequest()
while (!fQuit && !(receiveEnd && parseEnd)) { while (!fQuit && !(receiveEnd && parseEnd)) {
if (!receiveEnd) { if (!receiveEnd) {
bytesRead = fSocket.Receive(fInputBuffer, receiveBufferSize); fSocket->WaitForReadable();
BNetBuffer chunk(receiveBufferSize);
bytesRead = fSocket->Read(chunk.Data(), receiveBufferSize);
if (bytesRead < 0) { if (bytesRead < 0) {
readError = true; readError = true;
@@ -474,6 +481,8 @@ BUrlProtocolHttp::_MakeRequest()
continue; continue;
} else if (bytesRead == 0) } else if (bytesRead == 0)
receiveEnd = true; receiveEnd = true;
fInputBuffer.AppendData(chunk.Data(), bytesRead);
} }
else else
bytesRead = 0; bytesRead = 0;
@@ -563,7 +572,7 @@ BUrlProtocolHttp::_MakeRequest()
parseEnd = (fInputBuffer.Size() == 0); parseEnd = (fInputBuffer.Size() == 0);
} }
fSocket.Close(); fSocket->Disconnect();
if (readError) if (readError)
return B_PROT_READ_FAILED; return B_PROT_READ_FAILED;
@@ -681,7 +690,7 @@ BUrlProtocolHttp::_CopyChunkInBuffer(char** buffer, ssize_t* bytesReceived)
chunkHeader.Length() - semiColonIndex); chunkHeader.Length() - semiColonIndex);
chunkSize = strtol(chunkHeader.String(), NULL, 16); chunkSize = strtol(chunkHeader.String(), NULL, 16);
PRINT(("BHP[%p] Chunk %s=%d\n", this, chunkHeader.String(), chunkSize)); PRINT(("BHP[%p] Chunk %s=%ld\n", this, chunkHeader.String(), chunkSize));
if (chunkSize == 0) { if (chunkSize == 0) {
fContentReceived = true; fContentReceived = true;
} }
+9 -1
View File
@@ -136,7 +136,15 @@ BUrlRequest::Identify()
fUrlProtocol = NULL; fUrlProtocol = NULL;
if (fUrl.Protocol() == "http") { if (fUrl.Protocol() == "http") {
fUrlProtocol = new(std::nothrow) BUrlProtocolHttp(fUrl, fListener, fContext, &fResult); fUrlProtocol = new(std::nothrow) BUrlProtocolHttp(fUrl, false,
fListener, fContext,
&fResult);
fReady = true;
return B_OK;
} else if (fUrl.Protocol() == "https") {
fUrlProtocol = new(std::nothrow) BUrlProtocolHttp(fUrl, true,
fListener, fContext,
&fResult);
fReady = true; fReady = true;
return B_OK; return B_OK;
} }