Sunday, May 8, 2016

How to retrieve an image sent from a desktop app to a Rails API

Leave a Comment

I'm building a desktop app using Electron, which is basically JavaScript.

In it, I'm sending an image to my Rails API like this:

var myHeaders = new Headers(); myHeaders.append('Authorization', 'Token token=redacted'); myHeaders.append('Content-Type', 'application/json'); myHeaders.append('Accept', 'application/json');  ...  var formData = new FormData(); formData.append("img", base64EncodedImage); var myPost = {method: 'POST', headers: myHeaders, body: formData} fetch("url", myPost) 

(simplified)

In my Rails console, I see:

{"REMOTE_ADDR"=>"127.0.0.1", "REQUEST_METHOD"=>"POST", "REQUEST_PATH"=>"/task/screenshot", "PATH_INFO"=>"/task/screenshot", "REQUEST_URI"=>"/task/screenshot", "SERVER_PROTOCOL"=>"HTTP/1.1", "HTTP_VERSION"=>"HTTP/1.1", "HTTP_HOST"=>"localhost:3000", "HTTP_CONNECTION"=>"keep-alive", "CONTENT_LENGTH"=>"454856", "HTTP_ACCEPT"=>"application/json", "HTTP_ORIGIN"=>"null", "HTTP_USER_AGENT"=>"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) testivate-research-gigs/1.0.0 Chrome/49.0.2623.75 Electron/0.37.5 Safari/537.36", "HTTP_AUTHORIZATION"=>"Token token=redacted", "CONTENT_TYPE"=>"application/json", "HTTP_ACCEPT_ENCODING"=>"gzip, deflate", "HTTP_ACCEPT_LANGUAGE"=>"en-US", "rack.url_scheme"=>"http", "SERVER_NAME"=>"localhost", "SERVER_PORT"=>"3000", "QUERY_STRING"=>"", "rack.tempfiles"=>[#<Unicorn::TmpIO:/var/folders/k9/vnpft_6d7qs6xmdb9_4svvmw0000gn/T/0.19309304750270062>], "rack.input"=>#<Rack::Lint::InputWrapper:0x007fe1de317000 @input=#<Unicorn::TeeInput:0x007fe1de31d950 @len=454856, @chunked=false, @socket=#<Kgio::Socket:fd 7>, @parser=#<Unicorn::HttpParser:0x007fe1db08ce00>, @buf="", @rbuf="------WebKitFormBoundaryxkkhvE17qoI5ozlK\r\nContent-Disposition: form-data; name=\"img\"\r\n\r\ndata:image/jpeg;base64,iVBORw0KGgoAAAANSUhEU...

But I can't get to the image. This is what I see when I drop into the controller using Pry:

> request.body.read > request.body.rewind > request.body.read > request.env 

That is, I receive empty responses to most of the commands, and then it just hangs there indefinitely after I type request.env, without returning to the prompt.

How do I get to the image?

Thanks.

BTW, other actions that are receiving POSTs but not with embedded images are working perfectly. Previously, this action was working perfectly too when I was using XMLHttpRequest() not fetch(), but I've had to make the switch to turn my Google Chrome Extension into an Electron app.

UPDATE

I solved this problem for myself by uploading my images directly to S3 rather than to S3-via-Rails. It not only works but is faster than going via the app, which I now only have to tell where to look to find the image. But seeing as my original issue was not addressed, I'm leaving this question and the bounty open. Perhaps someone will solve it, claim the bounty, and write up an answer that someone else will find useful down the track.

2 Answers

Answers 1

If you are sending the image properly with POST and have it on the permitted params it should be available through regular parameters collection, then you can read your base64 encoded image and write it out:

File.open('some/path/to/image.jpg', 'wb') do|f|   f.write(Base64.decode64(base_64_encoded_data)) end 

Why are you reading from request.body directly anyway? params in your controller should have a hash of values from the form data.

Answers 2

I would test by sending a request from the desktop app to a locally served version of the API (i.e. run rails server from the terminal) and watch the rails console to see what is received. You should see a list of params. If the img param is included in the request then you are probably blacklisting via strong params in your rails controller

If you don't see the img param then you need to tweak the desktop app to send the form data correctly

Also, I suspect you should be using a post not a fetch from the desktop app

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment