1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
|
# Multipart::Post
Adds a streamy multipart form post capability to `Net::HTTP`. Also supports other
methods besides `POST`.
[](https://github.com/socketry/multipart-post/actions?workflow=Test)
## Features/Problems
- Appears to actually work. A good feature to have.
- Encapsulates posting of file/binary parts and name/value parameter parts, similar to
most browsers' file upload forms.
- Provides an `UploadIO` helper class to prepare IO objects for inclusion in the params
hash of the multipart post object.
## Installation
``` shell
bundle add multipart-post
```
## Usage
``` ruby
require 'net/http/post/multipart'
url = URI.parse('http://www.example.com/upload')
File.open("./image.jpg") do |jpg|
req = Net::HTTP::Post::Multipart.new url.path,
"file" => UploadIO.new(jpg, "image/jpeg", "image.jpg")
res = Net::HTTP.start(url.host, url.port) do |http|
http.request(req)
end
end
```
To post multiple files or attachments, simply include multiple parameters with
`UploadIO` values:
``` ruby
require 'net/http/post/multipart'
url = URI.parse('http://www.example.com/upload')
req = Net::HTTP::Post::Multipart.new url.path,
"file1" => UploadIO.new(File.new("./image.jpg"), "image/jpeg", "image.jpg"),
"file2" => UploadIO.new(File.new("./image2.jpg"), "image/jpeg", "image2.jpg")
res = Net::HTTP.start(url.host, url.port) do |http|
http.request(req)
end
```
To post files with other normal, non-file params such as input values, you need to pass hashes to the `Multipart.new` method.
In Rails 4 for example:
``` ruby
def model_params
require_params = params.require(:model).permit(:param_one, :param_two, :param_three, :avatar)
require_params[:avatar] = model_params[:avatar].present? ? UploadIO.new(model_params[:avatar].tempfile, model_params[:avatar].content_type, model_params[:avatar].original_filename) : nil
require_params
end
require 'net/http/post/multipart'
url = URI.parse('http://www.example.com/upload')
Net::HTTP.start(url.host, url.port) do |http|
req = Net::HTTP::Post::Multipart.new(url, model_params)
key = "authorization_key"
req.add_field("Authorization", key) #add to Headers
http.use_ssl = (url.scheme == "https")
http.request(req)
end
```
Or in plain ruby:
``` ruby
def params(file)
params = { "description" => "A nice picture!" }
params[:datei] = UploadIO.new(file, "image/jpeg", "image.jpg")
params
end
url = URI.parse('http://www.example.com/upload')
File.open("./image.jpg") do |file|
req = Net::HTTP::Post::Multipart.new(url.path, params(file))
res = Net::HTTP.start(url.host, url.port) do |http|
return http.request(req).body
end
end
```
### Parts Headers
By default, all individual parts will include the header `Content-Disposition` as well as `Content-Length`, `Content-Transfer-Encoding` and `Content-Type` for the File Parts.
You may optionally configure the headers `Content-Type` and `Content-ID` for both ParamPart and FilePart by passing in a `parts` header.
For example:
``` ruby
url = URI.parse('http://www.example.com/upload')
params = {
"file_metadata_01" => { "description" => "A nice picture!" },
"file_content_01" => UploadIO.new(file, "image/jpeg", "image.jpg")
}
headers = {
'parts': {
'file_metadata_01': {
'Content-Type' => "application/json"
}
}
}
req = Net::HTTP::Post::Multipart.new(uri, params, headers)
```
This would configure the `file_metadata_01` part to include `Content-Type`
Content-Disposition: form-data; name="file_metadata_01"
Content-Type: application/json
{
"description" => "A nice picture!"
}
#### Custom Parts Headers
*For FileParts only.*
You can include any number of custom parts headers in addition to `Content-Type` and `Content-ID`.
``` ruby
headers = {
'parts': {
'file_metadata_01': {
'Content-Type' => "application/json",
'My-Custom-Header' => "Yo Yo!"
}
}
}
```
### Debugging
You can debug requests and responses (e.g. status codes) for all requests by adding the following code:
``` ruby
http = Net::HTTP.new(uri.host, uri.port)
http.set_debug_output($stdout)
```
## Versioning
This library aims to adhere to [Semantic Versioning 2.0.0](http://semver.org/).
Violations of this scheme should be reported as bugs. Specifically,
if a minor or patch version is released that breaks backward
compatibility, a new version should be immediately released that
restores compatibility. Breaking changes to the public API will
only be introduced with new major versions.
As a result of this policy, you can (and should) specify a
dependency on this gem using the [Pessimistic Version Constraint](http://guides.rubygems.org/patterns/#pessimistic-version-constraint) with two digits of precision.
For example:
``` ruby
spec.add_dependency 'multipart-post', '~> 2.1'
```
|