Get POST parameters using a HTTP server

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.

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

Any suggestion?

Thanks in advance.


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

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

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

Hi Daniel,

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

HTTP.Handlers.serve(server_host, server_port) do request::HTTP.Request

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



Did you see this example 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.

Thank you for all your suggestions!

Finally, I have done:

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

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!

1 Like

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:

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 = ""
        content_type = only(headers)[2]

    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), "-" => "")

            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)"

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

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

                params[name] = value
    return params

I have put the code if it could help anyone.

1 Like