hrev47621 adds 2 changesets to branch 'master' old head: fedec7b31f35176eea75a996c7d33dda2efc3b81 new head: 89b4e98a8fbef003d06732181a384bda84c969c8 overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=89b4e98+%5Efedec7b ---------------------------------------------------------------------------- 2f9b187: Factor out a BNetworkRequest * Shares common behavior between the Gopher and HTTP request handlers. * Most of this can be used when implemeting other protocols. 89b4e98: Move signal hack to BNetworkRequest * This is used to unlock sockets when a read is pending after a close * It is not needed on requests that don't use a socket. [ Adrien Destugues <pulkomandy@xxxxxxxxxxxxx> ] ---------------------------------------------------------------------------- 9 files changed, 173 insertions(+), 174 deletions(-) headers/os/net/GopherRequest.h | 13 +-- headers/os/net/HttpRequest.h | 15 +-- headers/os/net/NetworkRequest.h | 42 ++++++++ headers/os/net/UrlRequest.h | 1 + src/kits/network/libnetapi/GopherRequest.cpp | 66 +------------ src/kits/network/libnetapi/HttpRequest.cpp | 71 +------------ src/kits/network/libnetapi/Jamfile | 1 + src/kits/network/libnetapi/NetworkRequest.cpp | 115 ++++++++++++++++++++++ src/kits/network/libnetapi/UrlRequest.cpp | 23 +---- ############################################################################ Commit: 2f9b1874977669807fe200c7d3595d86a1984454 URL: http://cgit.haiku-os.org/haiku/commit/?id=2f9b187 Author: Adrien Destugues <pulkomandy@xxxxxxxxxxxxx> Date: Mon Aug 4 13:59:53 2014 UTC Factor out a BNetworkRequest * Shares common behavior between the Gopher and HTTP request handlers. * Most of this can be used when implemeting other protocols. ---------------------------------------------------------------------------- diff --git a/headers/os/net/GopherRequest.h b/headers/os/net/GopherRequest.h index 9173349..9d1c692 100644 --- a/headers/os/net/GopherRequest.h +++ b/headers/os/net/GopherRequest.h @@ -8,15 +8,10 @@ #include <deque> -#include <NetBuffer.h> -#include <NetworkAddress.h> -#include <UrlRequest.h> +#include <NetworkRequest.h> -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 080805d..6ca63eb 100644 --- a/headers/os/net/HttpRequest.h +++ b/headers/os/net/HttpRequest.h @@ -11,15 +11,11 @@ #include <HttpForm.h> #include <HttpHeaders.h> #include <HttpResult.h> -#include <NetBuffer.h> #include <NetworkAddress.h> -#include <UrlRequest.h> +#include <NetworkRequest.h> -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 0000000..8684f24 --- /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 <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 diff --git a/src/kits/network/libnetapi/GopherRequest.cpp b/src/kits/network/libnetapi/GopherRequest.cpp index 951a9cc..9d0f15b 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 7f88003..e456145 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 fb8da38..9be8f6d 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 0000000..3c7a6fd --- /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@xxxxxxxxx + * Niels Sascha Reedijk, niels.reedijk@xxxxxxxxx + * Adrien Destugues, pulkomandy@xxxxxxxxxxxxx + */ + + +#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; +} + + ############################################################################ Revision: hrev47621 Commit: 89b4e98a8fbef003d06732181a384bda84c969c8 URL: http://cgit.haiku-os.org/haiku/commit/?id=89b4e98 Author: Adrien Destugues <pulkomandy@xxxxxxxxxxxxx> Date: Mon Aug 4 14:25:48 2014 UTC Move signal hack to BNetworkRequest * This is used to unlock sockets when a read is pending after a close * It is not needed on requests that don't use a socket. ---------------------------------------------------------------------------- diff --git a/headers/os/net/NetworkRequest.h b/headers/os/net/NetworkRequest.h index 8684f24..7158dab 100644 --- a/headers/os/net/NetworkRequest.h +++ b/headers/os/net/NetworkRequest.h @@ -22,9 +22,13 @@ public: BUrlContext* context, const char* threadName, const char* protocolName); + + virtual status_t Stop(); + protected: bool _ResolveHostName(uint16_t port); + void _ProtocolSetup(); status_t _GetLine(BString& destString); protected: diff --git a/headers/os/net/UrlRequest.h b/headers/os/net/UrlRequest.h index 206b212..64a0e7d 100644 --- a/headers/os/net/UrlRequest.h +++ b/headers/os/net/UrlRequest.h @@ -48,6 +48,7 @@ public: protected: static int32 _ThreadEntry(void* arg); + virtual void _ProtocolSetup() {}; virtual status_t _ProtocolLoop() = 0; virtual void _EmitDebug(BUrlProtocolDebugMessage type, const char* format, ...); diff --git a/src/kits/network/libnetapi/GopherRequest.cpp b/src/kits/network/libnetapi/GopherRequest.cpp index 9d0f15b..3092adf 100644 --- a/src/kits/network/libnetapi/GopherRequest.cpp +++ b/src/kits/network/libnetapi/GopherRequest.cpp @@ -219,7 +219,7 @@ BGopherRequest::Stop() fSocket->Disconnect(); // Unlock any pending connect, read or write operation. } - return BUrlRequest::Stop(); + return BNetworkRequest::Stop(); } diff --git a/src/kits/network/libnetapi/HttpRequest.cpp b/src/kits/network/libnetapi/HttpRequest.cpp index e456145..8e065c0 100644 --- a/src/kits/network/libnetapi/HttpRequest.cpp +++ b/src/kits/network/libnetapi/HttpRequest.cpp @@ -278,7 +278,7 @@ BHttpRequest::Stop() fSocket->Disconnect(); // Unlock any pending connect, read or write operation. } - return BUrlRequest::Stop(); + return BNetworkRequest::Stop(); } diff --git a/src/kits/network/libnetapi/NetworkRequest.cpp b/src/kits/network/libnetapi/NetworkRequest.cpp index 3c7a6fd..43e64b0 100644 --- a/src/kits/network/libnetapi/NetworkRequest.cpp +++ b/src/kits/network/libnetapi/NetworkRequest.cpp @@ -21,6 +21,20 @@ BNetworkRequest::BNetworkRequest(const BUrl& url, BUrlProtocolListener* listener } +status_t +BNetworkRequest::Stop() +{ + status_t threadStatus = BUrlRequest::Stop(); + + if (threadStatus != B_OK) + return threadStatus; + + send_signal(fThreadId, SIGUSR1); // unblock blocking syscalls. + wait_for_thread(fThreadId, &threadStatus); + return threadStatus; +} + + bool BNetworkRequest::_ResolveHostName(uint16_t port) { @@ -48,6 +62,27 @@ BNetworkRequest::_ResolveHostName(uint16_t port) } +static void +empty(int) +{ +} + + +void +BNetworkRequest::_ProtocolSetup() +{ + // Setup an (empty) signal handler so we can be stopped by a signal, + // without the whole process being killed. + // TODO make connect() properly unlock when close() is called on the + // socket, and remove this. + struct sigaction action; + action.sa_handler = empty; + action.sa_mask = 0; + action.sa_flags = 0; + sigaction(SIGUSR1, &action, NULL); +} + + status_t BNetworkRequest::_GetLine(BString& destString) { diff --git a/src/kits/network/libnetapi/UrlRequest.cpp b/src/kits/network/libnetapi/UrlRequest.cpp index 7e46779..51dc7a0 100644 --- a/src/kits/network/libnetapi/UrlRequest.cpp +++ b/src/kits/network/libnetapi/UrlRequest.cpp @@ -87,12 +87,8 @@ BUrlRequest::Stop() if (!fRunning) return B_ERROR; - status_t threadStatus = B_OK; fQuit = true; - - send_signal(fThreadId, SIGUSR1); // unblock blocking syscalls. - wait_for_thread(fThreadId, &threadStatus); - return threadStatus; + return B_OK; } @@ -184,27 +180,12 @@ BUrlRequest::Status() const // #pragma mark Thread management -static void -empty(int) -{ -} - - /*static*/ int32 BUrlRequest::_ThreadEntry(void* arg) { - // Setup an (empty) signal handler so we can be stopped by a signal, - // without the whole process being killed. - // TODO make connect() properly unlock when close() is called on the - // socket, and remove this. - struct sigaction action; - action.sa_handler = empty; - action.sa_mask = 0; - action.sa_flags = 0; - sigaction(SIGUSR1, &action, NULL); - BUrlRequest* request = reinterpret_cast<BUrlRequest*>(arg); request->fThreadStatus = B_BUSY; + request->_ProtocolSetup(); status_t protocolLoopExitStatus = request->_ProtocolLoop();