Uploading a multipart form with Net::HTTP

Did anyone ever figure this out?

Chris Morris had a message that indicated that he couldn't get it
working, back in 2003. I have a desparate need for this to work, and
I'm not really sure where to begin.

-austin

···

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca
: as of this email, I have [ 6 ] Gmail invitations

Austin,

This stuff might be useful. This was part of a wiki migration script. I modified it so you wouldn't have to install narf to use it, but you'll need to find a replacement for Web::Mime::get_mime_type in FileParam#to_multipart. Or you could hard code the mime-type.

Cheers,

Patrick

···

------------------

require 'open-uri'
require 'net/http'
require 'cgi'

def post( query, headers={} )
   Net::HTTP.start( "www.yourserver.com", 80 ) { |h|
     h.post( "/cgi-bin/your_script.rb", query, headers )
   }
end

class Param
   attr_accessor :k, :v
   def initialize( k, v )
     @k = k
     @v = v
   end

   def to_multipart
     return "Content-Disposition: form-data; name=\"#{CGI::escape(k)}\"\r\n\r\n#{v}\r\n"
   end
end

class FileParam
   attr_accessor :k, :filename, :content
   def initialize( k, filename, content )
     @k = k
     @filename = filename
     @content = content
   end

   def to_multipart
     return "Content-Disposition: form-data; name=\"#{CGI::escape(k)}\"; filename=\"#{filename}\"\r\n" +
          "Content-Transfer-Encoding: binary\r\n" +
            "Content-Type: #{Web::Mime.get_mime_type(filename)}\r\n\r\n" + content + "\r\n"

   end
end

filename = 'some_image.jpg'
content = open( 'some_image.jpg' ) { |f|
   f.read
}

boundary = "7d21f962d00c4"
params = [ Param.new( "action", "Upload" ),
                  FileParam.new( "upload", filename, content ) ]

query = params.collect { |p|
     "--" + boundary + "\r\n" + p.to_multipart
   }.join("") + "--" + boundary + "--"

resp, data = post( query, "Content-type" => "multipart/form-data, boundary=" + boundary + " " )

On Sunday, September 26, 2004, at 10:22 AM, Austin Ziegler wrote:

Did anyone ever figure this out?

Chris Morris had a message that indicated that he couldn't get it
working, back in 2003. I have a desparate need for this to work, and
I'm not really sure where to begin.

-austin
--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca
: as of this email, I have [ 6 ] Gmail invitations

Also,

Austin,

This stuff might be useful. This was part of a wiki migration script. I modified it so you wouldn't have to install narf to use it, but you'll need to find a replacement for Web::Mime::get_mime_type in FileParam#to_multipart. Or you could hard code the mime-type.

Cheers,

Patrick

------------------

require 'open-uri'

open-uri is actually not necessary; left over from my script.

require 'net/http'
require 'cgi'

def post( query, headers={} )
  Net::HTTP.start( "www.yourserver.com", 80 ) { |h|
    h.post( "/cgi-bin/your_script.rb", query, headers )
  }
end

class Param
  attr_accessor :k, :v
  def initialize( k, v )
    @k = k
    @v = v
  end

  def to_multipart
    return "Content-Disposition: form-data; name=\"#{CGI::escape(k)}\"\r\n\r\n#{v}\r\n"
  end
end

class FileParam
  attr_accessor :k, :filename, :content
  def initialize( k, filename, content )
    @k = k
    @filename = filename
    @content = content
  end

  def to_multipart
    return "Content-Disposition: form-data; name=\"#{CGI::escape(k)}\"; filename=\"#{filename}\"\r\n" +
         "Content-Transfer-Encoding: binary\r\n" +
           "Content-Type: #{Web::Mime.get_mime_type(filename)}\r\n\r\n" + content + "\r\n"

  end
end

filename = 'some_image.jpg'
content = open( 'some_image.jpg' ) { |f|
  f.read
}

boundary = "7d21f962d00c4"
params = [ Param.new( "action", "Upload" ),
                 FileParam.new( "upload", filename, content ) ]

query = params.collect { |p|
    "--" + boundary + "\r\n" + p.to_multipart
  }.join("") + "--" + boundary + "--"

resp, data = post( query, "Content-type" => "multipart/form-data, boundary=" + boundary + " " )

The boundary stuff is the delicate part here. If something is wrong, this would be where it would be, I think.

Cheers,

patrick

···

On Sunday, September 26, 2004, at 11:34 AM, Patrick May wrote:

Austin,

This stuff might be useful. This was part of a wiki migration script.
  I modified it so you wouldn't have to install narf to use it, but
you'll need to find a replacement for Web::Mime::get_mime_type in
FileParam#to_multipart. Or you could hard code the mime-type.

Thank you. What does Web::Mime::get_mime_type do? Perhaps you
could/should be using my centralised database in MIME::Types -- I'm
planning at some point on extending that in two ways. First, I plan on
using the freedesktop.org shared mime database as an option, and
second I plan on implementing libmmagic in pure Ruby (so you don't
have to trust the extension of the file if you don't choose to do so).

···

On Mon, 27 Sep 2004 00:34:04 +0900, Patrick May <patrick@hexane.org> wrote:

------------------

require 'open-uri'
require 'net/http'
require 'cgi'

def post( query, headers={} )
   Net::HTTP.start( "www.yourserver.com ", 80 ) { |h|
     h.post( "/cgi-bin/your_script.rb", query, headers )
   }
end

class Param
   attr_accessor :k, :v
   def initialize( k, v )
     @k = k
     @v = v
   end

   def to_multipart
     return "Content-Disposition: form-data;
name=\"#{CGI::escape(k)}\"\r\n\r\n#{v}\r\n"
   end
end

class FileParam
   attr_accessor :k, :filename, :content
   def initialize( k, filename, content )
     @k = k
     @filename = filename
     @content = content
   end

   def to_multipart
     return "Content-Disposition: form-data; name=\"#{CGI::escape(k)}\";
filename=\"#{filename}\"\r\n" +
           "Content-Transfer-Encoding: binary\r\n" +
            "Content-Type: #{Web::Mime.get_mime_type(filename)}\r\n\r\n"
+ content + "\r\n"

   end
end

filename = 'some_image.jpg'
content = open( 'some_image.jpg' ) { |f|
   f.read
}

boundary = "7d21f962d00c4"
params = [ Param.new( "action", "Upload" ),
                   FileParam.new( "upload", filename, content ) ]

query = params.collect { |p|
     "--" + boundary + "\r\n" + p.to_multipart
   }.join("") + "--" + boundary + "--"

resp, data = post( query, "Content-type" => "multipart/form-data,
boundary=" + boundary + " " )

On Sunday, September 26, 2004, at 10:22 AM, Austin Ziegler wrote:

> Did anyone ever figure this out?
>
> Chris Morris had a message that indicated that he couldn't get it
> working, back in 2003. I have a desparate need for this to work, and
> I'm not really sure where to begin.
>
> -austin
> --
> Austin Ziegler * halostatue@gmail.com
> * Alternate: austin@halostatue.ca
> : as of this email, I have [ 6 ] Gmail invitations
>

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca
: as of this email, I have [ 6 ] Gmail invitations

Web::Mime is a class in narf that gets mime types by filename extension. It parses a copy of Apache's mime.types file. It's not an exciting class; you should be able to replace that call with anything that returns the appropriate mime type.

At the moment, I'm managing my own dependencies to keep the installation of narf as simple as possible. I know that's a bit anti-social, but it makes it easier for me to support narf.

Cheers,

Patrick

···

On Sunday, September 26, 2004, at 12:43 PM, Austin Ziegler wrote:

On Mon, 27 Sep 2004 00:34:04 +0900, Patrick May <patrick@hexane.org> > wrote:

Austin,

This stuff might be useful. This was part of a wiki migration script.
  I modified it so you wouldn't have to install narf to use it, but
you'll need to find a replacement for Web::Mime::get_mime_type in
FileParam#to_multipart. Or you could hard code the mime-type.

Thank you. What does Web::Mime::get_mime_type do? Perhaps you
could/should be using my centralised database in MIME::Types -- I'm
planning at some point on extending that in two ways. First, I plan on
using the freedesktop.org shared mime database as an option, and
second I plan on implementing libmmagic in pure Ruby (so you don't
have to trust the extension of the file if you don't choose to do so).