Module: TestPuma::PumaSocketInclude
| Relationships & Source Files | |
| Extension / Inclusion / Inheritance Descendants | |
|
Included In:
| |
| Defined in: | test/helpers/test_puma/puma_socket_include.rb |
Overview
This module contains the methods included in PumaSSLSocket, PumaTCPSocket, and PumaUNIXSocket, which are subclasses of the native Ruby sockets. All methods add functionality related to their use with client HTTP connections.
Constant Summary
-
NO_ENTITY_BODY =
# File 'test/helpers/test_puma/puma_socket_include.rb', line 21Puma::STATUS_WITH_NO_ENTITY_BODY
-
RESP_READ_LEN =
# File 'test/helpers/test_puma/puma_socket_include.rb', line 1965_536 -
RESP_READ_TIMEOUT =
# File 'test/helpers/test_puma/puma_socket_include.rb', line 2010
Instance Method Summary
-
#<<(req = nil)
Alias for #send_http.
-
#read_all(timeout: RESP_READ_TIMEOUT, len: RESP_READ_LEN) ⇒ String
Reads all that is available on the socket.
-
#read_body(timeout: nil, len: nil) ⇒ String
Reads the response body on the socket.
-
#read_response(timeout: nil, len: nil) ⇒ Response
Reads the HTTP response on the socket.
-
#req_write(req = nil)
Alias for #send_http.
-
#send_http(req = nil) ⇒ self
(also: #<<, #req_write)
Writes the request/data to the socket.
-
#send_http_read_body(req = nil, timeout: nil, len: nil) ⇒ String
Writes the request/data to the socket and returns the response body.
-
#send_http_read_response(req = nil, timeout: nil, len: nil) ⇒ Response
Writes the request/data to the socket and returns the response.
-
#wait_read(len, timeout: 5) ⇒ String
Uses a single
sysreadstatement to read the socket.
Instance Method Details
#<<(req = nil)
Alias for #send_http.
# File 'test/helpers/test_puma/puma_socket_include.rb', line 151
alias_method :<<, :send_http
#read_all(timeout: RESP_READ_TIMEOUT, len: RESP_READ_LEN) ⇒ String
Reads all that is available on the socket. Used for reading sockets that contain multiple responses.
# File 'test/helpers/test_puma/puma_socket_include.rb', line 29
def read_all(timeout: RESP_READ_TIMEOUT, len: RESP_READ_LEN) timeout ||= RESP_READ_TIMEOUT read_len = len || RESP_READ_LEN end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) + timeout read = String.new # rubocop: disable Performance/UnfreezeString prev_size = 0 loop do raise(Timeout::Error, 'Client Read Timeout') if Process.clock_gettime(Process::CLOCK_MONOTONIC) > end_time if wait_readable 1 read << sysread(read_len) end ttl_read = read.bytesize return read if prev_size == ttl_read && !ttl_read.zero? prev_size = ttl_read end rescue EOFError return read rescue => e raise e end
#read_body(timeout: nil, len: nil) ⇒ String
Reads the response body on the socket. Assumes one response, use #read_all to read multiple responses.
# File 'test/helpers/test_puma/puma_socket_include.rb', line 55
def read_body(timeout: nil, len: nil) self.read_response(timeout: timeout, len: len).split(RESP_SPLIT, 2).last end
#read_response(timeout: nil, len: nil) ⇒ Response
Reads the HTTP response on the socket. Assumes one response, use #read_all to read multiple responses.
# File 'test/helpers/test_puma/puma_socket_include.rb', line 64
def read_response(timeout: nil, len: nil) content_length = nil chunked = nil status = nil no_body = nil response = Response.new read_len = len || RESP_READ_LEN timeout ||= RESP_READ_TIMEOUT time_start = Process.clock_gettime(Process::CLOCK_MONOTONIC) time_end = time_start + timeout times = [] time_read = nil loop do begin self.to_io.wait_readable timeout time_read ||= Process.clock_gettime(Process::CLOCK_MONOTONIC) part = self.read_nonblock(read_len, exception: false) case part when String times << (Process.clock_gettime(Process::CLOCK_MONOTONIC) - time_read).round(4) status ||= part[/\AHTTP\/1\.[01] (\d{3})/, 1] if status no_body ||= NO_ENTITY_BODY.key?(status.to_i) || status.to_i < 200 end if no_body && part.end_with?(RESP_SPLIT) response.times = times return response << part end unless content_length || chunked chunked ||= part.downcase.include? "\r\ntransfer-encoding: chunked\r\n" content_length = (t = part[/^Content-Length: (\d+)/i , 1]) ? t.to_i : nil end response << part hdrs, body = response.split RESP_SPLIT, 2 unless body.nil? # below could be simplified, but allows for debugging... finished = if content_length body.bytesize == content_length elsif chunked body.end_with? "0\r\n\r\n" elsif !hdrs.empty? && !body.empty? true else false end response.times = times return response if finished end sleep 0.000_1 when :wait_readable # continue loop when :wait_writable # :wait_writable for ssl to = time_end - Process.clock_gettime(Process::CLOCK_MONOTONIC) self.to_io.wait_writable to when nil if response.empty? raise EOFError else response.times = times return response end end timeout = time_end - Process.clock_gettime(Process::CLOCK_MONOTONIC) if timeout <= 0 raise Timeout::Error, 'Client Read Timeout' end end end end
#req_write(req = nil)
Alias for #send_http.
# File 'test/helpers/test_puma/puma_socket_include.rb', line 152
alias_method :req_write, :send_http
#send_http(req = nil) ⇒ self
Also known as: #<<, #req_write
Writes the request/data to the socket. Returns self
# File 'test/helpers/test_puma/puma_socket_include.rb', line 142
def send_http(req = nil) req ||= PumaSocket::GET_11 if String === req sent = 0 size = req.bytesize sent += syswrite(req.byteslice(sent, size - sent)) while sent < size end self end
#send_http_read_body(req = nil, timeout: nil, len: nil) ⇒ String
Writes the request/data to the socket and returns the response body. Assumes one response, use #read_all to read multiple responses.
# File 'test/helpers/test_puma/puma_socket_include.rb', line 160
def send_http_read_body(req = nil, timeout: nil, len: nil) req ||= PumaSocket::GET_11 send_http_read_response(req, timeout: timeout, len: len) .split(RESP_SPLIT, 2).last end
#send_http_read_response(req = nil, timeout: nil, len: nil) ⇒ Response
Writes the request/data to the socket and returns the response. Assumes one response, use #read_all to read multiple responses.
# File 'test/helpers/test_puma/puma_socket_include.rb', line 172
def send_http_read_response(req = nil, timeout: nil, len: nil) req ||= PumaSocket::GET_11 send_http(req).read_response(timeout: timeout, len: len) end
#wait_read(len, timeout: 5) ⇒ String
Uses a single sysread statement to read the socket. Reads len bytes from the socket. A wait_readable call using timeout: preceeds it.
# File 'test/helpers/test_puma/puma_socket_include.rb', line 183
def wait_read(len, timeout: 5) Thread.pass self.wait_readable timeout Thread.pass sysread len end