Module: Syntropy::HTTP::ProtocolMethods
- Defined in:
- lib/syntropy/http/io_extensions.rb
Constant Summary collapse
- RE_REQUEST_LINE =
/^([a-z]+)\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 =
1KB
1 << 10
- 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_write_request_headers(headers) ⇒ Object
Instance Method Details
#http_read_body(headers) ⇒ Object
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/syntropy/http/io_extensions.rb', line 77 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
96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/syntropy/http/io_extensions.rb', line 96 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 45 |
# 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], ':protocol' => 'http/1.1' } 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
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 75 |
# File 'lib/syntropy/http/io_extensions.rb', line 47 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_write_request_headers(headers) ⇒ Object
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/syntropy/http/io_extensions.rb', line 109 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 |