# HTTP post a file

**URL:** <https://forum.crystal-lang.org/t/http-post-a-file/2913>\
**Category:** Help & Support\
**Created:** [January 29, 2021, 12:44am UTC](https://forum.crystal-lang.org/t/http-post-a-file/2913 "2021-01-29T00:44:48Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![wontruefree](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/wontruefree/32/1467_2.png) [@wontruefree](https://forum.crystal-lang.org/u/wontruefree)\
**Post date:** [January 29, 2021, 12:44am UTC](https://forum.crystal-lang.org/t/http-post-a-file/2913/1 "2021-01-29T00:44:48Z")

</div>

What is the best way to post a file with the `HTTP::Client`?

I have been messing around with some crystal code trying to replicate something like this.

> <https://github.com/braintree/braintree_ruby/blob/fe3c3f04db2c6141689b4e09d80de77aa99ebfa3/lib/braintree/http.rb#L37>

There is a few libraries that make this way easier like Crest and Halite. it would be nice to in the standard library just call a post method with a file like Crest of Halite.

Something like.

```crystal
response = HTTP::Client.post(
  "http://example.com/",
  form: { "file" => File.read("foo.txt") }
)

```

---

<div class="post-metadata">

**Author:** ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)\
**Post date:** [January 29, 2021, 1:00am UTC](https://forum.crystal-lang.org/t/http-post-a-file/2913/2 "2021-01-29T01:00:54Z")

</div>

It depends on what the server is expecting. If it’s expecting form data you’d be best off using [HTTP::FormData::Builder - Crystal 1.0.0-dev](https://crystal-lang.org/api/master/HTTP/FormData/Builder.html#file(name:String,io,metadata:FileMetadata=FileMetadata.new,headers:HTTP::Headers=HTTP::Headers.new)-instance-method) and pass the same `io` to the `form` argument of `.post`. Another way would involve sending the endpoint the contents of the file Base64 encoded; such as as part of a JSON object.

---

<div class="post-metadata">

**Author:** ![wontruefree](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/wontruefree/32/1467_2.png) [@wontruefree](https://forum.crystal-lang.org/u/wontruefree)\
**Post date:** [February 1, 2021, 6:09pm UTC](https://forum.crystal-lang.org/t/http-post-a-file/2913/3 "2021-02-01T18:09:32Z")

</div>

It is true it depends on what the server expects. I figured out how to replicate this with `HTTP::FormData::Builder` I just think there might be an easier interface to do it.

Seems like this might not be something other people want though. I like the interfaces of Crest and Halite though.
