Class: Mongrel::HttpRequest
- Inherits:
-
Object
- Object
- Mongrel::HttpRequest
- Defined in:
- lib/mongrel.rb
Overview
When a handler is found for a registered URI then this class is constructed and passed to your HttpHandler::process method. You should assume that one handler processes all requests. Included in the HttpRequest is a HttpRequest.params Hash that matches common CGI params, and a HttpRequest.body which is a string containing the request body (raw for now).
The HttpRequest.initialize method will convert any request that is larger than Const::MAX_BODY into a Tempfile and use that as the body. Otherwise it uses a StringIO object. To be safe, you should assume it works like a file.
The HttpHandler.request_notify system is implemented by having HttpRequest call HttpHandler.request_begins, HttpHandler.request_progress, HttpHandler.process during the IO processing. This adds a small amount of overhead but lets you implement finer controlled handlers and filters.
Instance Attribute Summary collapse
-
#body ⇒ Object
readonly
Returns the value of attribute body.
-
#params ⇒ Object
readonly
Returns the value of attribute params.
Class Method Summary collapse
-
.escape(s) ⇒ Object
Performs URI escaping so that you can construct proper query strings faster.
-
.query_parse(qs, d = '&;') ⇒ Object
Parses a query string by breaking it up at the ‘&’ and ‘;’ characters.
-
.unescape(s) ⇒ Object
Unescapes a URI escaped string.
Instance Method Summary collapse
-
#initialize(params, initial_body, socket, notifier) ⇒ HttpRequest
constructor
You don’t really call this.
Constructor Details
#initialize(params, initial_body, socket, notifier) ⇒ HttpRequest
You don’t really call this. It’s made for you. Main thing it does is hook up the params, and store any remaining body data into the HttpRequest.body attribute.
TODO: Implement tempfile removal when the request is done.
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
# File 'lib/mongrel.rb', line 189 def initialize(params, initial_body, socket, notifier) @params = params @socket = socket clen = params[Const::CONTENT_LENGTH].to_i - initial_body.length total = clen if clen > Const::MAX_BODY @body = Tempfile.new(Const::MONGREL_TMP_BASE) @body.binmode else @body = StringIO.new end begin @body.write(initial_body) notifier.request_begins(params) if notifier # write the odd sized chunk first clen -= @body.write(@socket.read(clen % Const::CHUNK_SIZE)) notifier.request_progress(params, clen, total) if notifier # then stream out nothing but perfectly sized chunks while clen > 0 and !@socket.closed? data = @socket.read(Const::CHUNK_SIZE) # have to do it this way since @socket.eof? causes it to block raise "Socket closed or read failure" if not data or data.length != Const::CHUNK_SIZE clen -= @body.write(data) # ASSUME: we are writing to a disk and these writes always write the requested amount notifier.request_progress(params, clen, total) if notifier end # rewind to keep the world happy @body.rewind rescue Object # any errors means we should delete the file, including if the file is dumped @socket.close unless @socket.closed? @body.delete if @body.class == Tempfile @body = nil # signals that there was a problem end end |
Instance Attribute Details
#body ⇒ Object (readonly)
Returns the value of attribute body.
182 183 184 |
# File 'lib/mongrel.rb', line 182 def body @body end |
#params ⇒ Object (readonly)
Returns the value of attribute params.
182 183 184 |
# File 'lib/mongrel.rb', line 182 def params @params end |
Class Method Details
.escape(s) ⇒ Object
Performs URI escaping so that you can construct proper query strings faster. Use this rather than the cgi.rb version since it’s faster. (Stolen from Camping).
234 235 236 237 238 |
# File 'lib/mongrel.rb', line 234 def self.escape(s) s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/n) { '%'+$1.unpack('H2'*$1.size).join('%').upcase }.tr(' ', '+') end |
.query_parse(qs, d = '&;') ⇒ Object
Parses a query string by breaking it up at the ‘&’ and ‘;’ characters. You can also use this to parse cookies by changing the characters used in the second parameter (which defaults to ‘&;’.
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 |
# File 'lib/mongrel.rb', line 252 def self.query_parse(qs, d = '&;') params = {} (qs||'').split(/[#{d}] */n).inject(params) { |h,p| k, v=unescape(p).split('=',2) if cur = params[k] if cur.class == Array params[k] << v else params[k] = [cur, v] end else params[k] = v end } return params end |
.unescape(s) ⇒ Object
Unescapes a URI escaped string. (Stolen from Camping).
242 243 244 245 246 |
# File 'lib/mongrel.rb', line 242 def self.unescape(s) s.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n){ [$1.delete('%')].pack('H*') } end |