I get a request.body from web service
fp = File.open("/home/mm/mms/video_rest/video_mp.mp4", "wb")
fp.write(request.body.readline)
fp.close
but when file are create size a 0 bytes
how to view if request body are a file size or how to best way to get a video file from request body?
UPDATE
have a this params
{"video"=>#<ActionDispatch::Http::UploadedFile:0x007febdc497da0 #tempfile=#<Tempfile:/tmp/RackMultipart20151007-3197-14dis8n.mp4>, #original_filename="VID_20151006_153121393.mp4", #content_type="application/octet-stream", #headers="Content-Disposition: form-data; name=\"video_presentacion\"; filename=\"VID_20151006_153121393.mp4\"\r\nContent-Type: application/octet-stream\r\nContent-Transfer-Encoding: binary\r\n">}
how to create a file on folder and change Content-Type application/octet-stream for 'video/mp4'?
im try with:
fp = File.open("/home/mm/aa/video_rest/video_mp.mp4", "wb")
fp.write(params[:video])
fp.close
or direct for paperclipt
usuario.update_attributes!(:video => params[:video])
result => Content type invalid
Solved
on android http using a on params add a content type("video/mp4")
and work fine !
regards!
Related
TL;DR
How can I to upload an image and maintain its original Content Type or, generate a signed or public URL that force a correct type for my file?
I explain more:
I have a problem with S3 (I really I'm using Minio, that is compatible with S3 protocol) in Rails app with
gem 'aws-sdk-s3', '~> 1.96'
I create the follow method to handle uploaded file (in Rails App) and send it to Minio.
def upload_file(file)
object_key = "#{Time.now.to_i}-#{file.original_filename}"
object = #s3_bucket.object(object_key)
object.upload_file(Pathname.new(file.path))
object
end
This is my uploaded file with correct Content-Type, before it was sent to Minio.
# file
#<ActionDispatch::Http::UploadedFile:0x00007f47918ef708
#content_type="image/jpeg",
#headers=
"Content-Disposition: form-data; name=\"images[]\"; filename=\"image_test.jpg\"\r\nContent-Type: image/jpeg\r\n",
#original_filename="image_test.jpg",
#tempfile=#<File:/tmp/RackMultipart20220120-9-gc3x7n.jpg>>
And here, is my file, with incorrect Type ("binary/octet-stream") on Minio
I need to send it to another service, and get the upload URL with correct Content-Type.
So, how can I to upload an image and maintain its original Content Type or, generate a signed or public URL that force a correct type for my file?
You could use the put_object method on the bucket instance that accepts a hash of options, one of which is content-type (Reference):
def upload_file(file)
object_key = "#{Time.now.to_i}-#{file.original_filename}"
#s3_bucket.put_object({
key: object_key,
body: Pathname.new(file.path),
content_type: "some/content_type"
})
end
I have a client in java that sends form post requests with video file.
I get in the server following POST:
Parameters: {"video"=>#<ActionDispatch::Http::UploadedFile:0x007f26783b49d0
#original_filename="video", #content_type=nil,
#headers="Content-Disposition: form-data; name=\"video\"; filename=\"video\"\r\n",
#tempfile=#<Tempfile:/tmp/RackMultipart20160405-3-106c9nr>>, "id"=>"36"}
I am trying to save the file to s3 using following lines:
I know the connection and actual saving works because I tried with base64 string as parameter and it worked well.
body = params[:video].tempfile
video_temp_file = write_to_file(body)
VideoUploader.new.upload_video_to_s3(video_temp_file, params[:id].to_s+'.mp4')
I see on s3 empty files or 24 bytes.
where do i do wrong?
Edit: I am using carrierwave:
def write_to_file(content)
thumbnail_file = Tempfile.new(['video','.mp4'])
thumbnail_file.binmode # note that the tempfile must be in binary mode
thumbnail_file.write content
thumbnail_file.rewind
thumbnail_file
end
I'm trying to post a jpeg file to a locally developed web service via Fiddler. This would be simple enough, but I also need to include some data alongside the file and can’t quite nail the syntax that fiddler wants. If I click the upload file button and select a file to upload, it replaces my POST body with:
---------------------------acebdf13572468
Content-Disposition: form-data; name="fieldNameHere"; filename="PantheraLeo.jpg"
Content-Type: image/jpeg
<#INCLUDE *C:\temp\PantheraLeo.jpg*#>
---------------------------acebdf13572468—
Now I want to add some additional data:
user=1&album=2&photo=[OUTPUT FROM FILE UPLOAD]
I’ve tried putting this at the start of the body, but when my Node app receives the request, I’m getting a user parameter, an album parameter but no photo.
Any ideas on how I could format this request to get both parameters and the photo uploaded as the photo parameter?
I've also been looking to do something similar myself and stumbled on your question. I've just managed to achieve what I needed after a bit of messing about with Fiddler. Try this:
---------------------------acebdf13572468
Content-Disposition: form-data; name="model"
MyModelInfo
---------------------------acebdf13572468
Content-Disposition: form-data; model="test123"; filename="123.gif"
Content-Type: image/gif
<#INCLUDE *Z:\Downloads\123.gif*#>
---------------------------acebdf13572468--
It would seem that you link the form data being sent up in your request body to the 'acebdf13572468' boundary in the POST info. Provide the Content-Disposition with a key name (in my case 'model') and then the following line represents your actual value for this key. (In my case "MyModelInfo".
Using the above request body I was able to POST up a file as well as some accompanying POST data to my API.
The accepted answer works well. But be warned the extra line after MyModelInfo comes through into the string. Also when copying and pasting in and out of fiddler some lines were corrupted breaking the file.
Note I have named the file param "file" in the fiddler body and in the receiving API function.
This works for me:
---------------------------acebdf13572468
Content-Disposition: form-data; name="PARAM1"
Some text with a line before but not after
---------------------------acebdf13572468
Content-Disposition: form-data; name="file"; filename="filename.jpg"
Content-Type: image/jpeg
<#INCLUDE *C:\local\filename.jpg*#>
---------------------------acebdf13572468--
The data can be received in .net core 2 like this:
[HttpPost]
[Route("AddImage")]
public async System.Threading.Tasks.Task<IActionResult> AddImageAsync(IFormFile file)
{
//f is the same as file
//var f = Request.Form.Files.Count > 0 ? Request.Form.Files[0] : null;
//useful to check the keys
//var additionalProperties = Request.Form.Keys;
if (file != null)
{
try
{
if (Request.Form.TryGetValue("PARAM1", out StringValues p1))
{
var txt = p1.ToString():
I am trying to upload a photo (in a multipart form) from an iOS app, using AFNetworking. I am using node.js for my backend, and almost have it working. The problem is that when I am trying to save the image it is also writing the headers to the file...So all of the images I save have something like this in the beginning (when I open the image in plain text):
--Boundary+9EF923E9CAACB213
Content-Disposition: form-data; name="para"
val
--Boundary+9EF923E9CAACB213
Content-Disposition: form-data; name="afImage"; filename="afImage.jpg"
Content-Type: image/jpeg
The server code I am using is:
uploadIOS: (req, res) ->
tmpfile = variables.uploadsDir + "tempname"
ws = fs.createWriteStream(tmpfile)
req.on 'data', (data) ->
ws.write data
req.on 'end', ->
ws.end()
I can get it working using the express body parser, but would prefer to do it this way if possible. Any ideas how to strip away the headers?
You have to use a multipart-capable parser such as busboy or multiparty.
In my controller the result of request.body.read is:
=============
--AJAX-----------------------1267183973160
Content-Disposition: form-data; name="1261400603_page_white_word.png"; filename="1261400603_page_white_word.png"
Content-Type: application/octet-stream
thefile
--AJAX-----------------------1267183973160
Content-Disposition: form-data; name="1261400536_page_white_excel.png"; filename="1261400536_page_white_excel.png"
Content-Type: application/octet-stream
thefile
--AJAX-----------------------1267183973160--
=============
It contains n form-data (2 in my example), my goal is to loop through the n form-data and get the data name, filename and a file uploaded, in my example I replaced the binary data by thefile.
here is the content of the params hash
{"action"=>"create", "controller"=>"photos", "1265144945_395.jpg"=>#<File:/var/folders/BT/BTpdsWBkF6myaI-sl3+1NU+++TI/-Tmp-/RackMultipart20100226-273-1un364r-0>}
Cheers
Have you considered using paperclip or attachment_fu? They are battle-tested and will do better than using request.body. In any case, you could parse request.body as follows but it's not the best solution.
inputs = request.body.read.split(/--ajax-+\d+-*/mi)
inputs.each do |input|
input.scan(/(.*)[\n\r]{2,4}(.*)/m) do |header, file|
header.scan(/name=["'](.*)["'];\s+filename=["'](.*)["']/) do |name, filename|
puts name
puts filename
end
puts file
end
end
Edit: So that params parsing is probably the job of Rack::Utils::Multipart.parse_mulitpart. One should probably reuse the regex's from the source of that to parse this a bit more robustly. Also, it looks like rack is creating a tmp file for you of some sort. Can you check the contents of that file?