create a blocking + cancellable Socket::readBytes method
This commit is contained in:
parent
0f4e9af172
commit
86cc76388e
@ -178,6 +178,13 @@ CMakefiles for the library and the examples are available. This library has few
|
|||||||
|
|
||||||
There is a Dockerfile for running some code on Linux, and a unittest which can be executed by typing `make test`.
|
There is a Dockerfile for running some code on Linux, and a unittest which can be executed by typing `make test`.
|
||||||
|
|
||||||
|
You can build and install the ws command line tool with Homebrew.
|
||||||
|
|
||||||
|
```
|
||||||
|
brew create --cmake https://github.com/machinezone/IXWebSocket/archive/v1.1.0.tar.gz
|
||||||
|
brew install IXWebSocket
|
||||||
|
```
|
||||||
|
|
||||||
## Implementation details
|
## Implementation details
|
||||||
|
|
||||||
### Per Message Deflate compression.
|
### Per Message Deflate compression.
|
||||||
|
@ -231,19 +231,15 @@ namespace ix
|
|||||||
|
|
||||||
payload.reserve(contentLength);
|
payload.reserve(contentLength);
|
||||||
|
|
||||||
// FIXME: very inefficient way to read bytes, but it works...
|
auto chunkResult = _socket->readBytes(contentLength, isCancellationRequested);
|
||||||
for (int i = 0; i < contentLength; ++i)
|
if (!chunkResult.first)
|
||||||
{
|
{
|
||||||
char c;
|
errorMsg = "Cannot read chunk";
|
||||||
if (!_socket->readByte(&c, isCancellationRequested))
|
return std::make_tuple(code, HttpErrorCode_ChunkReadError,
|
||||||
{
|
headers, payload, errorMsg,
|
||||||
return std::make_tuple(code, HttpErrorCode_ReadError,
|
uploadSize, downloadSize);
|
||||||
headers, payload, "Cannot read byte",
|
|
||||||
uploadSize, downloadSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
payload += c;
|
|
||||||
}
|
}
|
||||||
|
payload += chunkResult.second;
|
||||||
}
|
}
|
||||||
else if (headers.find("Transfer-Encoding") != headers.end() &&
|
else if (headers.find("Transfer-Encoding") != headers.end() &&
|
||||||
headers["Transfer-Encoding"] == "chunked")
|
headers["Transfer-Encoding"] == "chunked")
|
||||||
@ -277,22 +273,18 @@ namespace ix
|
|||||||
|
|
||||||
payload.reserve(payload.size() + chunkSize);
|
payload.reserve(payload.size() + chunkSize);
|
||||||
|
|
||||||
// Read another line
|
// Read a chunk
|
||||||
|
auto chunkResult = _socket->readBytes(chunkSize, isCancellationRequested);
|
||||||
for (uint64_t i = 0; i < chunkSize; ++i)
|
if (!chunkResult.first)
|
||||||
{
|
{
|
||||||
char c;
|
errorMsg = "Cannot read chunk";
|
||||||
if (!_socket->readByte(&c, isCancellationRequested))
|
return std::make_tuple(code, HttpErrorCode_ChunkReadError,
|
||||||
{
|
headers, payload, errorMsg,
|
||||||
errorMsg = "Cannot read byte";
|
uploadSize, downloadSize);
|
||||||
return std::make_tuple(code, HttpErrorCode_ChunkReadError,
|
|
||||||
headers, payload, errorMsg,
|
|
||||||
uploadSize, downloadSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
payload += c;
|
|
||||||
}
|
}
|
||||||
|
payload += chunkResult.second;
|
||||||
|
|
||||||
|
// Read the line that terminates the chunk (\r\n)
|
||||||
lineResult = _socket->readLine(isCancellationRequested);
|
lineResult = _socket->readLine(isCancellationRequested);
|
||||||
|
|
||||||
if (!lineResult.first)
|
if (!lineResult.first)
|
||||||
|
@ -251,7 +251,8 @@ namespace ix
|
|||||||
{
|
{
|
||||||
if (!readByte(&c, isCancellationRequested))
|
if (!readByte(&c, isCancellationRequested))
|
||||||
{
|
{
|
||||||
return std::make_pair(false, std::string());
|
// Return what we were able to read
|
||||||
|
return std::make_pair(false, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
line += c;
|
line += c;
|
||||||
@ -259,4 +260,26 @@ namespace ix
|
|||||||
|
|
||||||
return std::make_pair(true, line);
|
return std::make_pair(true, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<bool, std::string> Socket::readBytes(
|
||||||
|
size_t length,
|
||||||
|
const CancellationRequest& isCancellationRequested)
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
std::string buffer;
|
||||||
|
buffer.reserve(length);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < length; ++i)
|
||||||
|
{
|
||||||
|
if (!readByte(&c, isCancellationRequested))
|
||||||
|
{
|
||||||
|
// Return what we were able to read
|
||||||
|
return std::make_pair(false, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer += c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_pair(true, buffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,12 @@ namespace ix
|
|||||||
const CancellationRequest& isCancellationRequested);
|
const CancellationRequest& isCancellationRequested);
|
||||||
bool writeBytes(const std::string& str,
|
bool writeBytes(const std::string& str,
|
||||||
const CancellationRequest& isCancellationRequested);
|
const CancellationRequest& isCancellationRequested);
|
||||||
std::pair<bool, std::string> readLine(const CancellationRequest& isCancellationRequested);
|
|
||||||
|
std::pair<bool, std::string> readLine(
|
||||||
|
const CancellationRequest& isCancellationRequested);
|
||||||
|
std::pair<bool, std::string> readBytes(
|
||||||
|
size_t length,
|
||||||
|
const CancellationRequest& isCancellationRequested);
|
||||||
|
|
||||||
static int getErrno();
|
static int getErrno();
|
||||||
static bool init(); // Required on Windows to initialize WinSocket
|
static bool init(); // Required on Windows to initialize WinSocket
|
||||||
|
20
third_party/homebrew_formula.rb
vendored
Normal file
20
third_party/homebrew_formula.rb
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
class Ixwebsocket < Formula
|
||||||
|
desc "WebSocket client and server, and HTTP client command-line tool"
|
||||||
|
homepage "https://github.com/machinezone/IXWebSocket"
|
||||||
|
url "https://github.com/machinezone/IXWebSocket/archive/v1.1.0.tar.gz"
|
||||||
|
sha256 "52592ce3d0a67ad0f90ac9e8a458f61724175d95a01a38d1bad3fcdc5c7b6666"
|
||||||
|
depends_on "cmake" => :build
|
||||||
|
|
||||||
|
def install
|
||||||
|
system "cmake", ".", *std_cmake_args
|
||||||
|
system "make", "install"
|
||||||
|
end
|
||||||
|
|
||||||
|
test do
|
||||||
|
system "#{bin}/ws", "--help"
|
||||||
|
system "#{bin}/ws", "send", "--help"
|
||||||
|
system "#{bin}/ws", "receive", "--help"
|
||||||
|
system "#{bin}/ws", "transfer", "--help"
|
||||||
|
system "#{bin}/ws", "curl", "--help"
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user