You are currently browsing the category archive for the ‘Snippits’ category.

Getting a line feed into an input on *nix is pretty easy, all you do is hit return in the middle of a quoted input:

  % ruby -e 'puts ARGV.inspect' 'line one
  > line two'
  ["line one\nline two"]

On Windows, it’s more verbose.  Use a caret, the MS-DOS escape character, to ignore the next line feed:

  % ruby -e 'puts ARGV.inspect' 'line one^
  More?
  More? line two'
  ["line one\nline two"]

Notice that pressing enter every other line is what actually puts the “\n” into the argument . Keep using carets to enter more lines.

The syntax on Windows isn’t exactly pretty, and sadly it doesn’t work with gem executables; the .bat scripts generated by rubygems re-processes inputs before calling the .rb executable and the extra lines get lost in translation.  Still, it’s nice to know it’s (sort-of) possible!

Advertisements

Most of the time a web server parses HTTP requests before you get access to them in your code. Time to time however, it’s nice to actually see what the HTTP from a web form looks like, and you may have manipulate the message programatically.

Firefox has a plugin called LiveHTTPHeaders that lets you capture and view HTTP requests as they get sent out. These you can save to files and then load into Ruby using the following code:

  require 'webrick'  req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)

  File.open("path/to/http.txt', 'rb') do |socket|
    req.parse(socket)
  end

Now req can be used as any other WEBrick::HTTPRequest. The input to parse can be any IO (like File or StringIO). The request will begin parsing an HTTP header from wherever the IO is positioned, and continues parsing until it reaches an empty line. This method works with multipart/form data as well. For example:

  POST /path HTTP/1.1
  Content-Type: multipart/form-data; boundary=1234567890
  Content-Length: 158

  --1234567890
  Content-Disposition: form-data; name="one"

  value one
  --1234567890
  Content-Disposition: form-data; name="two"

  value two
  --1234567890--

Used in conjunction with the code above, this message result in the following:

  req.header   # => {"content-type" => ["multipart/form-data; boundary=1234567890"],
                     "content-length" => ["158"]}
  req.query     # => {"one" => "value one", "two" => "value two"}

A couple notes about parsing HTTP using WEBrick in the current (1.8.6) version of Ruby:

  • As mentioned, WEBrick considers an empty line as a break between the headers and body of a message. The capture for multipart/form requests from LiveHTTPHeaders lacks this breaks, so you’ll have to add it if you’re using that tool. You should be ok if you’re parsing a non-multipart request.
  • Header parsing is forgiving with end-line characters (ie “\r\n” and “\n” are both acceptable) but parsing of multipart/form data IS NOT. Multipart/form data requires that the end-line characters are “\r\n”. On Windows, therefore, it is absolutely ESSENTIAL to open file data in binary mode (ex ‘rb’, as above) to preserve these characters.