Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multipart/form-data multiple file upload #14

Closed
ghost opened this issue Jun 21, 2018 · 13 comments
Closed

multipart/form-data multiple file upload #14

ghost opened this issue Jun 21, 2018 · 13 comments

Comments

@ghost
Copy link

ghost commented Jun 21, 2018

This awesome tool 💯 really needs parsing for multipart/form-data via post, including multiple files with one tag name (like <input multiple>)

This would be very nice :)

As example:

This exists:

Halite.post("http://127.0.0.1:3000/upload", form: {
  "username" => "Quincy",
  "avatar" => File.open("image.png")
})

This is standard:

Halite.post("http://127.0.0.1:3000/upload", form: {
  "username" => "Quincy",
  "avatar" => File.open("image1.png"),
  "bvatar" => File.open("image2.png"),
  "cvatar" => File.open("image3.png"),
  "dvatar" => File.open("image4.png")
})

This is <input multiple>

Halite.post("http://127.0.0.1:3000/upload", form: {
  "username" => "Quincy",
  "avatar" => [File.open("1.png"), File.open("2.png"), File.open("3.png"), File.open("4.png")]
})
@icyleaf
Copy link
Owner

icyleaf commented Jun 22, 2018

It was supported now. be sure the server process the right to files.

this is my spec code:

server handler:
https://github.com/icyleaf/halite/blob/master/spec/support/mock_server/route_handler.cr#L202

spec:
https://github.com/icyleaf/halite/blob/master/spec/halite_spec.cr#L113

@ghost
Copy link
Author

ghost commented Jun 22, 2018

Thank you very much 👍 I think this should generate a body like this?

image

(here "image1" is "avatar" - and the files are all the same dummys just to have a better view at)

I have to check it out :-)

@icyleaf
Copy link
Owner

icyleaf commented Jun 22, 2018

Yes, all the files use same name and it own filenames.

@icyleaf
Copy link
Owner

icyleaf commented Jun 22, 2018

I found the name must append [] to got in rails, without [] the file always be overwrite and keep the last one.

test result:

url = "http://localhost:3000/file_upload"
r = Halite.post(url, form: {
  "file" => [
    File.open("./shard.yml"),
    File.open("./src/halite.cr"),
  ]
})

body:

  "----------------------------afxb97KGQkD88a2jAZYhJICr\r\n" +
  "Content-Disposition: form-data; name=\"file\"; filename=\"shard.yml\"\r\n" +
  "\r\n" +
  "name: halite\n" +
  "version: 0.3.2\n" +
  "\n" +
  "authors:\n" +
  "  - icyleaf <[email protected]>\n" +
  "\n" +
  "crystal: 0.25.0\n" +
  "\n" +
  "license: MIT\n" +
  "\r\n" +
  "----------------------------afxb97KGQkD88a2jAZYhJICr\r\n" +
  "Content-Disposition: form-data; name=\"file\"; filename=\"halite.cr\"\r\n" +
  "\r\n" +
  "require \"./halite/*\"\n" +
  "require \"./halite/ext/*\"\n" +
  "\n" +
  "module Halite\n" +
  "  extend Chainable\n" +
  "end\n" +
  "\r\n" +
  "----------------------------afxb97KGQkD88a2jAZYhJICr--"

response:

{"file" => {"tempfile" => ["require \"./halite/*\"\n", "require \"./halite/ext/*\"\n", "\n", "module Halite\n", "  extend Chainable\n", "end\n"], "original_filename" => "halite.cr", "content_type" => nil, "headers" => "Content-Disposition: form-data; name=\"file\"; filename=\"halite.cr\"\r\n"}, "controller" => "file_upload", "action" => "create"}

But it append []

url = "http://localhost:3000/file_upload"
r = Halite.post(url, form: {
  "file[]" => [
    File.open("./shard.yml"),
    File.open("./src/halite.cr"),
  ]
})

body:

  "----------------------------afxb97KGQkD88a2jAZYhJICr\r\n" +
  "Content-Disposition: form-data; name=\"file[]\"; filename=\"shard.yml\"\r\n" +
  "\r\n" +
  "name: halite\n" +
  "version: 0.3.2\n" +
  "\n" +
  "authors:\n" +
  "  - icyleaf <[email protected]>\n" +
  "\n" +
  "crystal: 0.25.0\n" +
  "\n" +
  "license: MIT\n" +
  "\r\n" +
  "----------------------------afxb97KGQkD88a2jAZYhJICr\r\n" +
  "Content-Disposition: form-data; name=\"file[]\"; filename=\"halite.cr\"\r\n" +
  "\r\n" +
  "require \"./halite/*\"\n" +
  "require \"./halite/ext/*\"\n" +
  "\n" +
  "module Halite\n" +
  "  extend Chainable\n" +
  "end\n" +
  "\r\n" +
  "----------------------------afxb97KGQkD88a2jAZYhJICr--"

response:

{"file" => [{"tempfile" => ["name: halite\n", "version: 0.3.2\n", "\n", "authors:\n", "  - icyleaf <[email protected]>\n", "\n", "crystal: 0.25.0\n", "\n", "license: MIT\n"], "original_filename" => "shard.yml", "content_type" => nil, "headers" => "Content-Disposition: form-data; name=\"file[]\"; filename=\"shard.yml\"\r\n"}, {"tempfile" => ["require \"./halite/*\"\n", "require \"./halite/ext/*\"\n", "\n", "module Halite\n", "  extend Chainable\n", "end\n"], "original_filename" => "halite.cr", "content_type" => nil, "headers" => "Content-Disposition: form-data; name=\"file[]\"; filename=\"halite.cr\"\r\n"}], "controller" => "file_upload", "action" => "create"}

@ghost
Copy link
Author

ghost commented Jun 22, 2018

I just downloaded and tryied your master - for me (as first look)

Halite.post("http://127.0.0.1:3000/upload", form: {
  "username" => "Quincy",
  "avatar" => [File.open("public/1.png"), File.open("public/2.png"), File.open("public/3.png"), File.open("public/4.png")]
})

works as aspected, were

Halite.post("http://127.0.0.1:3000/upload", form: {
  "username" => "Quincy",
  "avatar[]" => [File.open("public/1.png"), File.open("public/2.png"), File.open("public/3.png"), File.open("public/4.png")]
})

errors as

Exception: Missing hash key: "avatar" (KeyError)

Which framework / shard / Server are you using while your error with overwritten files?

How did you output the body as String? Is this originally raw? :) I am looking for this :)

@ghost
Copy link
Author

ghost commented Jun 22, 2018

ups, i checked the + and "" - where comes this output from?

@ghost
Copy link
Author

ghost commented Jun 22, 2018

Just want to say if you are using kemal, this error could be related to kemalcr/kemal#455 ?

@icyleaf
Copy link
Owner

icyleaf commented Jun 22, 2018

i tested used Rails v5.1.4

With Crystal i do not knew which framework support multiple files upload, it is better choose the famous framework 😆

@icyleaf
Copy link
Owner

icyleaf commented Jun 22, 2018

Any news welcome, i will check on next monday.
have a nice week :)

@ghost
Copy link
Author

ghost commented Jun 22, 2018

thanks, mee to - its weekend, so we will do more next week and afterwards :-)

nice days for you :)

@ghost
Copy link
Author

ghost commented Jun 22, 2018

BTW, kemal is going to solve this, the parser will be completely rewritten to handle multipart/form-data correct for this 👍 Follow here: kemalcr/kemal#458

This is also nice: http://kemalcr.com/blog/2016/11/13/benchmarking-and-scaling-websockets-handling-60000-concurrent-connections/

Time to try it :)

@icyleaf
Copy link
Owner

icyleaf commented Jun 25, 2018

It is very easy to review the body of request by use logger feature.

And Is this works for your?

@icyleaf
Copy link
Owner

icyleaf commented Jun 26, 2018

I close it now, any issues to reopen 🍺

@icyleaf icyleaf closed this as completed Jun 26, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant