Factor out a BNetworkRequest
* Shares common behavior between the Gopher and HTTP request handlers. * Most of this can be used when implemeting other protocols.
This commit is contained in:
@@ -8,15 +8,10 @@
|
|||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
#include <NetBuffer.h>
|
#include <NetworkRequest.h>
|
||||||
#include <NetworkAddress.h>
|
|
||||||
#include <UrlRequest.h>
|
|
||||||
|
|
||||||
|
|
||||||
class BAbstractSocket;
|
class BGopherRequest : public BNetworkRequest {
|
||||||
|
|
||||||
|
|
||||||
class BGopherRequest : public BUrlRequest {
|
|
||||||
public:
|
public:
|
||||||
BGopherRequest(const BUrl& url,
|
BGopherRequest(const BUrl& url,
|
||||||
BUrlProtocolListener* listener = NULL,
|
BUrlProtocolListener* listener = NULL,
|
||||||
@@ -29,21 +24,17 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
status_t _ProtocolLoop();
|
status_t _ProtocolLoop();
|
||||||
bool _ResolveHostName();
|
|
||||||
void _SendRequest();
|
void _SendRequest();
|
||||||
|
|
||||||
bool _NeedsParsing();
|
bool _NeedsParsing();
|
||||||
bool _NeedsLastDotStrip();
|
bool _NeedsLastDotStrip();
|
||||||
void _ParseInput(bool last);
|
void _ParseInput(bool last);
|
||||||
|
|
||||||
status_t _GetLine(BString& destString);
|
|
||||||
BString& _HTMLEscapeString(BString &str);
|
BString& _HTMLEscapeString(BString &str);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char fItemType;
|
char fItemType;
|
||||||
BString fPath;
|
BString fPath;
|
||||||
BAbstractSocket* fSocket;
|
|
||||||
BNetworkAddress fRemoteAddr;
|
|
||||||
|
|
||||||
BNetBuffer fInputBuffer;
|
BNetBuffer fInputBuffer;
|
||||||
ssize_t fPosition;
|
ssize_t fPosition;
|
||||||
|
|||||||
@@ -11,15 +11,11 @@
|
|||||||
#include <HttpForm.h>
|
#include <HttpForm.h>
|
||||||
#include <HttpHeaders.h>
|
#include <HttpHeaders.h>
|
||||||
#include <HttpResult.h>
|
#include <HttpResult.h>
|
||||||
#include <NetBuffer.h>
|
|
||||||
#include <NetworkAddress.h>
|
#include <NetworkAddress.h>
|
||||||
#include <UrlRequest.h>
|
#include <NetworkRequest.h>
|
||||||
|
|
||||||
|
|
||||||
class BAbstractSocket;
|
class BHttpRequest : public BNetworkRequest {
|
||||||
|
|
||||||
|
|
||||||
class BHttpRequest : public BUrlRequest {
|
|
||||||
public:
|
public:
|
||||||
BHttpRequest(const BUrl& url,
|
BHttpRequest(const BUrl& url,
|
||||||
bool ssl = false,
|
bool ssl = false,
|
||||||
@@ -63,15 +59,12 @@ public:
|
|||||||
private:
|
private:
|
||||||
void _ResetOptions();
|
void _ResetOptions();
|
||||||
status_t _ProtocolLoop();
|
status_t _ProtocolLoop();
|
||||||
bool _ResolveHostName();
|
|
||||||
status_t _MakeRequest();
|
status_t _MakeRequest();
|
||||||
|
|
||||||
void _SendRequest();
|
void _SendRequest();
|
||||||
void _SendHeaders();
|
void _SendHeaders();
|
||||||
void _SendPostData();
|
void _SendPostData();
|
||||||
|
|
||||||
status_t _GetLine(BString& destString);
|
|
||||||
|
|
||||||
void _ParseStatus();
|
void _ParseStatus();
|
||||||
void _ParseHeaders();
|
void _ParseHeaders();
|
||||||
|
|
||||||
@@ -85,15 +78,11 @@ private:
|
|||||||
bool _IsDefaultPort();
|
bool _IsDefaultPort();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BAbstractSocket* fSocket;
|
|
||||||
BNetworkAddress fRemoteAddr;
|
|
||||||
bool fSSL;
|
bool fSSL;
|
||||||
|
|
||||||
BString fRequestMethod;
|
BString fRequestMethod;
|
||||||
int8 fHttpVersion;
|
int8 fHttpVersion;
|
||||||
|
|
||||||
BNetBuffer fInputBuffer;
|
|
||||||
|
|
||||||
BHttpHeaders fHeaders;
|
BHttpHeaders fHeaders;
|
||||||
|
|
||||||
// Request status
|
// Request status
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 Haiku Inc. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef _B_NET_REQUEST_H_
|
||||||
|
#define _B_NET_REQUEST_H_
|
||||||
|
|
||||||
|
|
||||||
|
#include <NetBuffer.h>
|
||||||
|
#include <NetworkAddress.h>
|
||||||
|
#include <UrlRequest.h>
|
||||||
|
|
||||||
|
|
||||||
|
class BAbstractSocket;
|
||||||
|
|
||||||
|
|
||||||
|
class BNetworkRequest: public BUrlRequest
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BNetworkRequest(const BUrl& url,
|
||||||
|
BUrlProtocolListener* listener,
|
||||||
|
BUrlContext* context,
|
||||||
|
const char* threadName,
|
||||||
|
const char* protocolName);
|
||||||
|
protected:
|
||||||
|
bool _ResolveHostName(uint16_t port);
|
||||||
|
|
||||||
|
status_t _GetLine(BString& destString);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BAbstractSocket* fSocket;
|
||||||
|
BNetworkAddress fRemoteAddr;
|
||||||
|
|
||||||
|
BNetBuffer fInputBuffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -182,7 +182,7 @@ static const bool kInlineImages = true;
|
|||||||
BGopherRequest::BGopherRequest(const BUrl& url, BUrlProtocolListener* listener,
|
BGopherRequest::BGopherRequest(const BUrl& url, BUrlProtocolListener* listener,
|
||||||
BUrlContext* context)
|
BUrlContext* context)
|
||||||
:
|
:
|
||||||
BUrlRequest(url, listener, context, "BUrlProtocol.Gopher", "gopher"),
|
BNetworkRequest(url, listener, context, "BUrlProtocol.Gopher", "gopher"),
|
||||||
fItemType(GOPHER_TYPE_NONE),
|
fItemType(GOPHER_TYPE_NONE),
|
||||||
fPosition(0),
|
fPosition(0),
|
||||||
fResult()
|
fResult()
|
||||||
@@ -236,7 +236,7 @@ BGopherRequest::_ProtocolLoop()
|
|||||||
if (fSocket == NULL)
|
if (fSocket == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
if (!_ResolveHostName()) {
|
if (!_ResolveHostName(70)) {
|
||||||
_EmitDebug(B_URL_PROTOCOL_DEBUG_ERROR,
|
_EmitDebug(B_URL_PROTOCOL_DEBUG_ERROR,
|
||||||
"Unable to resolve hostname (%s), aborting.",
|
"Unable to resolve hostname (%s), aborting.",
|
||||||
fUrl.Host().String());
|
fUrl.Host().String());
|
||||||
@@ -386,36 +386,6 @@ BGopherRequest::_ProtocolLoop()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
BGopherRequest::_ResolveHostName()
|
|
||||||
{
|
|
||||||
_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Resolving %s",
|
|
||||||
fUrl.UrlString().String());
|
|
||||||
|
|
||||||
uint16_t port;
|
|
||||||
if (fUrl.HasPort())
|
|
||||||
port = fUrl.Port();
|
|
||||||
else
|
|
||||||
port = 70;
|
|
||||||
|
|
||||||
// FIXME stop forcing AF_INET, when BNetworkAddress stops giving IPv6
|
|
||||||
// addresses when there isn't an IPv6 link available.
|
|
||||||
fRemoteAddr = BNetworkAddress(AF_INET, fUrl.Host(), port);
|
|
||||||
|
|
||||||
if (fRemoteAddr.InitCheck() != B_OK)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
//! ProtocolHook:HostnameResolved
|
|
||||||
if (fListener != NULL)
|
|
||||||
fListener->HostnameResolved(this, fRemoteAddr.ToString().String());
|
|
||||||
|
|
||||||
_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Hostname resolved to: %s",
|
|
||||||
fRemoteAddr.ToString().String());
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BGopherRequest::_SendRequest()
|
BGopherRequest::_SendRequest()
|
||||||
{
|
{
|
||||||
@@ -726,36 +696,6 @@ BGopherRequest::_ParseInput(bool last)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
BGopherRequest::_GetLine(BString& destString)
|
|
||||||
{
|
|
||||||
// Find a complete line in inputBuffer
|
|
||||||
uint32 characterIndex = 0;
|
|
||||||
|
|
||||||
while ((characterIndex < fInputBuffer.Size())
|
|
||||||
&& ((fInputBuffer.Data())[characterIndex] != '\n'))
|
|
||||||
characterIndex++;
|
|
||||||
|
|
||||||
if (characterIndex == fInputBuffer.Size())
|
|
||||||
return B_ERROR;
|
|
||||||
|
|
||||||
char* temporaryBuffer = new(std::nothrow) char[characterIndex + 1];
|
|
||||||
if (temporaryBuffer == NULL)
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
|
|
||||||
fInputBuffer.RemoveData(temporaryBuffer, characterIndex + 1);
|
|
||||||
|
|
||||||
// Strip end-of-line character(s)
|
|
||||||
if (temporaryBuffer[characterIndex - 1] == '\r')
|
|
||||||
destString.SetTo(temporaryBuffer, characterIndex - 1);
|
|
||||||
else
|
|
||||||
destString.SetTo(temporaryBuffer, characterIndex);
|
|
||||||
|
|
||||||
delete[] temporaryBuffer;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BString&
|
BString&
|
||||||
BGopherRequest::_HTMLEscapeString(BString &str)
|
BGopherRequest::_HTMLEscapeString(BString &str)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,11 +30,11 @@
|
|||||||
|
|
||||||
static const int32 kHttpBufferSize = 4096;
|
static const int32 kHttpBufferSize = 4096;
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
:
|
:
|
||||||
BUrlRequest(url, listener, context, "BUrlProtocol.HTTP", protocolName),
|
BNetworkRequest(url, listener, context, "BUrlProtocol.HTTP", protocolName),
|
||||||
fSocket(NULL),
|
|
||||||
fSSL(ssl),
|
fSSL(ssl),
|
||||||
fRequestMethod(B_HTTP_GET),
|
fRequestMethod(B_HTTP_GET),
|
||||||
fHttpVersion(B_HTTP_11),
|
fHttpVersion(B_HTTP_11),
|
||||||
@@ -58,9 +58,8 @@ BHttpRequest::BHttpRequest(const BUrl& url, bool ssl, const char* protocolName,
|
|||||||
|
|
||||||
BHttpRequest::BHttpRequest(const BHttpRequest& other)
|
BHttpRequest::BHttpRequest(const BHttpRequest& other)
|
||||||
:
|
:
|
||||||
BUrlRequest(other.Url(), other.fListener, other.fContext,
|
BNetworkRequest(other.Url(), other.fListener, other.fContext,
|
||||||
"BUrlProtocol.HTTP", other.fSSL ? "HTTPS" : "HTTP"),
|
"BUrlProtocol.HTTP", other.fSSL ? "HTTPS" : "HTTP"),
|
||||||
fSocket(NULL),
|
|
||||||
fSSL(other.fSSL),
|
fSSL(other.fSSL),
|
||||||
fRequestMethod(other.fRequestMethod),
|
fRequestMethod(other.fRequestMethod),
|
||||||
fHttpVersion(other.fHttpVersion),
|
fHttpVersion(other.fHttpVersion),
|
||||||
@@ -320,7 +319,7 @@ BHttpRequest::_ProtocolLoop()
|
|||||||
fHeaders.Clear();
|
fHeaders.Clear();
|
||||||
_ResultHeaders().Clear();
|
_ResultHeaders().Clear();
|
||||||
|
|
||||||
if (!_ResolveHostName()) {
|
if (!_ResolveHostName(fSSL ? 443 : 80)) {
|
||||||
_EmitDebug(B_URL_PROTOCOL_DEBUG_ERROR,
|
_EmitDebug(B_URL_PROTOCOL_DEBUG_ERROR,
|
||||||
"Unable to resolve hostname (%s), aborting.",
|
"Unable to resolve hostname (%s), aborting.",
|
||||||
fUrl.Host().String());
|
fUrl.Host().String());
|
||||||
@@ -425,36 +424,6 @@ BHttpRequest::_ProtocolLoop()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
BHttpRequest::_ResolveHostName()
|
|
||||||
{
|
|
||||||
_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Resolving %s",
|
|
||||||
fUrl.UrlString().String());
|
|
||||||
|
|
||||||
uint16_t port;
|
|
||||||
if (fUrl.HasPort())
|
|
||||||
port = fUrl.Port();
|
|
||||||
else
|
|
||||||
port = fSSL ? 443 : 80;
|
|
||||||
|
|
||||||
// FIXME stop forcing AF_INET, when BNetworkAddress stops giving IPv6
|
|
||||||
// addresses when there isn't an IPv6 link available.
|
|
||||||
fRemoteAddr = BNetworkAddress(AF_INET, fUrl.Host(), port);
|
|
||||||
|
|
||||||
if (fRemoteAddr.InitCheck() != B_OK)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
//! ProtocolHook:HostnameResolved
|
|
||||||
if (fListener != NULL)
|
|
||||||
fListener->HostnameResolved(this, fRemoteAddr.ToString().String());
|
|
||||||
|
|
||||||
_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Hostname resolved to: %s",
|
|
||||||
fRemoteAddr.ToString().String());
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BHttpRequest::_MakeRequest()
|
BHttpRequest::_MakeRequest()
|
||||||
{
|
{
|
||||||
@@ -713,36 +682,6 @@ BHttpRequest::_MakeRequest()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
BHttpRequest::_GetLine(BString& destString)
|
|
||||||
{
|
|
||||||
// Find a complete line in inputBuffer
|
|
||||||
uint32 characterIndex = 0;
|
|
||||||
|
|
||||||
while ((characterIndex < fInputBuffer.Size())
|
|
||||||
&& ((fInputBuffer.Data())[characterIndex] != '\n'))
|
|
||||||
characterIndex++;
|
|
||||||
|
|
||||||
if (characterIndex == fInputBuffer.Size())
|
|
||||||
return B_ERROR;
|
|
||||||
|
|
||||||
char* temporaryBuffer = new(std::nothrow) char[characterIndex + 1];
|
|
||||||
if (temporaryBuffer == NULL)
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
|
|
||||||
fInputBuffer.RemoveData(temporaryBuffer, characterIndex + 1);
|
|
||||||
|
|
||||||
// Strip end-of-line character(s)
|
|
||||||
if (temporaryBuffer[characterIndex - 1] == '\r')
|
|
||||||
destString.SetTo(temporaryBuffer, characterIndex - 1);
|
|
||||||
else
|
|
||||||
destString.SetTo(temporaryBuffer, characterIndex);
|
|
||||||
|
|
||||||
delete[] temporaryBuffer;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BHttpRequest::_ParseStatus()
|
BHttpRequest::_ParseStatus()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
|||||||
|
|
||||||
$(md5Sources)
|
$(md5Sources)
|
||||||
|
|
||||||
|
NetworkRequest.cpp
|
||||||
Url.cpp
|
Url.cpp
|
||||||
UrlContext.cpp
|
UrlContext.cpp
|
||||||
UrlProtocolAsynchronousListener.cpp
|
UrlProtocolAsynchronousListener.cpp
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2014 Haiku Inc. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Christophe Huriaux, c.huriaux@gmail.com
|
||||||
|
* Niels Sascha Reedijk, niels.reedijk@gmail.com
|
||||||
|
* Adrien Destugues, pulkomandy@pulkomandy.tk
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <NetworkRequest.h>
|
||||||
|
|
||||||
|
|
||||||
|
BNetworkRequest::BNetworkRequest(const BUrl& url, BUrlProtocolListener* listener,
|
||||||
|
BUrlContext* context, const char* threadName, const char* protocolName)
|
||||||
|
:
|
||||||
|
BUrlRequest(url, listener, context, threadName, protocolName),
|
||||||
|
fSocket(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BNetworkRequest::_ResolveHostName(uint16_t port)
|
||||||
|
{
|
||||||
|
_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Resolving %s",
|
||||||
|
fUrl.UrlString().String());
|
||||||
|
|
||||||
|
if (fUrl.HasPort())
|
||||||
|
port = fUrl.Port();
|
||||||
|
|
||||||
|
// FIXME stop forcing AF_INET, when BNetworkAddress stops giving IPv6
|
||||||
|
// addresses when there isn't an IPv6 link available.
|
||||||
|
fRemoteAddr = BNetworkAddress(AF_INET, fUrl.Host(), port);
|
||||||
|
|
||||||
|
if (fRemoteAddr.InitCheck() != B_OK)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//! ProtocolHook:HostnameResolved
|
||||||
|
if (fListener != NULL)
|
||||||
|
fListener->HostnameResolved(this, fRemoteAddr.ToString().String());
|
||||||
|
|
||||||
|
_EmitDebug(B_URL_PROTOCOL_DEBUG_TEXT, "Hostname resolved to: %s",
|
||||||
|
fRemoteAddr.ToString().String());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BNetworkRequest::_GetLine(BString& destString)
|
||||||
|
{
|
||||||
|
// Find a complete line in inputBuffer
|
||||||
|
uint32 characterIndex = 0;
|
||||||
|
|
||||||
|
while ((characterIndex < fInputBuffer.Size())
|
||||||
|
&& ((fInputBuffer.Data())[characterIndex] != '\n'))
|
||||||
|
characterIndex++;
|
||||||
|
|
||||||
|
if (characterIndex == fInputBuffer.Size())
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
char* temporaryBuffer = new(std::nothrow) char[characterIndex + 1];
|
||||||
|
if (temporaryBuffer == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
fInputBuffer.RemoveData(temporaryBuffer, characterIndex + 1);
|
||||||
|
|
||||||
|
// Strip end-of-line character(s)
|
||||||
|
if (temporaryBuffer[characterIndex - 1] == '\r')
|
||||||
|
destString.SetTo(temporaryBuffer, characterIndex - 1);
|
||||||
|
else
|
||||||
|
destString.SetTo(temporaryBuffer, characterIndex);
|
||||||
|
|
||||||
|
delete[] temporaryBuffer;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user