[haiku-commits] haiku: hrev47865 - src/kits/network/libnetapi src/tests/kits/net/service headers/os/net

  • From: pulkomandy@xxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 15 Sep 2014 14:29:11 +0200 (CEST)

hrev47865 adds 1 changeset to branch 'master'
old head: cee64ce5074d04f8517bc086dccb3759d1454d91
new head: c98378e51ae02d8ad6e833c7eb8223a10cbd46f5
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=c98378e+%5Ecee64ce

----------------------------------------------------------------------------

c98378e: Add HTTP proxy support.
  
  * Move default context management to BUrlRequest since some code
  (including the testsuite) bypass the BUrlProtocolRoster.
  * Introduce proxy host and port in BUrlContext
  * Have BHttpRequest use the proxy when making requests

                                 [ Adrien Destugues <pulkomandy@xxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev47865
Commit:      c98378e51ae02d8ad6e833c7eb8223a10cbd46f5
URL:         http://cgit.haiku-os.org/haiku/commit/?id=c98378e
Author:      Adrien Destugues <pulkomandy@xxxxxxxxx>
Date:        Mon Sep 15 12:24:37 2014 UTC

----------------------------------------------------------------------------

10 files changed, 124 insertions(+), 32 deletions(-)
headers/os/net/NetworkRequest.h                  |  2 +-
headers/os/net/UrlContext.h                      | 12 ++++-
src/kits/network/libnetapi/GopherRequest.cpp     |  2 +-
src/kits/network/libnetapi/HttpRequest.cpp       | 26 ++++++++--
src/kits/network/libnetapi/NetworkRequest.cpp    |  7 +--
src/kits/network/libnetapi/UrlContext.cpp        | 37 ++++++++++++--
src/kits/network/libnetapi/UrlProtocolRoster.cpp | 12 -----
src/kits/network/libnetapi/UrlRequest.cpp        |  5 ++
src/tests/kits/net/service/HttpTest.cpp          | 52 +++++++++++++++++---
src/tests/kits/net/service/HttpTest.h            |  1 +

----------------------------------------------------------------------------

diff --git a/headers/os/net/NetworkRequest.h b/headers/os/net/NetworkRequest.h
index 7158dab..1d139c7 100644
--- a/headers/os/net/NetworkRequest.h
+++ b/headers/os/net/NetworkRequest.h
@@ -26,7 +26,7 @@ public:
        virtual status_t                        Stop();
 
 protected:
-                       bool                            
_ResolveHostName(uint16_t port);
+                       bool                            
_ResolveHostName(BString host, uint16_t port);
 
                        void                            _ProtocolSetup();
                        status_t                        _GetLine(BString& 
destString);
diff --git a/headers/os/net/UrlContext.h b/headers/os/net/UrlContext.h
index eed0813..d561ef5 100644
--- a/headers/os/net/UrlContext.h
+++ b/headers/os/net/UrlContext.h
@@ -2,6 +2,8 @@
  * Copyright 2010-2014 Haiku Inc. All rights reserved.
  * Distributed under the terms of the MIT License.
  */
+
+
 #ifndef _B_URL_CONTEXT_H_
 #define _B_URL_CONTEXT_H_
 
@@ -27,16 +29,24 @@ public:
                                                                        const 
BNetworkCookieJar& cookieJar);
                        void                            AddAuthentication(const 
BUrl& url,
                                                                        const 
BHttpAuthentication& authentication);
-                                                                               
        
+                       void                            SetProxy(BString host, 
uint16 port);
+
        // Context accessors
                        BNetworkCookieJar&      GetCookieJar();
                        BHttpAuthentication& GetAuthentication(const BUrl& url);
+                       bool                            UseProxy();
+                       BString                         GetProxyHost();
+                       uint16                          GetProxyPort();
 
 private:
                        BNetworkCookieJar       fCookieJar;
                        typedef 
BPrivate::SynchronizedHashMap<BPrivate::HashString,
                                BHttpAuthentication*> BHttpAuthenticationMap;
                        BHttpAuthenticationMap* fAuthenticationMap;
+
+                       BString                         fProxyHost;
+                       uint16                          fProxyPort;
 };
 
+
 #endif // _B_URL_CONTEXT_H_
diff --git a/src/kits/network/libnetapi/GopherRequest.cpp 
b/src/kits/network/libnetapi/GopherRequest.cpp
index f78cda7..ac3a127 100644
--- a/src/kits/network/libnetapi/GopherRequest.cpp
+++ b/src/kits/network/libnetapi/GopherRequest.cpp
@@ -235,7 +235,7 @@ BGopherRequest::_ProtocolLoop()
        if (fSocket == NULL)
                return B_NO_MEMORY;
 
-       if (!_ResolveHostName(70)) {
+       if (!_ResolveHostName(fUrl.Host(), fUrl.HasPort() ? fUrl.Port() : 70)) {
                _EmitDebug(B_URL_PROTOCOL_DEBUG_ERROR,
                        "Unable to resolve hostname (%s), aborting.",
                                fUrl.Host().String());
diff --git a/src/kits/network/libnetapi/HttpRequest.cpp 
b/src/kits/network/libnetapi/HttpRequest.cpp
index 8e065c0..a017a21 100644
--- a/src/kits/network/libnetapi/HttpRequest.cpp
+++ b/src/kits/network/libnetapi/HttpRequest.cpp
@@ -319,7 +319,18 @@ BHttpRequest::_ProtocolLoop()
                fHeaders.Clear();
                _ResultHeaders().Clear();
 
-               if (!_ResolveHostName(fSSL ? 443 : 80)) {
+               BString host = fUrl.Host();
+               int port = fSSL ? 443 : 80;
+
+               if (fUrl.HasPort())
+                       port = fUrl.Port();
+
+               if (fContext->UseProxy()) {
+                       host = fContext->GetProxyHost();
+                       port = fContext->GetProxyPort();
+               }
+
+               if (!_ResolveHostName(host, port)) {
                        _EmitDebug(B_URL_PROTOCOL_DEBUG_ERROR,
                                "Unable to resolve hostname (%s), aborting.",
                                        fUrl.Host().String());
@@ -733,11 +744,20 @@ void
 BHttpRequest::_SendRequest()
 {
        BString request(fRequestMethod);
+       request << ' ';
+
+       if (fContext->UseProxy()) {
+               // When there is a proxy, the request must include the host and 
port so
+               // the proxy knows where to send the request.
+               request << Url().Protocol() << "://" << Url().Host();
+               if (Url().HasPort())
+                       request << ':' << Url().Port();
+       }
 
        if (Url().HasPath())
-               request << ' ' << Url().Path();
+               request << Url().Path();
        else
-               request << " /";
+               request << '/';
 
        if (Url().HasRequest())
                request << '?' << Url().Request();
diff --git a/src/kits/network/libnetapi/NetworkRequest.cpp 
b/src/kits/network/libnetapi/NetworkRequest.cpp
index 43e64b0..779bd9c 100644
--- a/src/kits/network/libnetapi/NetworkRequest.cpp
+++ b/src/kits/network/libnetapi/NetworkRequest.cpp
@@ -36,17 +36,14 @@ BNetworkRequest::Stop()
 
 
 bool
-BNetworkRequest::_ResolveHostName(uint16_t port)
+BNetworkRequest::_ResolveHostName(BString host, 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);
+       fRemoteAddr = BNetworkAddress(AF_INET, host, port);
 
        if (fRemoteAddr.InitCheck() != B_OK)
                return false;
diff --git a/src/kits/network/libnetapi/UrlContext.cpp 
b/src/kits/network/libnetapi/UrlContext.cpp
index 3818adf..6a9f6e1 100644
--- a/src/kits/network/libnetapi/UrlContext.cpp
+++ b/src/kits/network/libnetapi/UrlContext.cpp
@@ -18,7 +18,9 @@
 BUrlContext::BUrlContext()
        :
        fCookieJar(),
-       fAuthenticationMap(NULL)
+       fAuthenticationMap(NULL),
+       fProxyHost(),
+       fProxyPort(0)
 {
        fAuthenticationMap = new(std::nothrow) BHttpAuthenticationMap();
 
@@ -31,8 +33,8 @@ BUrlContext::BUrlContext()
 
 BUrlContext::~BUrlContext()
 {
-       BHttpAuthenticationMap::Iterator iterator =
-               fAuthenticationMap->GetIterator();
+       BHttpAuthenticationMap::Iterator iterator
+               = fAuthenticationMap->GetIterator();
        while (iterator.HasNext())
                delete *iterator.NextValue();
 
@@ -74,6 +76,14 @@ BUrlContext::AddAuthentication(const BUrl& url,
 }
 
 
+void
+BUrlContext::SetProxy(BString host, uint16 port)
+{
+       fProxyHost = host;
+       fProxyPort = port;
+}
+
+
 // #pragma mark Context accessors
 
 
@@ -102,3 +112,24 @@ BUrlContext::GetAuthentication(const BUrl& url)
 
        return *authentication;
 }
+
+
+bool
+BUrlContext::UseProxy()
+{
+       return !fProxyHost.IsEmpty();
+}
+
+
+BString
+BUrlContext::GetProxyHost()
+{
+       return fProxyHost;
+}
+
+
+uint16
+BUrlContext::GetProxyPort()
+{
+       return fProxyPort;
+}
diff --git a/src/kits/network/libnetapi/UrlProtocolRoster.cpp 
b/src/kits/network/libnetapi/UrlProtocolRoster.cpp
index 54e27e2..1284bee 100644
--- a/src/kits/network/libnetapi/UrlProtocolRoster.cpp
+++ b/src/kits/network/libnetapi/UrlProtocolRoster.cpp
@@ -19,22 +19,10 @@
 #include <UrlRequest.h>
 
 
-static BReference<BUrlContext> gDefaultContext = new(std::nothrow) 
BUrlContext();
-
-
 /* static */ BUrlRequest*
 BUrlProtocolRoster::MakeRequest(const BUrl& url,
        BUrlProtocolListener* listener, BUrlContext* context)
 {
-       if (context == NULL)
-               context = gDefaultContext;
-
-       if (context == NULL) {
-               // Allocation of the gDefaultContext failed. Don't allow 
creating
-               // requests without a context.
-               return NULL;
-       }
-
        // TODO: instanciate the correct BUrlProtocol using add-on interface
        if (url.Protocol() == "http") {
                return new(std::nothrow) BHttpRequest(url, false, "HTTP", 
listener,
diff --git a/src/kits/network/libnetapi/UrlRequest.cpp 
b/src/kits/network/libnetapi/UrlRequest.cpp
index 35bb8a5..c1e2042 100644
--- a/src/kits/network/libnetapi/UrlRequest.cpp
+++ b/src/kits/network/libnetapi/UrlRequest.cpp
@@ -12,6 +12,9 @@
 #include <stdio.h>
 
 
+static BReference<BUrlContext> gDefaultContext = new(std::nothrow) 
BUrlContext();
+
+
 BUrlRequest::BUrlRequest(const BUrl& url, BUrlProtocolListener* listener,
        BUrlContext* context, const char* threadName, const char* protocolName)
        :
@@ -25,6 +28,8 @@ BUrlRequest::BUrlRequest(const BUrl& url, 
BUrlProtocolListener* listener,
        fThreadName(threadName),
        fProtocol(protocolName)
 {
+       if (fContext == NULL)
+               fContext = gDefaultContext;
 }
 
 
diff --git a/src/tests/kits/net/service/HttpTest.cpp 
b/src/tests/kits/net/service/HttpTest.cpp
index d2b0a2c..dd3240f 100644
--- a/src/tests/kits/net/service/HttpTest.cpp
+++ b/src/tests/kits/net/service/HttpTest.cpp
@@ -45,7 +45,7 @@ HttpTest::GetTest()
 
        CPPUNIT_ASSERT(t.Run());
 
-       while(t.IsRunning())
+       while (t.IsRunning())
                snooze(1000);
 
        CPPUNIT_ASSERT_EQUAL(B_OK, t.Status());
@@ -59,7 +59,44 @@ HttpTest::GetTest()
                // Fixed size as we know the response format.
        CPPUNIT_ASSERT(!c->GetCookieJar().GetIterator().HasNext());
                // This page should not set cookies
-       
+
+       c->ReleaseReference();
+}
+
+
+void
+HttpTest::ProxyTest()
+{
+       BUrl testUrl(fBaseUrl, "/user-agent");
+
+       BUrlContext* c = new BUrlContext();
+       c->AcquireReference();
+       c->SetProxy("120.203.214.182", 83);
+
+       BHttpRequest t(testUrl);
+       t.SetContext(c);
+
+       BUrlProtocolListener l;
+       t.SetListener(&l);
+
+       CPPUNIT_ASSERT(t.Run());
+
+       while (t.IsRunning())
+               snooze(1000);
+
+       CPPUNIT_ASSERT_EQUAL(B_OK, t.Status());
+
+       const BHttpResult& r = dynamic_cast<const BHttpResult&>(t.Result());
+
+printf("%s\n", r.StatusText().String());
+
+       CPPUNIT_ASSERT_EQUAL(200, r.StatusCode());
+       CPPUNIT_ASSERT_EQUAL(BString("OK"), r.StatusText());
+       CPPUNIT_ASSERT_EQUAL(42, r.Length());
+               // Fixed size as we know the response format.
+       CPPUNIT_ASSERT(!c->GetCookieJar().GetIterator().HasNext());
+               // This page should not set cookies
+
        c->ReleaseReference();
 }
 
@@ -93,7 +130,7 @@ HttpTest::PortTest()
 
        CPPUNIT_ASSERT(t.Run());
 
-       while(t.IsRunning())
+       while (t.IsRunning())
                snooze(1000);
 
        CPPUNIT_ASSERT_EQUAL(B_OK, t.Status());
@@ -123,7 +160,7 @@ HttpTest::UploadTest()
 
        CPPUNIT_ASSERT(t.Run());
 
-       while(t.IsRunning())
+       while (t.IsRunning())
                snooze(1000);
 
        CPPUNIT_ASSERT_EQUAL(B_OK, t.Status());
@@ -131,7 +168,7 @@ HttpTest::UploadTest()
        const BHttpResult& r = dynamic_cast<const BHttpResult&>(t.Result());
        CPPUNIT_ASSERT_EQUAL(200, r.StatusCode());
        CPPUNIT_ASSERT_EQUAL(BString("OK"), r.StatusText());
-       CPPUNIT_ASSERT_EQUAL(474, r.Length());
+       CPPUNIT_ASSERT_EQUAL(466, r.Length());
                // Fixed size as we know the response format.
 }
 
@@ -165,7 +202,7 @@ HttpTest::_AuthTest(BUrl& testUrl)
 
        CPPUNIT_ASSERT(t.Run());
 
-       while(t.IsRunning())
+       while (t.IsRunning())
                snooze(1000);
 
        CPPUNIT_ASSERT_EQUAL(B_OK, t.Status());
@@ -216,6 +253,9 @@ HttpTest::AddTests(BTestSuite& parent)
                suite.addTest(new CppUnit::TestCaller<HttpTest>(
                        "HttpTest::PortTest", &HttpTest::PortTest));
 
+               suite.addTest(new 
CppUnit::TestCaller<HttpTest>("HttpTest::ProxyTest",
+                       &HttpTest::ProxyTest));
+
                parent.addTest("HttpTest", &suite);
        }
 
diff --git a/src/tests/kits/net/service/HttpTest.h 
b/src/tests/kits/net/service/HttpTest.h
index c8abf55..7401920 100644
--- a/src/tests/kits/net/service/HttpTest.h
+++ b/src/tests/kits/net/service/HttpTest.h
@@ -24,6 +24,7 @@ public:
                                                                void    
UploadTest();
                                                                void    
AuthBasicTest();
                                                                void    
AuthDigestTest();
+                                                               void    
ProxyTest();
 
        static                                          void    
AddTests(BTestSuite& suite);
 


Other related posts: