[haiku-commits] haiku: hrev46478 - src/kits/network/libnetapi

  • From: pulkomandy@xxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 3 Dec 2013 16:46:14 +0100 (CET)

hrev46478 adds 2 changesets to branch 'master'
old head: 2031159e73cc6506c6a60f4caec806b852a69e20
new head: f36e1414b745380a50d9d8db9c20dc8721636810
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=f36e141+%5E2031159

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

dc6d2ef: HttpRequest: simplify and optimize receiving loop
  
  * Do not start with a ridiculously small buffer for socket reads.
  Sockets return data they have available, instead of trying to fill as
  much of the buffer as possible. In some cases a single Ethernet frame
  can hold a complete request.
  * Remove some looping and try parsing all the request in sequence each
  time we receive some bytes.
  * Avoid reallocating a temporary buffer each time we read some data from
  the socket. Instead, allocate it once, and grow it as needed. Since
  servers usually send chunks of equal size, we should get away with one
  reallocation on the first chunk.

f36e141: Cookie Jar: allow setting cookies on "file" URLs.
  
  * These are shared with HTTP cookies set for localhost. We probably want
  to split them apart later on, so cookies should store and check the
  protocol, additionally to the path and domain.
  * Fixes #10195.

                             [ Adrien Destugues <pulkomandy@xxxxxxxxxxxxx> ]

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

3 files changed, 49 insertions(+), 20 deletions(-)
src/kits/network/libnetapi/HttpRequest.cpp      | 41 +++++++++++++--------
src/kits/network/libnetapi/NetworkCookie.cpp    | 20 +++++++++-
src/kits/network/libnetapi/NetworkCookieJar.cpp |  8 +++-

############################################################################

Commit:      dc6d2ef6642035671a23b09b61f41a938aaeac61
URL:         http://cgit.haiku-os.org/haiku/commit/?id=dc6d2ef
Author:      Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
Date:        Tue Nov 26 10:28:30 2013 UTC

HttpRequest: simplify and optimize receiving loop

* Do not start with a ridiculously small buffer for socket reads.
Sockets return data they have available, instead of trying to fill as
much of the buffer as possible. In some cases a single Ethernet frame
can hold a complete request.
* Remove some looping and try parsing all the request in sequence each
time we receive some bytes.
* Avoid reallocating a temporary buffer each time we read some data from
the socket. Instead, allocate it once, and grow it as needed. Since
servers usually send chunks of equal size, we should get away with one
reallocation on the first chunk.

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

diff --git a/src/kits/network/libnetapi/HttpRequest.cpp 
b/src/kits/network/libnetapi/HttpRequest.cpp
index 3460b0f..d17d340 100644
--- a/src/kits/network/libnetapi/HttpRequest.cpp
+++ b/src/kits/network/libnetapi/HttpRequest.cpp
@@ -463,6 +463,7 @@ BHttpRequest::_MakeRequest()
                                        it.MultipartHeader().Length());
 
                                switch (currentField->Type()) {
+                                       default:
                                        case B_HTTPFORM_UNKNOWN:
                                                ASSERT(0);
                                                break;
@@ -486,9 +487,9 @@ BHttpRequest::_MakeRequest()
                                                                readSize = 
upFile.Read(readBuffer,
                                                                        
sizeof(readBuffer));
                                                        }
-                                               }
-                                               break;
 
+                                                       break;
+                                               }
                                        case B_HTTPFORM_BUFFER:
                                                
fSocket->Write(currentField->Buffer(),
                                                        
currentField->BufferSize());
@@ -539,18 +540,18 @@ BHttpRequest::_MakeRequest()
        bool parseEnd = false;
        bool readByChunks = false;
        bool readError = false;
-       int32 receiveBufferSize = 32;
        ssize_t bytesRead = 0;
        ssize_t bytesReceived = 0;
        ssize_t bytesTotal = 0;
-       char* inputTempBuffer = NULL;
+       char* inputTempBuffer = new char[kHttpBufferSize];
+       ssize_t inputTempSize = kHttpBufferSize;
        ssize_t chunkSize = -1;
 
        while (!fQuit && !(receiveEnd && parseEnd)) {
                if (!receiveEnd) {
                        fSocket->WaitForReadable();
-                       BNetBuffer chunk(receiveBufferSize);
-                       bytesRead = fSocket->Read(chunk.Data(), 
receiveBufferSize);
+                       BNetBuffer chunk(kHttpBufferSize);
+                       bytesRead = fSocket->Read(chunk.Data(), 
kHttpBufferSize);
 
                        if (bytesRead < 0) {
                                readError = true;
@@ -568,11 +569,12 @@ BHttpRequest::_MakeRequest()
                        //! ProtocolHook:ResponseStarted
                        if (fRequestStatus >= kRequestStatusReceived && 
fListener != NULL)
                                fListener->ResponseStarted(this);
-               } else if (fRequestStatus < kRequestHeadersReceived) {
+               }
+
+               if (fRequestStatus < kRequestHeadersReceived) {
                        _ParseHeaders();
 
                        if (fRequestStatus >= kRequestHeadersReceived) {
-                               receiveBufferSize = kHttpBufferSize;
                                _ResultHeaders() = fHeaders;
 
                                //! ProtocolHook:HeadersReceived
@@ -598,7 +600,9 @@ BHttpRequest::_MakeRequest()
                                else
                                        bytesTotal = 0;
                        }
-               } else {
+               }
+
+               if (fRequestStatus >= kRequestHeadersReceived) {
                        // If Transfer-Encoding is chunked, we should read a 
complete
                        // chunk in buffer before handling it
                        if (readByChunks) {
@@ -606,20 +610,23 @@ BHttpRequest::_MakeRequest()
                                        if ((ssize_t)fInputBuffer.Size() >= 
chunkSize + 2) {
                                                        // 2 more bytes to 
handle the closing CR+LF
                                                bytesRead = chunkSize;
-                                               inputTempBuffer = new 
char[chunkSize + 2];
+                                               if (inputTempSize < chunkSize + 
2)
+                                               {
+                                                       delete[] 
inputTempBuffer;
+                                                       inputTempSize = 
chunkSize + 2;
+                                                       inputTempBuffer = new 
char[inputTempSize];
+                                               }
                                                
fInputBuffer.RemoveData(inputTempBuffer,
                                                        chunkSize + 2);
                                                chunkSize = -1;
                                        } else {
                                                // Not enough data, try again 
later
                                                bytesRead = -1;
-                                               inputTempBuffer = NULL;
                                        }
                                } else {
                                        BString chunkHeader;
                                        if (_GetLine(chunkHeader) == B_ERROR) {
                                                chunkSize = -1;
-                                               inputTempBuffer = NULL;
                                                bytesRead = -1;
                                        } else {
                                                // Format of a chunk header:
@@ -639,7 +646,6 @@ BHttpRequest::_MakeRequest()
                                                        fRequestStatus = 
kRequestContentReceived;
 
                                                bytesRead = -1;
-                                               inputTempBuffer = NULL;
                                        }
                                }
 
@@ -651,7 +657,11 @@ BHttpRequest::_MakeRequest()
                                bytesRead = fInputBuffer.Size();
 
                                if (bytesRead > 0) {
-                                       inputTempBuffer = new char[bytesRead];
+                                       if (inputTempSize < bytesRead) {
+                                               inputTempSize = bytesRead;
+                                               delete[] inputTempBuffer;
+                                               inputTempBuffer = new 
char[bytesRead];
+                                       }
                                        
fInputBuffer.RemoveData(inputTempBuffer, bytesRead);
                                }
                        }
@@ -667,8 +677,6 @@ BHttpRequest::_MakeRequest()
 
                                if (bytesTotal > 0 && bytesReceived >= 
bytesTotal)
                                        receiveEnd = true;
-
-                               delete[] inputTempBuffer;
                        }
                }
 
@@ -676,6 +684,7 @@ BHttpRequest::_MakeRequest()
        }
 
        fSocket->Disconnect();
+       delete[] inputTempBuffer;
 
        if (readError)
                return B_PROT_READ_FAILED;

############################################################################

Revision:    hrev46478
Commit:      f36e1414b745380a50d9d8db9c20dc8721636810
URL:         http://cgit.haiku-os.org/haiku/commit/?id=f36e141
Author:      Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
Date:        Tue Dec  3 15:42:54 2013 UTC

Ticket:      https://dev.haiku-os.org/ticket/10195

Cookie Jar: allow setting cookies on "file" URLs.

* These are shared with HTTP cookies set for localhost. We probably want
to split them apart later on, so cookies should store and check the
protocol, additionally to the path and domain.
* Fixes #10195.

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

diff --git a/src/kits/network/libnetapi/NetworkCookie.cpp 
b/src/kits/network/libnetapi/NetworkCookie.cpp
index bb85614..a9f3a33 100644
--- a/src/kits/network/libnetapi/NetworkCookie.cpp
+++ b/src/kits/network/libnetapi/NetworkCookie.cpp
@@ -38,6 +38,13 @@ BNetworkCookie::BNetworkCookie(const char* name, const char* 
value,
        fValue = value;
 
        SetDomain(url.Host());
+
+    if(url.Protocol() == "file" && url.Host().Length() == 0)
+    {
+        SetDomain("localhost");
+            // make sure cookies set from a file:// URL are stored somewhere.
+    }
+
        SetPath(_DefaultPathForUrl(url));
 }
 
@@ -93,6 +100,13 @@ BNetworkCookie::ParseCookieString(const BString& string, 
const BUrl& url)
        SetPath(_DefaultPathForUrl(url));
        SetDomain(url.Host());
        fHostOnly = true;
+    if(url.Protocol() == "file" && url.Host().Length() == 0)
+    {
+        fDomain = "localhost";
+            // make sure cookies set from a file:// URL are stored somewhere.
+            // not going through SetDomain as it requires at least one '.'
+            // in the domain (to avoid setting cookies on TLDs).
+    }
 
        BString name;
        BString value;
@@ -166,13 +180,12 @@ BNetworkCookie::ParseCookieString(const BString& string, 
const BUrl& url)
                }
        }
 
-       if (!IsValidForDomain(url.Host())) {
+       if (!IsValidForUrl(url)) {
                // Invalidate the cookie.
                _Reset();
                return B_NOT_ALLOWED;
        }
 
-
        return result;
 }
 
@@ -423,6 +436,9 @@ BNetworkCookie::IsValidForUrl(const BUrl& url) const
        if (Secure() && url.Protocol() != "https")
                return false;
 
+    if (url.Protocol() == "file")
+        return Domain() == "localhost" && IsValidForPath(url.Path());
+
        return IsValidForDomain(url.Host()) && IsValidForPath(url.Path());
 }
 
diff --git a/src/kits/network/libnetapi/NetworkCookieJar.cpp 
b/src/kits/network/libnetapi/NetworkCookieJar.cpp
index ae97f37..d4a9fd3 100644
--- a/src/kits/network/libnetapi/NetworkCookieJar.cpp
+++ b/src/kits/network/libnetapi/NetworkCookieJar.cpp
@@ -591,8 +591,12 @@ BNetworkCookieJar::UrlIterator::UrlIterator(const 
BNetworkCookieJar* cookieJar,
 {
        BString domain = url.Host();
 
-       if (!domain.Length())
-               return;
+       if (!domain.Length()) {
+        if (url.Protocol() == "file")
+            domain = "localhost";
+        else
+                   return;
+    }
 
        fIterator = new(std::nothrow) PrivateIterator(
                fCookieJar->fCookieHashMap->fHashMap.GetIterator());


Other related posts: