Module ServerSide::HTTP::Parsing
In: lib/serverside/http/parsing.rb

Methods

Constants

REQUEST_LINE_RE = /([A-Za-z0-9]+)\s(\/[^\/\?]*(?:\/[^\/\?]+)*)\/?(?:\?(.*))?\sHTTP\/(.+)/.freeze
HEADER_RE = /([^:]+):\s*(.*)/.freeze
HYPHEN = '-'.freeze
UNDERSCORE = '_'.freeze
AMPERSAND = '&'.freeze
PARAMETER_RE = /^(.{1,64})=(.{0,8192})$/.freeze
COOKIE_RE = /^(.+)=(.*)$/.freeze
SEMICOLON = ';'.freeze
BOUNDARY_FIX = '--'.freeze

Public Instance methods

[Source]

    # File lib/serverside/http/parsing.rb, line 25
25:     def header_to_sym(h)
26:       h.downcase.gsub(HYPHEN, UNDERSCORE).to_sym
27:     end

Parses the request body.

[Source]

     # File lib/serverside/http/parsing.rb, line 94
 94:     def parse_body(body)
 95:       @body = body
 96:       case @headers[:content_type]
 97:       when MULTIPART_FORM_DATA_RE:
 98:         parse_multi_part(body, BOUNDARY_FIX + $1) # body.dup so we keep the original request body?
 99:       when FORM_URL_ENCODED:
100:         parse_form_url_encoded(body)
101:       end
102:     end

Parses a cookies header.

[Source]

    # File lib/serverside/http/parsing.rb, line 81
81:     def parse_cookies(cookies)
82:       cookies.split(SEMICOLON).each do |c|
83:         if c.strip =~ COOKIE_RE
84:           @cookies[$1.to_sym] = $2.uri_unescape
85:         else
86:           raise BadRequestError, "Invalid cookie format"
87:         end
88:       end
89:     end

Parses query parameters passed in the body (for POST requests.)

[Source]

     # File lib/serverside/http/parsing.rb, line 152
152:     def parse_form_url_encoded(body)
153:       @params ||= {}
154:       @params.merge!(parse_query_parameters(body))
155:     end

Parses an HTTP header.

[Source]

    # File lib/serverside/http/parsing.rb, line 30
30:     def parse_header(line)
31:       # check header count
32:       if (@header_count += 1) > MAX_HEADER_COUNT
33:         raise BadRequestError, "Too many headers"
34:       end
35: 
36:       if line =~ HEADER_RE
37:         if $1.size > MAX_HEADER_NAME_SIZE
38:           raise BadRequestError, "Invalid header size"
39:         end
40:         k = header_to_sym($1)
41:         v = $2.freeze
42:         case k
43:         when :content_length: @content_length = v.to_i
44:         when :connection: @persistent = v == KEEP_ALIVE
45:         when :cookie: parse_cookies(v)
46:         end
47:         @headers[k] = v
48:       else
49:         raise BadRequestError, "Invalid header format"
50:       end
51:     end

Parses a multipart request body.

[Source]

     # File lib/serverside/http/parsing.rb, line 105
105:     def parse_multi_part(body, boundary)
106:       while part = body.get_up_to_boundary_with_crlf(boundary)
107:         unless part.empty?
108:           parse_part(part)
109:         end
110:       end
111:     end

Parses a part of a multipart body.

[Source]

     # File lib/serverside/http/parsing.rb, line 114
114:     def parse_part(part)
115:       part_name = nil
116:       file_name = nil
117:       file_type = nil
118:       # part headers
119:       while (line = part.get_line)
120:         break if line.empty?
121:         if line =~ HEADER_RE
122:           k = $1.freeze
123:           v = $2.freeze
124:           case k
125:           when CONTENT_DISPOSITION:
126:             case v
127:             when DISPOSITION_FORM_DATA_RE:
128:               p [$1, $2, $3]
129:               part_name = $1.to_sym
130:               file_name = $3
131:             end
132:           when CONTENT_TYPE:
133:             file_type = v
134:           end
135:         else
136:           raise BadRequestError, "Invalid header in part"
137:         end
138:       end
139:       # check if we got the content name
140:       unless part_name
141:         raise BadRequestError, "Invalid part content"
142:       end
143:       # part body
144:       part_body = part.chomp! # what's left of it
145:       @params ||= {}
146:       @params[part_name] = file_name ? 
147:         {:file_name => file_name, :file_content => part_body, :file_type => file_type} :
148:         part_body
149:     end

Parses query parameters by splitting the query string and unescaping parameter values.

[Source]

    # File lib/serverside/http/parsing.rb, line 58
58:     def parse_query_parameters(query)
59:       query.split(AMPERSAND).inject({}) do |m, i|
60:         if i =~ PARAMETER_RE
61:           k = $1
62:           if k.size > MAX_PARAMETER_NAME_SIZE
63:             raise BadRequestError, "Invalid parameter size"
64:           end
65:           v = $2
66:           if v.size > MAX_PARAMETER_VALUE_SIZE
67:             raise BadRequestError, "Invalid parameter size"
68:           end
69:           m[k.to_sym] = v.uri_unescape
70:         else
71:           raise BadRequestError, "Invalid parameter format"
72:         end
73:         m
74:       end
75:     end

Parses a request line into a method, URI, query and HTTP version parts. If a query is included, it is parsed into query parameters.

[Source]

    # File lib/serverside/http/parsing.rb, line 7
 7:     def parse_request_line(line)
 8:       if line =~ REQUEST_LINE_RE
 9:         @request_line = line
10:         @method, @path, @query, @http_version = $1.downcase.to_sym, $2, $3, $4
11:         @params = @query ? parse_query_parameters(@query) : {}
12:         
13:         # HTTP 1.1 connections are persistent by default.
14:         @persistent = @http_version == VERSION_1_1
15:       else
16:         raise BadRequestError, "Invalid request format"
17:       end
18:     end

[Validate]