6

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.

steven_noble
  • 4,133
  • 10
  • 44
  • 77
  • how storing an image in rails, do use any gem ? – 7urkm3n Apr 28 '16 at 15:04
  • Use paperclip gem for image upload http://stackoverflow.com/questions/35765578/rails-api-paperclip-uploading-image-converting-it-to-base-64-and-saving-it-and/35766241#35766241 – Pitabas Prathal Apr 28 '16 at 15:37
  • it seems like you have filtered out the parameter. – joewoodward Apr 28 '16 at 17:49
  • Hi @joewoodward -- that's why I started with showing that `request.body.read` (unfiltered) was itself empty. – steven_noble Apr 28 '16 at 21:04
  • Hi @7urkm3n -- I'm using CarrierWave. But that step comes later. As this is being uploaded from a desktop app, not from my own web app, I can't rely on CarrierWave or Paperclip to handle this initial step. – steven_noble Apr 28 '16 at 21:06
  • @steven_noble did u try to curl it first yr backend `curl -i -H "Accept: application/json" -H "Content-type:application/json" -X POST -d '{"remote_image":"http//xxxxx", '"title": "test"}' http://localhost:3000`, also give a permission for json `protect_from_forgery with: :null_session` – 7urkm3n Apr 28 '16 at 21:34
  • Are you able to access the data that's being printed to the logs? (Is it in `request`?) – Laurel May 02 '16 at 01:22
  • Hi @Laurel -- no, that's the crux of my post. I am saying that when I try to access `request`, I find that it is empty. – steven_noble May 02 '16 at 01:29
  • How is it being printed to the logs then? Could you just get the data from there maybe? – Laurel May 02 '16 at 01:34
  • Sorry @Laurel it is being printed to console not log; i'll update – steven_noble May 02 '16 at 01:35
  • [It seems you could write it to a file](http://stackoverflow.com/questions/8720150). – Laurel May 02 '16 at 01:41
  • @steven_noble have you made sure `protect_from_forgery` is not affecting your requests without `csrf_token`? Have you removed it from applicaition controller? – Uzbekjon May 06 '16 at 08:51

2 Answers2

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.

Gustavo Rubio
  • 10,209
  • 8
  • 39
  • 57
0

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

joewoodward
  • 263
  • 4
  • 10
  • Hi @joewoodward. Thanks. I am actually sending a `POST` using JavaScript's `fetch()` method. That's why `var myPost = {method: 'POST', headers: myHeaders, body: formData}`. When I say "here is what I see in my controller using Pry", I'm talking about what I see when I run the app on localhost. – steven_noble Apr 28 '16 at 21:07