Enable HTTPS connections.
Using more modern network classes: * BNetworkAddress instead of BNetAddress * BSocket and BSecureSocket instead of BNetEndpoint
This commit is contained in:
committed by
Hamish Morrison
parent
d1b6afe678
commit
4e607e1aae
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user