# Get POST parameters using a HTTP server

**URL:** <https://discourse.julialang.org/t/get-post-parameters-using-a-http-server/39113>\
**Category:** Web Stack\
**Tags:** question, package\
**Created:** [May 8, 2020, 2:05pm UTC](https://discourse.julialang.org/t/get-post-parameters-using-a-http-server/39113 "2020-05-08T14:05:38Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![dmolina](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dmolina/32/5246_2.png) [@dmolina](https://discourse.julialang.org/u/dmolina)\
**Post date:** [May 8, 2020, 2:05pm UTC](https://discourse.julialang.org/t/get-post-parameters-using-a-http-server/39113/1 "2020-05-08T14:05:38Z")

</div>

Dear all,

I want to do a small server using Julia. This service implies to receive POST parameters and returns a file. Because I want to include it inside my package, I have chosen HTTP.jl (instead of Genie) to reduce the dependencies.

Using HTTP, after many errors, I could send the file. The problem is how to receive the POST parameters from a HTML form using a handle.  
I have check the documentation but I have not found any clue. I have try the request.headers and request.body but without any success.

```julia
function handle(req::HTTP.Request)
      # Get the POST parameters?
end

```

Any suggestion?

Thanks in advance.

Daniel

---

<div class="post-metadata">

**Author:** ![Iulian.Cioarca](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iulian.cioarca/32/30166_2.png) [@Iulian.Cioarca](https://discourse.julialang.org/u/Iulian.Cioarca)\
**Post date:** [May 8, 2020, 2:19pm UTC](https://discourse.julialang.org/t/get-post-parameters-using-a-http-server/39113/2 "2020-05-08T14:19:04Z")

</div>

I can’t help you directly, since I’ve done something similar for images, but with Genie:

```julia
route("/getpic", method = POST) do
  #read payload
  raw = filespayload()
  img = ImageMagick.readblob(raw["file_name"].data)
end
Genie.startup(port,ip,async = false)

```

Maybe if you look inside the `Genie.filespayload()` function?

---

<div class="post-metadata">

**Author:** ![yoh-meyers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yoh-meyers/32/14700_2.png) [@yoh-meyers](https://discourse.julialang.org/u/yoh-meyers)\
**Post date:** [May 8, 2020, 2:29pm UTC](https://discourse.julialang.org/t/get-post-parameters-using-a-http-server/39113/3 "2020-05-08T14:29:39Z")

</div>

Hi Daniel,

I have studied the `HTTP.jl` library extensively.  
You would need to do:

```julia
HTTP.Handlers.serve(server_host, server_port) do request::HTTP.Request
  request_payload=String(take!(IOBuffer(request.body))))
end

```

`request_payload` is JSON string format

As side note I recently created a lighter Julia web library (only renders JSON API and HTTP Get) doing all this for you. Might want to check [Dance.jl](https://github.com/DanceJL/Dance.jl)

Cheers

---

<div class="post-metadata">

**Author:** ![uwechsler](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uwechsler/32/5223_2.png) [@uwechsler](https://discourse.julialang.org/u/uwechsler)\
**Post date:** [May 8, 2020, 3:35pm UTC](https://discourse.julialang.org/t/get-post-parameters-using-a-http-server/39113/4 "2020-05-08T15:35:47Z")

</div>

Did you see this [example](https://juliaweb.github.io/HTTP.jl/stable/public_interface/#HTTP.Handlers) from the `HTTP.jl` documentation where the payload is obtained using `IOBuffer(HTTP.payload(req))`. This object can then be parsed with one of the julia json readers.

---

<div class="post-metadata">

**Author:** ![dmolina](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dmolina/32/5246_2.png) [@dmolina](https://discourse.julialang.org/u/dmolina)\
**Post date:** [May 8, 2020, 7:06pm UTC](https://discourse.julialang.org/t/get-post-parameters-using-a-http-server/39113/5 "2020-05-08T19:06:54Z")

</div>

Thank you for all your suggestions!

Finally, I have done:

```julia
function handle(req::HTTP.Request)
      data = String(req.body)
     params = Dict(split.(split(data, "&"), Ref("=")))
     # Process params
end

```

The String(req.body) is enough when your form is simple (in my case all where input, select, and textarea), if there is a file the option suggested by @yoh-meyers is the best one. That sentence concatenate the values as: "data = “penalty\_options=0.25&penalty\_boolean=0&text=…”  
So, the next line divide the different form values using the & and the = symbol, and create a Dictionary with the parameters. (if there is a conflictive symbol as ‘&’ or ‘=’ as the values of the variables, they are encoded).

@uwechsler thank you, but the payload function did not work for me.

Thanks again all for your ideas!

---

<div class="post-metadata">

**Author:** ![dmolina](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dmolina/32/5246_2.png) [@dmolina](https://discourse.julialang.org/u/dmolina)\
**Post date:** [May 9, 2020, 1:52pm UTC](https://discourse.julialang.org/t/get-post-parameters-using-a-http-server/39113/6 "2020-05-09T13:52:14Z")

</div>

To answer myself, I have develop a (not so) simple function to read parameters. It is not working with files, but it is working with “application/x-www-form-urlencoded” and “multipart/form-data” content-types:

```julia
function get_params(req::HTTP.Request)
    data = String(req.body)
    params = Dict{String,String}()

    headers = filter(x->x[1] == "Content-Type", req.headers)
    # Check there is content-type
    if (isempty(headers))
        content_type = ""
    else
        content_type = only(headers)[2]
    end

    if (content_type == "application/x-www-form-urlencoded")
        pairs = split.(split(data, "&"), Ref("="))
        params = Dict(name => HTTP.URIs.unescapeuri(value) for (name, value) in pairs)
    elseif (startswith(content_type, "multipart/form-data"))
        body = IOBuffer(data)

        # First line is the stopping line
        stopping_line = replace(readline(body), "-" => "")

        while(!eof(body))
            line = readline(body)
            text_head = r"Content-Disposition: form-data; name=\"(.*)\""
            m = match(text_head, line)

            if !isnothing(m)
                name = m.captures[1]
                _ = readline(body)
                line = readline(body)
                value = ""

                if (!occursin(stopping_line, line))
                    value = "$(line)"
                end

                while (!eof(body) && !occursin(stopping_line, line))
                    line = readline(body)

                    if (!occursin(stopping_line, line))
                        value *= "\n$(line)"
                    end
                end

                params[name] = value
            end
        end
    end
    return params
end

```

I have put the code if it could help anyone.
