[haiku-commits] haiku: hrev50644 - src/kits/network/libnetapi headers/os/net

  • From: pulkomandy@xxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 31 Oct 2016 22:18:00 +0100 (CET)

hrev50644 adds 3 changesets to branch 'master'
old head: af7d48fe5b769f48d37314c10082f5a967ad4d78
new head: ed31589c375022059cda2a96beb6b06f893748da
overview: 
http://cgit.haiku-os.org/haiku/log/?qt=range&q=ed31589c3750+%5Eaf7d48fe5b76

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

a9665fc66a4a: HttpRequest: use data from the input buffer first
  
  The HttpRequest protocol loop is designed using an input buffer storing
  data from the socket. At each loop, we try to parse some of the data,
  and then read more from the socket.
  
  However, in some cases (in particular with chunks, which we parse only
  one at a time in a loop iteration), we may not use all the data from the
  buffer. Eventually, we will be left with an "empty" socket (nothing to
  read from there) but the request not completed because there is still
  data in the input buffer.
  
  In that case, we would hang waiting for a read on the socket, instead of
  processing data from the input buffer.
  
  Change the code to read from the socket only if a loop iteration did not
  manage to read anything from the input buffer. This means the input
  buffer is too small for the next thing to process (it contains less than
  one line of data, for example), and in that case we can safely read from
  the socket without being blocked.
  
  This should fix several cases where the network code was stuck doing
  nothing, including https://my.justenergy.com/ reported in #13010.

ed6d3d88c112: SecureSocket: add code to trace SSL events.
  
  Under a #define TRACE_SSL, should you need it.
  
  Also load error strings when initializing the SSL context, so we get
  human readable errors from SSL (also in the ser reported ones).

ed31589c3750: URL Disaptching/Async listeners: forward debug messages
  
  This makes it possible for the Asynchronous listener to get the
  messages. It can then process them in a more fancy way.
  
  The default implementation will still log the messages to the console
  (if debug is enabled), but it will do so from the Async listener for
  asynchronous requests now. This means they will probably be logged from
  the same thread, and show up in a more readable way.
  
  This also makes it possible to listen to several requests and log them
  in a nice way (in a status window or whatever).

                             [ Adrien Destugues <pulkomandy@xxxxxxxxxxxxx> ]

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

5 files changed, 80 insertions(+), 3 deletions(-)
headers/os/net/UrlProtocolDispatchingListener.h  |  6 ++-
src/kits/network/libnetapi/HttpRequest.cpp       |  5 ++-
src/kits/network/libnetapi/SecureSocket.cpp      | 47 ++++++++++++++++++++
.../UrlProtocolAsynchronousListener.cpp          | 11 +++++
.../libnetapi/UrlProtocolDispatchingListener.cpp | 14 +++++-

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

Commit:      a9665fc66a4a91a7d342a115fd82820ebc231f7d
URL:         http://cgit.haiku-os.org/haiku/commit/?id=a9665fc66a4a
Author:      Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
Date:        Mon Oct 31 21:00:40 2016 UTC

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

HttpRequest: use data from the input buffer first

The HttpRequest protocol loop is designed using an input buffer storing
data from the socket. At each loop, we try to parse some of the data,
and then read more from the socket.

However, in some cases (in particular with chunks, which we parse only
one at a time in a loop iteration), we may not use all the data from the
buffer. Eventually, we will be left with an "empty" socket (nothing to
read from there) but the request not completed because there is still
data in the input buffer.

In that case, we would hang waiting for a read on the socket, instead of
processing data from the input buffer.

Change the code to read from the socket only if a loop iteration did not
manage to read anything from the input buffer. This means the input
buffer is too small for the next thing to process (it contains less than
one line of data, for example), and in that case we can safely read from
the socket without being blocked.

This should fix several cases where the network code was stuck doing
nothing, including https://my.justenergy.com/ reported in #13010.

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

diff --git a/src/kits/network/libnetapi/HttpRequest.cpp 
b/src/kits/network/libnetapi/HttpRequest.cpp
index 57d1dea..d91654a 100644
--- a/src/kits/network/libnetapi/HttpRequest.cpp
+++ b/src/kits/network/libnetapi/HttpRequest.cpp
@@ -570,6 +570,7 @@ BHttpRequest::_MakeRequest()
        ssize_t bytesRead = 0;
        ssize_t bytesReceived = 0;
        ssize_t bytesTotal = 0;
+       size_t previousBufferSize = 0;
        off_t bytesUnpacked = 0;
        char* inputTempBuffer = new(std::nothrow) char[kHttpBufferSize];
        ssize_t inputTempSize = kHttpBufferSize;
@@ -579,7 +580,7 @@ BHttpRequest::_MakeRequest()
        ObjectDeleter<BDataIO> decompressingStreamDeleter;
 
        while (!fQuit && !(receiveEnd && parseEnd)) {
-               if (!receiveEnd) {
+               if ((!receiveEnd) && (fInputBuffer.Size() == 
previousBufferSize)) {
                        fSocket->WaitForReadable();
                        BStackOrHeapArray<char, 4096> chunk(kHttpBufferSize);
                        bytesRead = fSocket->Read(chunk, kHttpBufferSize);
@@ -594,6 +595,8 @@ BHttpRequest::_MakeRequest()
                } else
                        bytesRead = 0;
 
+               previousBufferSize = fInputBuffer.Size();
+
                if (fRequestStatus < kRequestStatusReceived) {
                        _ParseStatus();
 

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

Commit:      ed6d3d88c112c5129a6a6d35306b0d112b244df7
URL:         http://cgit.haiku-os.org/haiku/commit/?id=ed6d3d88c112
Author:      Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
Date:        Mon Oct 31 21:12:50 2016 UTC

SecureSocket: add code to trace SSL events.

Under a #define TRACE_SSL, should you need it.

Also load error strings when initializing the SSL context, so we get
human readable errors from SSL (also in the ser reported ones).

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

diff --git a/src/kits/network/libnetapi/SecureSocket.cpp 
b/src/kits/network/libnetapi/SecureSocket.cpp
index 9ca4f66..7b3cfeb 100644
--- a/src/kits/network/libnetapi/SecureSocket.cpp
+++ b/src/kits/network/libnetapi/SecureSocket.cpp
@@ -179,11 +179,58 @@ BSecureSocket::Private::VerifyCallback(int ok, 
X509_STORE_CTX* ctx)
 }
 
 
+#if TRACE_SSL
+static void apps_ssl_info_callback(const SSL *s, int where, int ret)
+{
+       const char *str;
+       int w;
+
+       w=where& ~SSL_ST_MASK;
+
+       if (w & SSL_ST_CONNECT) str="SSL_connect";
+       else if (w & SSL_ST_ACCEPT) str="SSL_accept";
+       else str="undefined";
+
+       if (where & SSL_CB_LOOP)
+       {
+               fprintf(stderr,"%s:%s\n",str,SSL_state_string_long(s));
+       }
+       else if (where & SSL_CB_ALERT)
+       {
+               str=(where & SSL_CB_READ)?"read":"write";
+               fprintf(stderr,"SSL3 alert %s:%s:%s\n",
+                               str,
+                               SSL_alert_type_string_long(ret),
+                               SSL_alert_desc_string_long(ret));
+       }
+       else if (where & SSL_CB_EXIT)
+       {
+               if (ret == 0)
+                       fprintf(stderr,"%s:failed in %s\n",
+                                       str,SSL_state_string_long(s));
+               else if (ret < 0)
+               {
+                       fprintf(stderr,"%s:error in %s\n",
+                                       str,SSL_state_string_long(s));
+               }
+       }
+}
+#endif
+
+
 /* static */ void
 BSecureSocket::Private::_CreateContext()
 {
+       // We want SSL to report errors in human readable format.
+       SSL_load_error_strings();
+
        sContext = SSL_CTX_new(SSLv23_method());
 
+#if TRACE_SSL
+       // For debugging purposes: get all SSL messages to the standard error.
+       SSL_CTX_set_info_callback(sContext, apps_ssl_info_callback);
+#endif
+
        // Disable legacy protocols. They have known vulnerabilities.
        SSL_CTX_set_options(sContext, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
 

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

Revision:    hrev50644
Commit:      ed31589c375022059cda2a96beb6b06f893748da
URL:         http://cgit.haiku-os.org/haiku/commit/?id=ed31589c3750
Author:      Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
Date:        Mon Oct 31 21:14:39 2016 UTC

URL Disaptching/Async listeners: forward debug messages

This makes it possible for the Asynchronous listener to get the
messages. It can then process them in a more fancy way.

The default implementation will still log the messages to the console
(if debug is enabled), but it will do so from the Async listener for
asynchronous requests now. This means they will probably be logged from
the same thread, and show up in a more readable way.

This also makes it possible to listen to several requests and log them
in a nice way (in a status window or whatever).

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

diff --git a/headers/os/net/UrlProtocolDispatchingListener.h 
b/headers/os/net/UrlProtocolDispatchingListener.h
index 9d276b8..29fa46f 100644
--- a/headers/os/net/UrlProtocolDispatchingListener.h
+++ b/headers/os/net/UrlProtocolDispatchingListener.h
@@ -27,7 +27,8 @@ enum {
        B_URL_PROTOCOL_DOWNLOAD_PROGRESS,
        B_URL_PROTOCOL_UPLOAD_PROGRESS,
        B_URL_PROTOCOL_REQUEST_COMPLETED,
-       B_URL_PROTOCOL_CERTIFICATE_VERIFICATION_FAILED
+       B_URL_PROTOCOL_CERTIFICATE_VERIFICATION_FAILED,
+       B_URL_PROTOCOL_DEBUG_MESSAGE
 };
 
 
@@ -53,6 +54,9 @@ public:
                                                                        ssize_t 
bytesSent, ssize_t bytesTotal);
        virtual void                            RequestCompleted(BUrlRequest* 
caller,
                                                                        bool 
success);
+       virtual void                            DebugMessage(BUrlRequest* 
caller,
+                                                                       
BUrlProtocolDebugMessage type,
+                                                                       const 
char* text);
        virtual bool                            CertificateVerificationFailed(
                                                                        
BUrlRequest* caller,
                                                                        
BCertificate& certificate,
diff --git a/src/kits/network/libnetapi/UrlProtocolAsynchronousListener.cpp 
b/src/kits/network/libnetapi/UrlProtocolAsynchronousListener.cpp
index b90e9f6..dc53a42 100644
--- a/src/kits/network/libnetapi/UrlProtocolAsynchronousListener.cpp
+++ b/src/kits/network/libnetapi/UrlProtocolAsynchronousListener.cpp
@@ -12,6 +12,7 @@
 #include <AppKit.h>
 #include <UrlProtocolAsynchronousListener.h>
 #include <Debug.h>
+#include <String.h>
 
 extern const char* kUrlProtocolMessageType;
 extern const char* kUrlProtocolCaller;
@@ -142,6 +143,16 @@ 
BUrlProtocolAsynchronousListener::MessageReceived(BMessage* message)
                        }
                        break;
 
+               case B_URL_PROTOCOL_DEBUG_MESSAGE:
+                       {
+                               BUrlProtocolDebugMessage type
+                                       = 
(BUrlProtocolDebugMessage)message->FindInt32("url:type");
+                               BString text = message->FindString("url:text");
+
+                               DebugMessage(caller, type, text);
+                       }
+                       break;
+
                case B_URL_PROTOCOL_CERTIFICATE_VERIFICATION_FAILED:
                        {
                                const char* error = 
message->FindString("url:error");
diff --git a/src/kits/network/libnetapi/UrlProtocolDispatchingListener.cpp 
b/src/kits/network/libnetapi/UrlProtocolDispatchingListener.cpp
index d3222cb..ee4f184 100644
--- a/src/kits/network/libnetapi/UrlProtocolDispatchingListener.cpp
+++ b/src/kits/network/libnetapi/UrlProtocolDispatchingListener.cpp
@@ -125,6 +125,18 @@ 
BUrlProtocolDispatchingListener::RequestCompleted(BUrlRequest* caller,
 }
 
 
+void
+BUrlProtocolDispatchingListener::DebugMessage(BUrlRequest* caller,
+       BUrlProtocolDebugMessage type, const char* text)
+{
+       BMessage message(B_URL_PROTOCOL_NOTIFICATION);
+       message.AddInt32("url:type", type);
+       message.AddString("url:text", text);
+
+       _SendMessage(&message, B_URL_PROTOCOL_DEBUG_MESSAGE, caller);
+}
+
+
 bool
 BUrlProtocolDispatchingListener::CertificateVerificationFailed(
        BUrlRequest* caller, BCertificate& certificate, const char* error)
@@ -149,7 +161,7 @@ BUrlProtocolDispatchingListener::_SendMessage(BMessage* 
message,
        int8 notification, BUrlRequest* caller)
 {
        ASSERT(message != NULL);
-               
+
        message->AddPointer(kUrlProtocolCaller, caller);
        message->AddInt8(kUrlProtocolMessageType, notification);
 


Other related posts:

  • » [haiku-commits] haiku: hrev50644 - src/kits/network/libnetapi headers/os/net - pulkomandy