From c23a77d4cc5a765bfd3e8cac796febbfc6ef6447 Mon Sep 17 00:00:00 2001 From: Fred Nicolson Date: Tue, 30 Apr 2019 17:29:03 +0100 Subject: [PATCH] Cleaned up code. Updated documentation. --- include/frnetlib/Http.h | 6 ++++-- include/frnetlib/HttpRequest.h | 1 - include/frnetlib/HttpResponse.h | 1 - include/frnetlib/Packet.h | 23 +++++++++++++---------- include/frnetlib/SSLSocket.h | 3 ++- include/frnetlib/Socket.h | 8 ++++---- include/frnetlib/TcpSocket.h | 3 ++- include/frnetlib/WebFrame.h | 7 +++++-- src/Http.cpp | 12 +++++++++--- src/Socket.cpp | 25 ++++++++++--------------- src/WebFrame.cpp | 28 ++++++++++++++++++++++++---- 11 files changed, 73 insertions(+), 44 deletions(-) diff --git a/include/frnetlib/Http.h b/include/frnetlib/Http.h index cb864a1..575387b 100644 --- a/include/frnetlib/Http.h +++ b/include/frnetlib/Http.h @@ -95,7 +95,6 @@ namespace fr Http(const Http&)= default; Http &operator=(const Http &)=default; Http &operator=(Http &&)=default; - virtual ~Http() = default; /*! @@ -326,7 +325,10 @@ namespace fr * 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; diff --git a/include/frnetlib/HttpRequest.h b/include/frnetlib/HttpRequest.h index 8d01450..1378e0c 100644 --- a/include/frnetlib/HttpRequest.h +++ b/include/frnetlib/HttpRequest.h @@ -21,7 +21,6 @@ namespace fr HttpRequest(const HttpRequest&)= default; HttpRequest &operator=(const HttpRequest &)=default; HttpRequest &operator=(HttpRequest &&)=default; - virtual ~HttpRequest() = default; /*! * Parse a HTTP response. diff --git a/include/frnetlib/HttpResponse.h b/include/frnetlib/HttpResponse.h index 96b9788..d77963d 100644 --- a/include/frnetlib/HttpResponse.h +++ b/include/frnetlib/HttpResponse.h @@ -21,7 +21,6 @@ namespace fr HttpResponse(const HttpResponse&)= default; HttpResponse &operator=(const HttpResponse &)=default; HttpResponse &operator=(HttpResponse &&)=default; - virtual ~HttpResponse() = default; /*! * Parse a raw request or response from a string diff --git a/include/frnetlib/Packet.h b/include/frnetlib/Packet.h index f1ac892..1b87091 100644 --- a/include/frnetlib/Packet.h +++ b/include/frnetlib/Packet.h @@ -22,14 +22,12 @@ namespace fr { public: Packet() noexcept - : buffer(PACKET_HEADER_LENGTH, '0'), - buffer_read_index(PACKET_HEADER_LENGTH) + : buffer(PACKET_HEADER_LENGTH, '0'), + buffer_read_index(PACKET_HEADER_LENGTH) { } - virtual ~Packet() = default; - //Nasty constructor to allow things like Packet{1, 2, 3, "bob"}. template Packet(T const &part, Args &&...args) @@ -721,8 +719,10 @@ namespace fr * custom types to be directly received through * 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 { @@ -742,11 +742,14 @@ namespace fr //Now we've got the length, read the rest of the data in if(packet_length + PACKET_HEADER_LENGTH > buffer.size()) 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; } diff --git a/include/frnetlib/SSLSocket.h b/include/frnetlib/SSLSocket.h index 5e8a3d1..8e613e7 100644 --- a/include/frnetlib/SSLSocket.h +++ b/include/frnetlib/SSLSocket.h @@ -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 received Will be filled with the number of bytes actually received, might be less than you requested. * @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. * 'SSLError' An SSL error has occurred. * 'Success' All the bytes you wanted have been read diff --git a/include/frnetlib/Socket.h b/include/frnetlib/Socket.h index 1dc44bf..966c5d7 100644 --- a/include/frnetlib/Socket.h +++ b/include/frnetlib/Socket.h @@ -159,10 +159,10 @@ namespace fr * * @param dest Where to read the data into * @param buffer_size The number of bytes to read - * @return Operation status: - * 'Disconnected' if the socket disconnected - * 'Success' if buffer_size bytes could be read successfully - * '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 + * @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(). */ Status receive_all(void *dest, size_t buffer_size); diff --git a/include/frnetlib/TcpSocket.h b/include/frnetlib/TcpSocket.h index bca21f8..10df49d 100644 --- a/include/frnetlib/TcpSocket.h +++ b/include/frnetlib/TcpSocket.h @@ -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. * @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 - * '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. * 'Success' All the bytes you wanted have been read */ diff --git a/include/frnetlib/WebFrame.h b/include/frnetlib/WebFrame.h index 27eb701..bb1e82f 100644 --- a/include/frnetlib/WebFrame.h +++ b/include/frnetlib/WebFrame.h @@ -32,7 +32,7 @@ namespace fr explicit WebFrame(Opcode type = Text); /*! - * Get's the received payload data. (Data received). + * Get's the receied payload data. (Data received). * * @return The payload */ @@ -112,7 +112,10 @@ namespace fr * * @note If the maximum message length is exceeded, then the connection will be closed * @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; diff --git a/src/Http.cpp b/src/Http.cpp index f143731..aef38d0 100644 --- a/src/Http.cpp +++ b/src/Http.cpp @@ -1014,10 +1014,16 @@ namespace fr do { //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; - if(status != Socket::Success && !(status == fr::Socket::WouldBlock && total_received != 0)) - return status; + if(status != Socket::Success) + { + if(total_received == 0) + return status; + if(status == Socket::WouldBlock) + continue; + return Socket::Disconnected; + } //Parse it state = parse(recv_buffer, received); diff --git a/src/Socket.cpp b/src/Socket.cpp index 2f58503..2ab7f76 100644 --- a/src/Socket.cpp +++ b/src/Socket.cpp @@ -34,30 +34,25 @@ namespace fr Socket::Status Socket::receive(Sendable &obj) { - if(!connected()) - return Socket::Disconnected; - return obj.receive(this); } Socket::Status Socket::receive_all(void *dest, size_t buffer_size) { - if(!connected()) - return Socket::Disconnected; - - auto bytes_remaining = (int32_t) buffer_size; - size_t bytes_read = 0; + auto bytes_remaining = (ssize_t) buffer_size; while(bytes_remaining > 0) { size_t received = 0; - auto *arr = (char*)dest; - Status status = receive_raw(&arr[bytes_read], (size_t)bytes_remaining, received); - if(status != fr::Socket::WouldBlock && status != fr::Socket::Success) - return status; + Status status = receive_raw((char*)dest + (buffer_size - bytes_remaining), (size_t)bytes_remaining, received); bytes_remaining -= received; - bytes_read += received; - if(status == fr::Socket::WouldBlock && bytes_read == 0) - return status; + if(status != Socket::Success) + { + if((ssize_t)buffer_size == bytes_remaining) + return status; + if(status == Socket::WouldBlock) + continue; + return Socket::Disconnected; + } } return Socket::Status::Success; diff --git a/src/WebFrame.cpp b/src/WebFrame.cpp index d903941..533e98e 100644 --- a/src/WebFrame.cpp +++ b/src/WebFrame.cpp @@ -119,14 +119,24 @@ namespace fr if(payload_length == 126) //Length is longer than 7 bit, so read 16bit 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); if(status != fr::Socket::Success) return status; } 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); if(status != fr::Socket::Success) return status; @@ -146,14 +156,24 @@ namespace fr } mask_union{}; 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) return status; } //Read payload 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) return status;