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?
end
Any suggestion?
Thanks in advance.
Daniel
             
            
              
              
              
            
            
           
          
            
            
              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)
end
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=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
Cheers
             
            
              
              
              2 Likes
            
                
            
           
          
            
            
              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
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!
             
            
              
              
              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 = ""
    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.
             
            
              
              
              1 Like