Cleaned up code. Updated documentation.

This commit is contained in:
Fred Nicolson 2019-04-30 17:29:03 +01:00
parent 7f1c25a73b
commit c23a77d4cc
No known key found for this signature in database
GPG Key ID: 78C1DD87B47797D2
11 changed files with 73 additions and 44 deletions

View File

@ -95,7 +95,6 @@ namespace fr
Http(const Http&)= default; Http(const Http&)= default;
Http &operator=(const Http &)=default; Http &operator=(const Http &)=default;
Http &operator=(Http &&)=default; Http &operator=(Http &&)=default;
virtual ~Http() = default;
/*! /*!
@ -326,7 +325,10 @@ namespace fr
* sockets. * sockets.
* *
* @param socket The socket to send through * @param socket The socket to send through
* @return Status indicating if the send succeeded or not. * @return Status indicating if the send succeeded or not:
* 'Success': All good, object still valid.
* 'WouldBlock' or 'Timeout': No data received. Object still valid though.
* Anything else: Object invalid. Call disconnect().
*/ */
Socket::Status receive(Socket *socket) override; Socket::Status receive(Socket *socket) override;

View File

@ -21,7 +21,6 @@ namespace fr
HttpRequest(const HttpRequest&)= default; HttpRequest(const HttpRequest&)= default;
HttpRequest &operator=(const HttpRequest &)=default; HttpRequest &operator=(const HttpRequest &)=default;
HttpRequest &operator=(HttpRequest &&)=default; HttpRequest &operator=(HttpRequest &&)=default;
virtual ~HttpRequest() = default;
/*! /*!
* Parse a HTTP response. * Parse a HTTP response.

View File

@ -21,7 +21,6 @@ namespace fr
HttpResponse(const HttpResponse&)= default; HttpResponse(const HttpResponse&)= default;
HttpResponse &operator=(const HttpResponse &)=default; HttpResponse &operator=(const HttpResponse &)=default;
HttpResponse &operator=(HttpResponse &&)=default; HttpResponse &operator=(HttpResponse &&)=default;
virtual ~HttpResponse() = default;
/*! /*!
* Parse a raw request or response from a string * Parse a raw request or response from a string

View File

@ -22,14 +22,12 @@ namespace fr
{ {
public: public:
Packet() noexcept Packet() noexcept
: buffer(PACKET_HEADER_LENGTH, '0'), : buffer(PACKET_HEADER_LENGTH, '0'),
buffer_read_index(PACKET_HEADER_LENGTH) buffer_read_index(PACKET_HEADER_LENGTH)
{ {
} }
virtual ~Packet() = default;
//Nasty constructor to allow things like Packet{1, 2, 3, "bob"}. //Nasty constructor to allow things like Packet{1, 2, 3, "bob"}.
template <typename T, typename ...Args> template <typename T, typename ...Args>
Packet(T const &part, Args &&...args) Packet(T const &part, Args &&...args)
@ -721,8 +719,10 @@ namespace fr
* custom types to be directly received through * custom types to be directly received through
* sockets. * sockets.
* *
* @param socket The socket to send through * @return Status indicating if the send succeeded or not:
* @return Status indicating if the send succeeded or not. * 'Success': All good, object still valid.
* 'WouldBlock' or 'Timeout': No data received. Object still valid though.
* Anything else: Object invalid. Call disconnect().
*/ */
Socket::Status receive(Socket *socket) override Socket::Status receive(Socket *socket) override
{ {
@ -742,11 +742,14 @@ namespace fr
//Now we've got the length, read the rest of the data in //Now we've got the length, read the rest of the data in
if(packet_length + PACKET_HEADER_LENGTH > buffer.size()) if(packet_length + PACKET_HEADER_LENGTH > buffer.size())
buffer.resize(packet_length + PACKET_HEADER_LENGTH); buffer.resize(packet_length + PACKET_HEADER_LENGTH);
status = socket->receive_all(&buffer[PACKET_HEADER_LENGTH], packet_length);
if(status != Socket::Status::Success)
return status;
return Socket::Status::Success; do
{
status = socket->receive_all(&buffer[PACKET_HEADER_LENGTH], packet_length);
} while(status == fr::Socket::WouldBlock);
if(status == fr::Socket::Timeout)
status = fr::Socket::Disconnected;
return status;
} }

View File

@ -49,7 +49,8 @@ namespace fr
* @param data_size The number of bytes to try and receive. Be sure that it's not larger than data. * @param data_size The number of bytes to try and receive. Be sure that it's not larger than data.
* @param received Will be filled with the number of bytes actually received, might be less than you requested. * @param received Will be filled with the number of bytes actually received, might be less than you requested.
* @return The status of the operation: * @return The status of the operation:
* 'WouldBlock' if no data has been received, and the socket is in non-blocking mode or the operation has timed out * 'WouldBlock' if no data has been received and the socket is nonblockins
* 'TimedOut' if the socket is blocking and no data was received in time.
* 'Disconnected' if the socket has disconnected. * 'Disconnected' if the socket has disconnected.
* 'SSLError' An SSL error has occurred. * 'SSLError' An SSL error has occurred.
* 'Success' All the bytes you wanted have been read * 'Success' All the bytes you wanted have been read

View File

@ -159,10 +159,10 @@ namespace fr
* *
* @param dest Where to read the data into * @param dest Where to read the data into
* @param buffer_size The number of bytes to read * @param buffer_size The number of bytes to read
* @return Operation status: * @return Status indicating if the send succeeded or not:
* 'Disconnected' if the socket disconnected * 'Success': All good, object still valid.
* 'Success' if buffer_size bytes could be read successfully * 'WouldBlock' or 'Timeout': No data received. Object still valid though.
* 'WouldBlock' if the socket is in blocking mode and no data could be read, or if the read timed out before any data was received * Anything else: Object invalid. Call disconnect().
*/ */
Status receive_all(void *dest, size_t buffer_size); Status receive_all(void *dest, size_t buffer_size);

View File

@ -59,7 +59,8 @@ namespace fr
* @param received Will be filled with the number of bytes actually received, might be less than you requested if in non-blocking mode/error. * @param received Will be filled with the number of bytes actually received, might be less than you requested if in non-blocking mode/error.
* @return The status of the operation: * @return The status of the operation:
* 'WouldBlock' if no data has been received, and the socket is in non-blocking mode or operation has timed out * 'WouldBlock' if no data has been received, and the socket is in non-blocking mode or operation has timed out
* 'Disconnected' if the socket has disconnected. * 'Timeout' Socket is in blocking mode and it timed out.
* 'Disconnected' if the socket has disconnected. (you must now call disconnect())
* 'ReceiveError' A receive error occurred. * 'ReceiveError' A receive error occurred.
* 'Success' All the bytes you wanted have been read * 'Success' All the bytes you wanted have been read
*/ */

View File

@ -32,7 +32,7 @@ namespace fr
explicit WebFrame(Opcode type = Text); explicit WebFrame(Opcode type = Text);
/*! /*!
* Get's the received payload data. (Data received). * Get's the receied payload data. (Data received).
* *
* @return The payload * @return The payload
*/ */
@ -112,7 +112,10 @@ namespace fr
* *
* @note If the maximum message length is exceeded, then the connection will be closed * @note If the maximum message length is exceeded, then the connection will be closed
* @param socket The socket to send through * @param socket The socket to send through
* @return Status indicating if the send succeeded or not. * @return Status indicating if the send succeeded or not:
* 'Success': All good, object still valid.
* 'WouldBlock' or 'Timeout': No data received. Object still valid though.
* Anything else: Object invalid. Call disconnect().
*/ */
Socket::Status receive(Socket *socket) override; Socket::Status receive(Socket *socket) override;

View File

@ -1014,10 +1014,16 @@ namespace fr
do do
{ {
//Receive the request //Receive the request
Socket::Status status = socket->receive_raw(recv_buffer, RECV_CHUNK_SIZE, received); auto status = socket->receive_raw(recv_buffer, RECV_CHUNK_SIZE, received);
total_received += received; total_received += received;
if(status != Socket::Success && !(status == fr::Socket::WouldBlock && total_received != 0)) if(status != Socket::Success)
return status; {
if(total_received == 0)
return status;
if(status == Socket::WouldBlock)
continue;
return Socket::Disconnected;
}
//Parse it //Parse it
state = parse(recv_buffer, received); state = parse(recv_buffer, received);

View File

@ -34,30 +34,25 @@ namespace fr
Socket::Status Socket::receive(Sendable &obj) Socket::Status Socket::receive(Sendable &obj)
{ {
if(!connected())
return Socket::Disconnected;
return obj.receive(this); return obj.receive(this);
} }
Socket::Status Socket::receive_all(void *dest, size_t buffer_size) Socket::Status Socket::receive_all(void *dest, size_t buffer_size)
{ {
if(!connected()) auto bytes_remaining = (ssize_t) buffer_size;
return Socket::Disconnected;
auto bytes_remaining = (int32_t) buffer_size;
size_t bytes_read = 0;
while(bytes_remaining > 0) while(bytes_remaining > 0)
{ {
size_t received = 0; size_t received = 0;
auto *arr = (char*)dest; Status status = receive_raw((char*)dest + (buffer_size - bytes_remaining), (size_t)bytes_remaining, received);
Status status = receive_raw(&arr[bytes_read], (size_t)bytes_remaining, received);
if(status != fr::Socket::WouldBlock && status != fr::Socket::Success)
return status;
bytes_remaining -= received; bytes_remaining -= received;
bytes_read += received; if(status != Socket::Success)
if(status == fr::Socket::WouldBlock && bytes_read == 0) {
return status; if((ssize_t)buffer_size == bytes_remaining)
return status;
if(status == Socket::WouldBlock)
continue;
return Socket::Disconnected;
}
} }
return Socket::Status::Success; return Socket::Status::Success;

View File

@ -119,14 +119,24 @@ namespace fr
if(payload_length == 126) //Length is longer than 7 bit, so read 16bit length if(payload_length == 126) //Length is longer than 7 bit, so read 16bit length
{ {
uint16_t length; uint16_t length;
status = socket->receive_all(&length, sizeof(length)); do
{
status = socket->receive_all(&length, sizeof(length));
} while(status == fr::Socket::WouldBlock);
if(status == fr::Socket::Timeout)
status = fr::Socket::Disconnected;
payload_length = ntohs(length); payload_length = ntohs(length);
if(status != fr::Socket::Success) if(status != fr::Socket::Success)
return status; return status;
} }
else if(payload_length == 127) //Length is longer than 16 bit, so read 64bit length else if(payload_length == 127) //Length is longer than 16 bit, so read 64bit length
{ {
status = socket->receive_all(&payload_length, sizeof(payload_length)); do
{
status = socket->receive_all(&payload_length, sizeof(payload_length));
} while(status == fr::Socket::WouldBlock);
if(status == fr::Socket::Timeout)
status = fr::Socket::Disconnected;
payload_length = fr_ntohll(payload_length); payload_length = fr_ntohll(payload_length);
if(status != fr::Socket::Success) if(status != fr::Socket::Success)
return status; return status;
@ -146,14 +156,24 @@ namespace fr
} mask_union{}; } mask_union{};
if(mask) if(mask)
{ {
status = socket->receive_all(&mask_union.mask_key, 4); do
{
status = socket->receive_all(&mask_union.mask_key, 4);
} while(status == fr::Socket::WouldBlock);
if(status == fr::Socket::Timeout)
status = fr::Socket::Disconnected;
if(status != fr::Socket::Success) if(status != fr::Socket::Success)
return status; return status;
} }
//Read payload //Read payload
payload.resize(payload_length, '\0'); payload.resize(payload_length, '\0');
status = socket->receive_all(&payload[0], payload_length); do
{
status = socket->receive_all(&payload[0], payload_length);
} while(status == fr::Socket::WouldBlock);
if(status == fr::Socket::Timeout)
status = fr::Socket::Disconnected;
if(status != fr::Socket::Success) if(status != fr::Socket::Success)
return status; return status;