Class: Segregate
- Inherits:
-
Object
- Object
- Segregate
- Defined in:
- lib/segregate.rb,
lib/segregate/version.rb,
lib/segregate/http_headers.rb,
lib/segregate/http_methods.rb,
lib/segregate/http_regular_expressions.rb
Constant Summary collapse
- VERSION =
"0.6.0".freeze
- DATE =
"2016-12-13".freeze
- GENERAL_HEADERS =
[ "cache-control", "connection", "date", "pragma", "trailer", "transfer-encoding", "upgrade", "via", "warning" ]
- REQUEST_HEADERS =
[ "accept", "accept-charset", "accept-encoding", "accept-language", "authorization", "expect", "from", "host", "if-match", "if-modified-Since", "if-none-Match", "if-range", "if-unmodified-Since", "max-forwards", "proxy-authorization", "range", "referer", "te", "user-agent" ]
- RESPONSE_HEADERS =
[ "accept-ranges", "age", "etag", "location", "proxy-authenticate", "retry-after", "server", "vary", "www-authenticate" ]
- ENTITY_HEADERS =
[ "allow", "content-encoding", "content-language", "content-length", "content-location", "content-md5", "content-range", "content-type", "expires", "last-modified" ]
- ALL_HEADERS =
GENERAL_HEADERS + REQUEST_HEADERS + RESPONSE_HEADERS + ENTITY_HEADERS
- HTTP_METHODS =
[ "OPTIONS", "GET", "HEAD", "POST", "PUT", "DELETE", "TRACE", "CONNECT", "PATCH" ]
- REQUEST_LINE =
/^(#{HTTP_METHODS.join("|")})\s(\*|\S+)\sHTTP\/(\d).(\d)$/
- STATUS_LINE =
/^HTTP\/(\d).(\d)\s(\d{3})\s(.+)$/
- UNKNOWN_REQUEST_LINE =
/^(\w+)\s(\*|\S+)\sHTTP\/(\d).(\d)$/
Instance Attribute Summary collapse
-
#body ⇒ Object
Returns the value of attribute body.
-
#headers ⇒ Object
readonly
Returns the value of attribute headers.
-
#http_version ⇒ Object
readonly
Returns the value of attribute http_version.
-
#request_method ⇒ Object
Returns the value of attribute request_method.
-
#state ⇒ Object
readonly
Returns the value of attribute state.
-
#status_code ⇒ Object
Returns the value of attribute status_code.
-
#status_phrase ⇒ Object
Returns the value of attribute status_phrase.
-
#type ⇒ Object
readonly
Returns the value of attribute type.
-
#uri ⇒ Object
readonly
Returns the value of attribute uri.
Instance Method Summary collapse
- #build_body(raw_message) ⇒ Object
- #build_headers(raw_message) ⇒ Object
- #debug(message) ⇒ Object
- #deflate_if_needed(body) ⇒ Object
- #done? ⇒ Boolean
- #headers_complete? ⇒ Boolean
-
#initialize(callback = nil, *args, **kwargs) ⇒ Segregate
constructor
A new instance of Segregate.
- #major_http_version ⇒ Object
- #major_http_version=(value) ⇒ Object
- #method_missing(meth, *args, &block) ⇒ Object
- #minor_http_version ⇒ Object
- #minor_http_version=(value) ⇒ Object
- #parse_data(data) ⇒ Object
- #parse_line(line) ⇒ Object
- #raw_data ⇒ Object
- #request? ⇒ Boolean
- #request_line ⇒ Object
- #request_url ⇒ Object
- #respond_to?(meth, include_private = false) ⇒ Boolean
- #response? ⇒ Boolean
- #status_line ⇒ Object
- #update_content_length ⇒ Object
Constructor Details
#initialize(callback = nil, *args, **kwargs) ⇒ Segregate
Returns a new instance of Segregate.
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/segregate.rb', line 31 def initialize callback = nil, *args, **kwargs @debug = kwargs[:debug] ? true : false @callback = callback @http_version = [nil, nil] # :request, :response @type = Juncture.new :request, :response @state = Juncture.new :waiting, :headers, :body, :done, default: :waiting @headers = Hashie::Mash.new @body = "" @stashed_data = "" @stashed_body = "" @header_order = [] end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(meth, *args, &block) ⇒ Object
13 14 15 16 17 18 19 |
# File 'lib/segregate.rb', line 13 def method_missing meth, *args, &block if @uri.respond_to? meth @uri.send meth, *args, &block else super end end |
Instance Attribute Details
#body ⇒ Object
Returns the value of attribute body.
11 12 13 |
# File 'lib/segregate.rb', line 11 def body @body end |
#headers ⇒ Object (readonly)
Returns the value of attribute headers.
10 11 12 |
# File 'lib/segregate.rb', line 10 def headers @headers end |
#http_version ⇒ Object (readonly)
Returns the value of attribute http_version.
10 11 12 |
# File 'lib/segregate.rb', line 10 def http_version @http_version end |
#request_method ⇒ Object
Returns the value of attribute request_method.
11 12 13 |
# File 'lib/segregate.rb', line 11 def request_method @request_method end |
#state ⇒ Object (readonly)
Returns the value of attribute state.
10 11 12 |
# File 'lib/segregate.rb', line 10 def state @state end |
#status_code ⇒ Object
Returns the value of attribute status_code.
11 12 13 |
# File 'lib/segregate.rb', line 11 def status_code @status_code end |
#status_phrase ⇒ Object
Returns the value of attribute status_phrase.
11 12 13 |
# File 'lib/segregate.rb', line 11 def status_phrase @status_phrase end |
#type ⇒ Object (readonly)
Returns the value of attribute type.
10 11 12 |
# File 'lib/segregate.rb', line 10 def type @type end |
#uri ⇒ Object (readonly)
Returns the value of attribute uri.
10 11 12 |
# File 'lib/segregate.rb', line 10 def uri @uri end |
Instance Method Details
#build_body(raw_message) ⇒ Object
126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/segregate.rb', line 126 def build_body new_body, size = deflate_if_needed(@body) if @headers['content-length'] << new_body << "\r\n\r\n" elsif @headers['transfer-encoding'] == 'chunked' << "%s\r\n" % (size.to_s(16)) << new_body + "\r\n" << "0\r\n\r\n" end end |
#build_headers(raw_message) ⇒ Object
111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/segregate.rb', line 111 def build_headers request? ? << request_line + "\r\n" : << status_line + "\r\n" @header_order.each do |header| values = @headers[header.downcase] if values.kind_of?(Array) values.each do |value| << "%s: %s\r\n" % [header, value] end else << "%s: %s\r\n" % [header, values] end end << "\r\n" end |
#debug(message) ⇒ Object
25 26 27 28 29 |
# File 'lib/segregate.rb', line 25 def debug if @debug puts "DEBUG: " + .to_s end end |
#deflate_if_needed(body) ⇒ Object
138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/segregate.rb', line 138 def deflate_if_needed(body) return [body, body.size] unless gzip_encoded_body? str_io = StringIO.new('w') w_gz = Zlib::GzipWriter.new(str_io) w_gz.write(body) w_gz.close # To specify the number of bytes for a gzip string # we should check for the buffer size instead of the string size [str_io.string, str_io.size] end |
#done? ⇒ Boolean
61 62 63 |
# File 'lib/segregate.rb', line 61 def done? @state >= :done end |
#headers_complete? ⇒ Boolean
57 58 59 |
# File 'lib/segregate.rb', line 57 def headers_complete? @state > :headers end |
#major_http_version ⇒ Object
77 78 79 |
# File 'lib/segregate.rb', line 77 def major_http_version http_version[0] end |
#major_http_version=(value) ⇒ Object
81 82 83 |
# File 'lib/segregate.rb', line 81 def major_http_version= value http_version[0] = value end |
#minor_http_version ⇒ Object
85 86 87 |
# File 'lib/segregate.rb', line 85 def minor_http_version http_version[1] end |
#minor_http_version=(value) ⇒ Object
89 90 91 |
# File 'lib/segregate.rb', line 89 def minor_http_version= value http_version[1] = value end |
#parse_data(data) ⇒ Object
151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/segregate.rb', line 151 def parse_data data data = StringIO.new(@stashed_data + data) @stashed_data = "" while !data.eof? && @state < :done line, complete_line = get_next_line data complete_line ? parse_line(line) : @stashed_data = line end data.close end |
#parse_line(line) ⇒ Object
163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/segregate.rb', line 163 def parse_line line case @state.state when :waiting read_in_first_line line when :headers read_in_headers line when :body read_in_body line end @callback. self if @callback.respond_to?(:on_message_complete) && done? end |
#raw_data ⇒ Object
101 102 103 104 105 106 107 108 109 |
# File 'lib/segregate.rb', line 101 def raw_data = "" update_content_length build_headers build_body return end |
#request? ⇒ Boolean
49 50 51 |
# File 'lib/segregate.rb', line 49 def request? @type == :request end |
#request_line ⇒ Object
65 66 67 |
# File 'lib/segregate.rb', line 65 def request_line request? ? "%s %s HTTP/%d.%d" % [request_method, request_url.to_s, *http_version] : nil end |
#request_url ⇒ Object
73 74 75 |
# File 'lib/segregate.rb', line 73 def request_url uri ? uri.to_s : nil end |
#respond_to?(meth, include_private = false) ⇒ Boolean
21 22 23 |
# File 'lib/segregate.rb', line 21 def respond_to?(meth, include_private = false) @uri.respond_to?(meth, include_private) || super end |
#response? ⇒ Boolean
53 54 55 |
# File 'lib/segregate.rb', line 53 def response? @type == :response end |
#status_line ⇒ Object
69 70 71 |
# File 'lib/segregate.rb', line 69 def status_line response? ? "HTTP/%d.%d %d %s" % [*http_version, status_code, status_phrase] : nil end |
#update_content_length ⇒ Object
93 94 95 96 97 98 99 |
# File 'lib/segregate.rb', line 93 def update_content_length unless @body.empty? if @headers['content-length'] @headers['content-length'] = @body.length.to_s end end end |