create a blocking + cancellable Socket::readBytes method
This commit is contained in:
		@@ -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
 | 
				
			||||||
		Reference in New Issue
	
	Block a user