NetServices: Implement asynchronous status update messages.

The integration PostTest has a basic test that the expected messages are sent and
have the expected data fields. The gist is documented in book.dox.

To do are the messages around SSL. However, that functionality is also not
implemented yet, so there is nothing to send.

Change-Id: Ib8f36ed32f9854d643d8256338b71af7067059f0
This commit is contained in:
Niels Sascha Reedijk
2022-07-24 08:56:02 +01:00
parent b74e852fd9
commit 60355daec9
8 changed files with 661 additions and 70 deletions
+171
View File
@@ -603,6 +603,177 @@ snooze_until(time - Latency(), B_SYSTEM_TIMEBASE);
application to <code>libnetservices2.a</code>. The new API is only
available for modern platforms (x86 and x86_64), and not for the legacy
platform (x86_gcc2). The compiler needs to support C++17 or higher.
<h3>Asynchronous handling of the result.</h3>
In GUI applications, networking operations are often triggered by a user action. For example,
downloading a file will be initiated by the user clicking a button. When you initiate that
action in the window's thread, and you block the message loop until the request is finished,
the user will be left with a non-responsive UI. That is why one would usually run a network
request asynchronously. And instead of checking the status every few CPU cycles, you'd want
to be proactively informed when something important happens, like the progress of the download
or a signal when the request is finished.
The Network Services kit support using the Haiku API's Looper and Handler system to keep you up
to date about relevant events that happen to the requests.
The following messages are available for all requests (HTTP and other). The messages below are
in the order that they will arrive (when applicable).
<table>
<tr>
<th>Message Constant</th>
<th>Description</th>
<th>Applies to</th>
<th> Additional Data</th>
</tr>
<tr>
<td>\ref BPrivate::Network::UrlEvent::HostNameResolved "UrlEvent::HostNameResolved"</td>
<td>
The hostname has been resolved. This message is even sent when you set an
IP-address in the URL object
</td>
<td>All protocols that use network connections.</td>
<td>
\ref BPrivate::Network::UrlEventData::Id "UrlEventData::Id" \c int32 <br/>
\ref BPrivate::Network::UrlEventData::HostName "UrlEventData::HostName"
\ref BString
</td>
</tr>
<tr>
<td>\ref BPrivate::Network::UrlEvent::ConnectionOpened "UrlEvent::ConnectionOpened"</td>
<td>
The connection to the remote server is opened. After this event, data will be
written.
</td>
<td>All protocols that use network connections.</td>
<td>
\ref BPrivate::Network::UrlEventData::Id "UrlEventData::Id" \c int32
</td>
</tr>
<tr>
<td>\ref BPrivate::Network::UrlEvent::UploadProgress "UrlEvent::UploadProgress"</td>
<td>
If there is a request body to be sent, this informs you of the progress. When the
total size of the request body is known, this will be part of the message.
</td>
<td>
All protocols that use network connections and support writing data to the server
(like HTTP(S)).
</td>
<td>
\ref BPrivate::Network::UrlEventData::Id "UrlEventData::Id" \c int32 <br/>
\ref BPrivate::Network::UrlEventData::NumBytes "UrlEventData::NumBytes"
\c int64 <br/>
\ref BPrivate::Network::UrlEventData::TotalBytes "UrlEventData::TotalBytes"
\c int64 (optional)
</td>
</tr>
<tr>
<td>\ref BPrivate::Network::UrlEvent::ResponseStarted "UrlEvent::ResponseStarted"</td>
<td>The server has started transmitting the response.</td>
<td>All Protocols</td>
<td>
\ref BPrivate::Network::UrlEventData::Id "UrlEventData::Id" \c int32 <br/>
</td>
</tr>
<tr>
<td>\ref BPrivate::Network::UrlEvent::HttpRedirect "UrlEvent::HttpRedirect</td>
<td>
The network services kit is handling a HTTP redirect. The request will be repeated
for a new URL.
</td>
<td>HTTP/HTTPS</td>
<td>
\ref BPrivate::Network::UrlEventData::Id "UrlEventData::Id" \c int32 <br/>
\ref BPrivate::Network::UrlEventData::HttpRedirectUrl
"UrlEventData::HttpRedirectUrl" \ref BString
</td>
</tr>
<tr>
<td>\ref BPrivate::Network::UrlEvent::HttpStatus "UrlEvent::HttpStatus"</td>
<td>
The response status is available. This means it can also be accessed through
\ref BPrivate::Network::BHttpResult::Status() "BHttpResult::Status()" without
blocking the system.
</td>
<td>HTTP/HTTPS</td>
<td>
\ref BPrivate::Network::UrlEventData::Id "UrlEventData::Id" \c int32 <br/>
\ref BPrivate::Network::UrlEventData::HttpStatusCode "UrlEventData::HttpStatusCode"
\c int16
</td>
</tr>
<tr>
<td>\ref BPrivate::Network::UrlEvent::HttpFields "UrlEvent::HttpFields"</td>
<td>
The HTTP header block has been fully received, and the HTTP fields can be accessed
using \ref BPrivate::Network::BHttpResult::Fields() "BHttpResult::Fields()" without
blocking the system.
</td>
<td>HTTP/HTTPS</td>
<td>
\ref BPrivate::Network::UrlEventData::Id "UrlEventData::Id" \c int32
</td>
</tr>
<tr>
<td>\ref BPrivate::Network::UrlEvent::DownloadProgress "UrlEvent::DownloadProgress"</td>
<td>
If there is a response body to be received, this informs you of the progress. If
the total size of the body is known, this will be included in the message as well.
</td>
<td>All protocols that use network connections.</td>
<td>
\ref BPrivate::Network::UrlEventData::Id "UrlEventData::Id" \c int32 <br/>
\ref BPrivate::Network::UrlEventData::NumBytes "UrlEventData::NumBytes"
\c int64 <br/>
\ref BPrivate::Network::UrlEventData::TotalBytes "UrlEventData::TotalBytes"
\c int64 (optional)
</td>
</tr>
<tr>
<td>\ref BPrivate::Network::UrlEvent::BytesWritten "UrlEvent::BytesWritten"</td>
<td>
An interim update on how many bytes have been written to the target. This message
is only sent when you supplied a custom target to store the body of the request in.
Note that the number of bytes written to the target may differ from the network
transfer size, due to compression in the protocol.
</td>
<td>All protocols.</td>
<td>
\ref BPrivate::Network::UrlEventData::Id "UrlEventData::Id" \c int32 <br/>
\ref BPrivate::Network::UrlEventData::NumBytes "UrlEventData::NumBytes"
\c int64
</td>
</tr>
<tr>
<td>\ref BPrivate::Network::UrlEvent::RequestCompleted "UrlEvent::RequestCompleted"</td>
<td>
The request is completed and all the data is written to the target, or there was
an error.
</td>
<td>All protocols.</td>
<td>
\ref BPrivate::Network::UrlEventData::Id "UrlEventData::Id" \c int32 <br/>
\ref BPrivate::Network::UrlEventData::Success "UrlEventData::Success" \c bool
</td>
</tr>
<tr>
<td>\ref BPrivate::Network::UrlEvent::DebugMessage "UrlEvent::DebugMessage"</td>
<td>
Additional debug information on the request. This is enabled or disabled per
request. See the details in the protocol description.
</td>
<td>All protocols.</td>
<td>
\ref BPrivate::Network::UrlEventData::Id "UrlEventData::Id" \c int32 <br/>
\ref BPrivate::Network::UrlEventData::DebugType "UrlEventData::DebugType"
\c int32 <br/>
\ref BPrivate::Network::UrlEventData::DebugMessage "UrlEventData::DebugMessage"
\ref BString
</td>
</tr>
</table>
*/
#endif
+65
View File
@@ -219,6 +219,71 @@ namespace Network {
*/
/*!
\var UrlEvent::HttpStatus
\brief The HTTP status code has been received, and can be accessed through the result object.
\since Haiku R1
*/
/*!
\var UrlEvent::HttpFields
\brief The HTTP header block has been received, and the status and fields can be accessed
through the result object.
\since Haiku R1
*/
/*!
\var UrlEvent::CertificateError
\brief There was an error communicating with the server because of an SSL certificate issue.
\since Haiku R1
*/
/*!
\var UrlEvent::HttpRedirect
\brief The Http request was redirected, and this redirect was handled by the kit.
\since Haiku R1
*/
/*!
\var const char* UrlEventData::HttpStatusCode
\brief An \c int16 value that contains the HTTP status code for this request.
\since Haiku R1
*/
/*!
\var const char* UrlEventData::SSLCertificate
\brief The SSL certificate that causes the issue.
\since Haiku R1
*/
/*!
\var const char* UrlEventData::SSLMessage
\brief A \ref BString message about the error while processing the SSL certificate.
\since Haiku R1
*/
/*!
\var const char* UrlEventData::HttpRedirectUrl
\brief A \ref BString with the URL that the HTTP request was redirected to.
\since Haiku R1
*/
} // namespace Network
} // namespace BPrivate
+150
View File
@@ -248,6 +248,156 @@ namespace Network {
*/
/*!
\fn BString encode_to_base64(const BString& string)
\brief Utility function that encodes a \a string to base64 and returns the result.
\since Haiku R1
*/
/*!
\namespace BPrivate::Network::UrlEvent
\brief Contains the message constants that are sent by the various protocols.
Please see the \link netservices kit documentation \endlink for details which messages are sent
at which stage, and what data they contain.
\since Haiku R1
*/
/*!
\var UrlEvent::HostNameResolved
\brief The hostname for the request is resolved.
\since Haiku R1
*/
/*!
\var UrlEvent::ConnectionOpened
\brief The connection for the request is opened and the request will be sent.
\since Haiku R1
*/
/*!
\var UrlEvent::UploadProgress
\brief There is progress sending the body for the request.
\since Haiku R1
*/
/*!
\var UrlEvent::ResponseStarted
\brief The request was sent, and the response is now incoming.
\since Haiku R1
*/
/*!
\var UrlEvent::DownloadProgress
\brief There is progress receiving the body of the request.
\since Haiku R1
*/
/*!
\var UrlEvent::BytesWritten
\brief There are bytes written to the target of the body.
\since Haiku R1
*/
/*!
\var UrlEvent::RequestCompleted
\brief The request was completed.
\since Haiku R1
*/
/*!
\var UrlEvent::DebugMessage
\brief There is a debug message for a request or for a protocol.
\since Haiku R1
*/
/*!
\namespace BPrivate::Network::UrlEventData
\brief Contains the names of the data in the messages that are sent by the various protocols.
Please see the \link netservices kit documentation \endlink for details which messages are sent
at which stage, and what data they contain.
\since Haiku R1
*/
/*!
\var const char* UrlEventData::Id
\brief An \c int32 that identifies the request the message pertains to.
\since Haiku R1
*/
/*!
\var const char* UrlEventData::HostName
\brief A \ref BString that represents the hostname that was resolved.
\since Haiku R1
*/
/*!
\var const char* UrlEventData::NumBytes
\brief An \c int64/off_t represening the number of bytes transferred to now.
\since Haiku R1
*/
/*!
\var const char* UrlEventData::TotalBytes
\brief An \c int64/off_t representing the total number of bytes that will be sent/received.
\since Haiku R1
*/
/*!
\var const char* UrlEventData::Success
\brief A \c bool that indicates whether an activity was succesful.
\since Haiku R1
*/
/*!
\var const char* UrlEventData::DebugType
\brief An \c int32 representing a debug type constant.
\since Haiku R1
*/
/*!
\var const char* UrlEventData::DebugMessage
\brief A \ref BString that contains the debug message.
\since Haiku R1
*/
} // namespace Network
} // namespace BPrivate