From 2f9b1874977669807fe200c7d3595d86a1984454 Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Mon, 4 Aug 2014 15:59:53 +0200 Subject: [PATCH] Factor out a BNetworkRequest * Shares common behavior between the Gopher and HTTP request handlers. * Most of this can be used when implemeting other protocols. --- headers/os/net/GopherRequest.h | 13 +-- headers/os/net/HttpRequest.h | 15 +--- headers/os/net/NetworkRequest.h | 38 +++++++++ src/kits/network/libnetapi/GopherRequest.cpp | 64 +-------------- src/kits/network/libnetapi/HttpRequest.cpp | 69 +--------------- src/kits/network/libnetapi/Jamfile | 1 + src/kits/network/libnetapi/NetworkRequest.cpp | 80 +++++++++++++++++++ 7 files changed, 129 insertions(+), 151 deletions(-) create mode 100644 headers/os/net/NetworkRequest.h create mode 100644 src/kits/network/libnetapi/NetworkRequest.cpp diff --git a/headers/os/net/GopherRequest.h b/headers/os/net/GopherRequest.h index 917334996a..9d1c692c03 100644 --- a/headers/os/net/GopherRequest.h +++ b/headers/os/net/GopherRequest.h @@ -8,15 +8,10 @@ #include -#include -#include -#include +#include -class BAbstractSocket; - - -class BGopherRequest : public BUrlRequest { +class BGopherRequest : public BNetworkRequest { public: BGopherRequest(const BUrl& url, BUrlProtocolListener* listener = NULL, @@ -29,21 +24,17 @@ public: private: status_t _ProtocolLoop(); - bool _ResolveHostName(); void _SendRequest(); bool _NeedsParsing(); bool _NeedsLastDotStrip(); void _ParseInput(bool last); - status_t _GetLine(BString& destString); BString& _HTMLEscapeString(BString &str); private: char fItemType; BString fPath; - BAbstractSocket* fSocket; - BNetworkAddress fRemoteAddr; BNetBuffer fInputBuffer; ssize_t fPosition; diff --git a/headers/os/net/HttpRequest.h b/headers/os/net/HttpRequest.h index 080805d933..6ca63ebe9b 100644 --- a/headers/os/net/HttpRequest.h +++ b/headers/os/net/HttpRequest.h @@ -11,15 +11,11 @@ #include #include #include -#include #include -#include +#include -class BAbstractSocket; - - -class BHttpRequest : public BUrlRequest { +class BHttpRequest : public BNetworkRequest { public: BHttpRequest(const BUrl& url, bool ssl = false, @@ -63,15 +59,12 @@ public: private: void _ResetOptions(); status_t _ProtocolLoop(); - bool _ResolveHostName(); status_t _MakeRequest(); void _SendRequest(); void _SendHeaders(); void _SendPostData(); - status_t _GetLine(BString& destString); - void _ParseStatus(); void _ParseHeaders(); @@ -85,15 +78,11 @@ private: bool _IsDefaultPort(); private: - BAbstractSocket* fSocket; - BNetworkAddress fRemoteAddr; bool fSSL; BString fRequestMethod; int8 fHttpVersion; - BNetBuffer fInputBuffer; - BHttpHeaders fHeaders; // Request status diff --git a/headers/os/net/NetworkRequest.h b/headers/os/net/NetworkRequest.h new file mode 100644 index 0000000000..8684f248b1 --- /dev/null +++ b/headers/os/net/NetworkRequest.h @@ -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 +#include +#include + + +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 diff --git a/src/kits/network/libnetapi/GopherRequest.cpp b/src/kits/network/libnetapi/GopherRequest.cpp index 951a9ccd88..9d0f15b29c 100644 --- a/src/kits/network/libnetapi/GopherRequest.cpp +++ b/src/kits/network/libnetapi/GopherRequest.cpp @@ -182,7 +182,7 @@ static const bool kInlineImages = true; BGopherRequest::BGopherRequest(const BUrl& url, BUrlProtocolListener* listener, BUrlContext* context) : - BUrlRequest(url, listener, context, "BUrlProtocol.Gopher", "gopher"), + BNetworkRequest(url, listener, context, "BUrlProtocol.Gopher", "gopher"), fItemType(GOPHER_TYPE_NONE), fPosition(0), fResult() @@ -236,7 +236,7 @@ BGopherRequest::_ProtocolLoop() if (fSocket == NULL) return B_NO_MEMORY; - if (!_ResolveHostName()) { + if (!_ResolveHostName(70)) { _EmitDebug(B_URL_PROTOCOL_DEBUG_ERROR, "Unable to resolve hostname (%s), aborting.", 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 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& BGopherRequest::_HTMLEscapeString(BString &str) { diff --git a/src/kits/network/libnetapi/HttpRequest.cpp b/src/kits/network/libnetapi/HttpRequest.cpp index 7f880036cd..e45614552b 100644 --- a/src/kits/network/libnetapi/HttpRequest.cpp +++ b/src/kits/network/libnetapi/HttpRequest.cpp @@ -30,11 +30,11 @@ static const int32 kHttpBufferSize = 4096; + BHttpRequest::BHttpRequest(const BUrl& url, bool ssl, const char* protocolName, BUrlProtocolListener* listener, BUrlContext* context) : - BUrlRequest(url, listener, context, "BUrlProtocol.HTTP", protocolName), - fSocket(NULL), + BNetworkRequest(url, listener, context, "BUrlProtocol.HTTP", protocolName), fSSL(ssl), fRequestMethod(B_HTTP_GET), fHttpVersion(B_HTTP_11), @@ -58,9 +58,8 @@ BHttpRequest::BHttpRequest(const BUrl& url, bool ssl, const char* protocolName, 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"), - fSocket(NULL), fSSL(other.fSSL), fRequestMethod(other.fRequestMethod), fHttpVersion(other.fHttpVersion), @@ -320,7 +319,7 @@ BHttpRequest::_ProtocolLoop() fHeaders.Clear(); _ResultHeaders().Clear(); - if (!_ResolveHostName()) { + if (!_ResolveHostName(fSSL ? 443 : 80)) { _EmitDebug(B_URL_PROTOCOL_DEBUG_ERROR, "Unable to resolve hostname (%s), aborting.", 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 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 BHttpRequest::_ParseStatus() { diff --git a/src/kits/network/libnetapi/Jamfile b/src/kits/network/libnetapi/Jamfile index fb8da38eb9..9be8f6d7e7 100644 --- a/src/kits/network/libnetapi/Jamfile +++ b/src/kits/network/libnetapi/Jamfile @@ -77,6 +77,7 @@ for architectureObject in [ MultiArchSubDirSetup ] { $(md5Sources) + NetworkRequest.cpp Url.cpp UrlContext.cpp UrlProtocolAsynchronousListener.cpp diff --git a/src/kits/network/libnetapi/NetworkRequest.cpp b/src/kits/network/libnetapi/NetworkRequest.cpp new file mode 100644 index 0000000000..3c7a6fd323 --- /dev/null +++ b/src/kits/network/libnetapi/NetworkRequest.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 + + +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; +} + +