Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 731
steven_noble Avatar asked Apr 28 '16 14:04

steven_noble


1 Answers

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.

like image 52
Gustavo Rubio Avatar answered Sep 25 '22 14:09

Gustavo Rubio