six-ddc / plow

A high-performance HTTP benchmarking tool that includes a real-time web UI and terminal display
Apache License 2.0
4.11k stars 140 forks source link

Plow not working with --body switch #30

Closed gaslit closed 2 years ago

gaslit commented 2 years ago

Thanks for your hard work on this but seeking advice about what I believe may be a bug in Windows build version 1.1

Inputting a JSON file into the --body switch fails to copy the contents of the file into the request body of the HTTP command generated by plow

Sample JSON file as follows: (line-endings all in LF format) { "test": { "test_id": "100", "account_id": "2176db06-dc03-4f21-8de4-de38df531c53", "funds_balance": "1", "funds_withheld": "1", "funds_escrow": "1", "currency": "thb" } }

Expected that these contents will go into the request body of the generated command created by this: plow http://localhost:4000/api/ -c 1 -n 1 --body @post.json --stream -T 'application/json' -m POST -H "Content-Length:262; Host:localhost:4000"

or this: plow http://localhost:4000/api/ -c 1 -n 1 --body @post.json --stream -T 'application/json' -m POST

Many thanks. A sample JSON document would be so useful so I can confirm that my JSON document is formatted correctly.

six-ddc commented 2 years ago

Thanks for you feedback. How did you determine that the --body was not working? Have any detailed information about the test process?

gaslit commented 2 years ago

I ran the commands above:

plow http://localhost:4000/api/ -c 1 -n 1 --body @post.json --stream -T 'application/json' -m POST

and

plow http://localhost:4000/api/ -c 1 -n 1 --body @post.json --stream -T 'application/json' -m POST -H "Content-Length:262; Host:localhost:4000"

Localhost:4000 has a Phoenix server and upon inspecting the connection initiated:

%Plug.Conn{
  adapter: {Plug.Cowboy.Conn, :...},
  assigns: %{},
  body_params: %Plug.Conn.Unfetched{aspect: :body_params},
  cookies: %{},
  halted: false,
  host: "localhost",
  method: "POST",
  owner: #PID<0.1008.0>,
  params: %{},
  path_info: ["api", "purses"],
  path_params: %{},
  port: 4000,
  private: %{
    TestWeb.Router => {[], %{Plug.Swoosh.MailboxPreview => ["mailbox"]}},
    :before_send => [#Function<0.23023616/1 in Plug.Telemetry.call/2>],
    :phoenix_endpoint => TestWeb.Endpoint,
    :phoenix_request_logger => {"request_logger", "request_logger"},
    :phoenix_router => TestWeb.Router,
    :plug_session_fetch => #Function<1.77458138/1 in Plug.Session.fetch_session/1>,
    :raw_version => "application/vnd.td-tp.app.v2+json",
    :version => [:v2],
    :version_verified => true
  },
  query_params: %{},
  query_string: "",
  remote_ip: {127, 0, 0, 1},
  req_cookies: %{},
  req_headers: [
    {Content-Length:262; Host:localhost:4000"},
    {"content-type", "'application/json'"},
    {"host", "localhost:4000"},
    {"user-agent", "plow"}
  ],
  request_path: "/api/purses",
  resp_body: nil,
  resp_cookies: %{},
  resp_headers: [
    {"cache-control", "max-age=0, private, must-revalidate"},
    {"x-request-id", "Fty5IL7nWEhsscoAAArD"}
  ],
  scheme: :http,
  script_name: [],
  secret_key_base: :...,
  state: :unset,
  status: nil
}

As there is a connection initiated by plow - and the params field is empty (where i expect to see the contents of the JSON file stated above) - there is some grounds to believe that the file is not parsed.

Can kindly advise regarding the format of the JSON file - as there is no documentation with regards to how should it be formatted? For clarity, I have cut and pasted the content of @post.json again:

{
"test": {
"test_id": "100",
"account_id": "2176db06-dc03-4f21-8de4-de38df531c53",
"funds_balance": "1",
"funds_withheld": "1",
"funds_escrow": "1",
"currency": "thb"
}
}

Many thanks.

six-ddc commented 2 years ago

Can you achieve that you expected with curl?

gaslit commented 2 years ago
curl --location --request POST 'http://localhost:4000/api/purses/' \
--header 'Content-Type: application/json' \
--data-raw '{
    "test": {
        "test_id": "100",
        "account_id": "2176db06-dc03-4f21-8de4-de38df531c53",
        "funds_balance": "1",
        "funds_withheld": "1",
        "funds_escrow": "1",
        "currency": "thb"
    }
}

Hi this cURL command works perfectly. But unfortunately I cannot replicate this using plow

Do you think theres anything wrong w the JSON formatting above? I am on the precompiled plow 1.1.0 on Windows 10. Not using WSL.

Many thanks.

six-ddc commented 2 years ago

Try removing --stream

gaslit commented 2 years ago

I tried that already/again. The result is still the same. :( Appreciate your kind help in this.

gaslit commented 2 years ago

Hi @six-ddc did quite a fair bit of testing and managed to make it work.

plow http://localhost:4000/api/ -c 1 -n 1 --body @post.json -T "application/json" -m POST -H "Content-Length:262; Host:localhost:4000"

  1. Do not need to use stream. But it works even with --stream switch
  2. Note that all params need to be enclosed using double quotes on Windows. The single quotes somehow caused the "application/json" parameter to never be passed and no parsing of the JSON is carried out.

TLDR: my bad.

Many thanks.