Damon McCormick's blog



Damon McCormickDamon McCormick
Standup 04/07/2009: We Have Questions
edit Posted by Damon McCormick on Friday April 10, 2009 at 05:22AM

Interesting

  • Nothing interesting happened on the internet yesterday. Sorry to get your hopes up.

Help

"Using compass and sass to generate css, how do we get line numbers in the compiled css indicating the corresponding sass declaration?"

The suggested answer is using the non-silent variety of sass comments in an old skool pragma-mark type fashion.

"Is there a canonical setup for dealing with failover when you have two HA proxy load balancers and round-robin DNS across their two IP addresses?"

Damon McCormickDamon McCormick
Standup 04/09/2009: An Answer to a previous question
edit Posted by Damon McCormick on Thursday April 09, 2009 at 05:09PM

Interesting

  • Regarding compass, sass, and line numbers, Chris Eppstein dropped some knowledge in the comments section on the 4/7/09 entry:
    config.after_initialize do
      Sass::Plugin.options[:line_comments] = true
    end

That will grants you wondrous and magical comments in your css. Cheers, Chris!

Damon McCormickDamon McCormick
Standup 04/08/2009: IE is wack, yo!
edit Posted by Damon McCormick on Wednesday April 08, 2009 at 04:16PM

Help

"IE does not let you float an element in front of a select -- how can I get around that?"

Use an iframe; jquery has an example in they're modal dialog box

Damon McCormickDamon McCormick
Standup 04/27/07: Testing File Uploads
edit Posted by Damon McCormick on Friday April 27, 2007 at 05:48PM

The setup:

I'm told file uploading is a pain to test. We needed to. So we cruised through the tubes over to ruby-doc.org to check out the Net::HTTP rdoc -- only to find that Net:HTTP::Post does not support multipart uploading and files. What to do, what to DO?!?

The research:

Some googling later, we find this article showing how to do it. A little copy-paste, a small spike later, and we have an external script capable of uploading files into our web-apps. But, lets brain-storm a little...

  • How can we make it better?
  • What would be a nice interface?

Well, the first step is to change the script such that it can be more easily integrated into rake test:functionals: make it less script-y; more library. The interface is somewhat inspired by the basic_auth method. All you have to say is Net::HTTP::Post.new().multipart_params = {}? You give it a hash, and it takes care of the rest. Huzzah! So lets open up Net::HTTP::POST and give it some new methods. Time for some CODE!!!

The Code

require 'net/https'
require "rubygems"
require "mime/types"
require "base64"
require 'cgi'

class Net::HTTP::Post
  def multipart_params=(param_hash={})
    boundary_token = [Array.new(8) {rand(256)}].join
    self.content_type = "multipart/form-data; boundary=#{boundary_token}"
    boundary_marker = "--#{boundary_token}\r\n"
    self.body = param_hash.map { |param_name, param_value|
      boundary_marker + case param_value
      when String
        text_to_multipart(param_name, param_value)
      when File
        file_to_multipart(param_name, param_value)
      end
    }.join('') + "--#{boundary_token}--\r\n"
  end

  protected
  def file_to_multipart(key,file)
    filename = File.basename(file.path)
    mime_types = MIME::Types.of(filename)
    mime_type = mime_types.empty? ? "application/octet-stream" : mime_types.first.content_type
    part = %Q|Content-Disposition: form-data; name="#{key}"; filename="#{filename}"\r\n|
    part += "Content-Transfer-Encoding: binary\r\n"
    part += "Content-Type: #{mime_type}\r\n\r\n#{file.read}"
  end

  def text_to_multipart(key,value)
    "Content-Disposition: form-data; name=\"#{key}\"\r\n\r\n#{value}\r\n"
  end
end

Oh the utility:

Now that's more like it. Hackish, since you have to stick headers into the request body, but effective. Notice the bit in there about MIME::Types. Did you see that? Yeah, we went there. Say it with me... Automatic mime type detection with a safe default. The absurd thing in there is that the MIME::Types gem (as of today) does not know about .rb files.

irb(main):007:0> MIME::Types.of('something.rb')                   
=> []

So now that you have that, it's just a simple use of Net::HTTP with a blizzock to upload a file in a functional test.

File.open(File.expand_path('script/test.png'), 'r') do |file|
  http = Net::HTTP.new('localhost', 3000)
  begin
    http.start do |http|
      request = Net::HTTP::Post.new('/your/url/here')
      request.basic_auth 'lonely_user', 'really_long_password'
      request.multipart_params = {'file' => file, 'title' => 'title'}
      response = http.request(request)
      response.value
      puts response.body
    end
  rescue Net::HTTPServerException => e
    p e
  end
end

The questions:

So what do you think? How can this be made even better?