Module: Syntropy::HTTP::ProtocolMethods
- Defined in:
- lib/syntropy/http/io_extensions.rb
Constant Summary collapse
- RE_REQUEST_LINE =
/^(get|head|options|trace|put|delete|post|patch|connect)\s+([^\s]+)\s+HTTP\/([019\.]{1,3})/i- RE_RESPONSE_LINE =
/^HTTP\/1\.1\s+(\d{3})(\s+.+)?$/i- RE_HEADER_LINE =
/^([a-z0-9\-]+):\s+(.+)/i- MAX_REQUEST_LINE_LEN =
16KB
1 << 14
- MAX_RESPONSE_LINE_LEN =
256
1 << 8
- MAX_HEADER_LINE_LEN =
8KB
1 << 13
- MAX_CHUNK_SIZE_LEN =
16
Instance Method Summary collapse
- #http_read_body(headers) ⇒ Object
- #http_read_body_chunk(headers) ⇒ Object
-
#http_read_request_headers ⇒ Hash
Headers.
- #http_read_response_headers ⇒ Object
- #http_skip_body(headers) ⇒ Object
- #http_write_request_headers(headers) ⇒ Object
Instance Method Details
#http_read_body(headers) ⇒ Object
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/syntropy/http/io_extensions.rb', line 76 def http_read_body(headers) content_length = headers['content-length'] if content_length chunk = read(content_length.to_i) return chunk end chunked_encoding = headers['transfer-encoding']&.downcase == 'chunked' if chunked_encoding buf = +'' while (chunk = http_read_cte_chunk(nil)) buf << chunk end return buf end nil end |
#http_read_body_chunk(headers) ⇒ Object
110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/syntropy/http/io_extensions.rb', line 110 def http_read_body_chunk(headers) content_length = headers['content-length'] if content_length chunk = read(content_length.to_i) return chunk end chunked_encoding = headers['transfer-encoding']&.downcase == 'chunked' return http_read_cte_chunk(nil) if chunked_encoding nil end |
#http_read_request_headers ⇒ Hash
Returns headers.
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/syntropy/http/io_extensions.rb', line 18 def http_read_request_headers line = read_line(MAX_REQUEST_LINE_LEN) return nil if !line m = line.match(RE_REQUEST_LINE) raise ProtocolError, 'Invalid request line' if !m http_version = m[3] raise UnsupportedHTTPVersionError, 'HTTP version not supported' if http_version != '1.1' headers = { ':method' => m[1].downcase, ':path' => m[2] } loop do line = read_line(MAX_HEADER_LINE_LEN) break if line.nil? || line.empty? m = line.match(RE_HEADER_LINE) raise ProtocolError, "Invalid header: #{line[0..2047].inspect}" if !m headers[m[1].downcase] = m[2] end headers end |
#http_read_response_headers ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/syntropy/http/io_extensions.rb', line 46 def http_read_response_headers line = read_line(MAX_RESPONSE_LINE_LEN) return nil if !line m = line.match(RE_RESPONSE_LINE) raise ProtocolError, 'Invalid response line' if !m headers = { ':status' => m[1].to_i } loop do line = read_line(MAX_HEADER_LINE_LEN) break if line.nil? || line.empty? m = line.match(RE_HEADER_LINE) raise ProtocolError, "Invalid header: #{line[0..2047].inspect}" if !m k = m[1].downcase if (h = headers[k]) (h = headers[k] = [h]) if !h.is_a?(Array) h << m[2] else headers[k] = m[2] end end headers end |
#http_skip_body(headers) ⇒ Object
95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/syntropy/http/io_extensions.rb', line 95 def http_skip_body(headers) content_length = headers['content-length'] if content_length return skip(content_length.to_i) end chunked_encoding = headers['transfer-encoding']&.downcase == 'chunked' if chunked_encoding while http_skip_cte_chunk end end nil end |
#http_write_request_headers(headers) ⇒ Object
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/syntropy/http/io_extensions.rb', line 123 def http_write_request_headers(headers) method = headers[':method'] || (raise BadRequestError) path = headers[':path'] || (raise BadRequestError) lines = ["#{method} #{path} HTTP/1.1\r\n"] headers.each do |k, v| next if k =~ /^\:/ if v.is_a?(Array) v.each { lines << "#{k}: #{it}\r\n" } else lines << "#{k}: #{v}\r\n" end end lines << "\r\n" write(*lines) end |