seanmonstar/warp

HELP: Post & Get issue

badonyt opened this issue · 16 comments

Version

├── cargo-tree v0.29.0
│   ├── anyhow v1.0.68
│   ├── cargo_metadata v0.9.1
│   │   ├── semver v0.9.0
│   │   │   ├── semver-parser v0.7.0
│   │   │   └── serde v1.0.152
│   │   ├── serde v1.0.152
│   │   ├── serde_derive v1.0.152 (proc-macro)
│   │   │   ├── proc-macro2 v1.0.49
│   │   │   │   └── unicode-ident v1.0.6
│   │   │   ├── quote v1.0.23
│   │   │   │   └── proc-macro2 v1.0.49 (*)
│   │   │   └── syn v1.0.107
│   │   │       ├── proc-macro2 v1.0.49 (*)
│   │   │       ├── quote v1.0.23 (*)
│   │   │       └── unicode-ident v1.0.6
│   │   └── serde_json v1.0.91
│   │       ├── itoa v1.0.5
│   │       ├── ryu v1.0.12
│   │       └── serde v1.0.152
│   ├── petgraph v0.4.13
│   │   ├── fixedbitset v0.1.9
│   │   └── ordermap v0.3.5
│   ├── semver v0.9.0 (*)
│   ├── serde_json v1.0.91 (*)
│   └── structopt v0.3.26
│       ├── clap v2.34.0
│       │   ├── ansi_term v0.12.1
│       │   ├── atty v0.2.14
│       │   │   └── libc v0.2.139
│       │   ├── bitflags v1.3.2
│       │   ├── strsim v0.8.0
│       │   ├── textwrap v0.11.0
│       │   │   └── unicode-width v0.1.10
│       │   ├── unicode-width v0.1.10
│       │   └── vec_map v0.8.2
│       ├── lazy_static v1.4.0
│       └── structopt-derive v0.4.18 (proc-macro)
│           ├── heck v0.3.3
│           │   └── unicode-segmentation v1.10.0
│           ├── proc-macro-error v1.0.4
│           │   ├── proc-macro-error-attr v1.0.4 (proc-macro)
│           │   │   ├── proc-macro2 v1.0.49 (*)
│           │   │   └── quote v1.0.23 (*)
│           │   │   [build-dependencies]
│           │   │   └── version_check v0.9.4
│           │   ├── proc-macro2 v1.0.49 (*)
│           │   ├── quote v1.0.23 (*)
│           │   └── syn v1.0.107 (*)
│           │   [build-dependencies]
│           │   └── version_check v0.9.4
│           ├── proc-macro2 v1.0.49 (*)
│           ├── quote v1.0.23 (*)
│           └── syn v1.0.107 (*)
├── tokio v1.24.1
│   ├── bytes v1.3.0
│   ├── libc v0.2.139
│   ├── memchr v2.5.0
│   ├── mio v0.8.5
│   │   ├── libc v0.2.139
│   │   └── log v0.4.17
│   │       └── cfg-if v1.0.0
│   ├── num_cpus v1.15.0
│   │   └── libc v0.2.139
│   ├── parking_lot v0.12.1
│   │   ├── lock_api v0.4.9
│   │   │   └── scopeguard v1.1.0
│   │   │   [build-dependencies]
│   │   │   └── autocfg v1.1.0
│   │   └── parking_lot_core v0.9.5
│   │       ├── cfg-if v1.0.0
│   │       ├── libc v0.2.139
│   │       └── smallvec v1.10.0
│   ├── pin-project-lite v0.2.9
│   ├── signal-hook-registry v1.4.0
│   │   └── libc v0.2.139
│   ├── socket2 v0.4.7
│   │   └── libc v0.2.139
│   └── tokio-macros v1.8.2 (proc-macro)
│       ├── proc-macro2 v1.0.49 (*)
│       ├── quote v1.0.23 (*)
│       └── syn v1.0.107 (*)
│   [build-dependencies]
│   └── autocfg v1.1.0
└── warp v0.3.3
    ├── bytes v1.3.0
    ├── futures-channel v0.3.25
    │   ├── futures-core v0.3.25
    │   └── futures-sink v0.3.25
    ├── futures-util v0.3.25
    │   ├── futures-core v0.3.25
    │   ├── futures-sink v0.3.25
    │   ├── futures-task v0.3.25
    │   ├── pin-project-lite v0.2.9
    │   ├── pin-utils v0.1.0
    │   └── slab v0.4.7
    │       [build-dependencies]
    │       └── autocfg v1.1.0
    ├── headers v0.3.8
    │   ├── base64 v0.13.1
    │   ├── bitflags v1.3.2
    │   ├── bytes v1.3.0
    │   ├── headers-core v0.2.0
    │   │   └── http v0.2.8
    │   │       ├── bytes v1.3.0
    │   │       ├── fnv v1.0.7
    │   │       └── itoa v1.0.5
    │   ├── http v0.2.8 (*)
    │   ├── httpdate v1.0.2
    │   ├── mime v0.3.16
    │   └── sha1 v0.10.5
    │       ├── cfg-if v1.0.0
    │       ├── cpufeatures v0.2.5
    │       └── digest v0.10.6
    │           ├── block-buffer v0.10.3
    │           │   └── generic-array v0.14.6
    │           │       └── typenum v1.16.0
    │           │       [build-dependencies]
    │           │       └── version_check v0.9.4
    │           └── crypto-common v0.1.6
    │               ├── generic-array v0.14.6 (*)
    │               └── typenum v1.16.0
    ├── http v0.2.8 (*)
    ├── hyper v0.14.23
    │   ├── bytes v1.3.0
    │   ├── futures-channel v0.3.25 (*)
    │   ├── futures-core v0.3.25
    │   ├── futures-util v0.3.25 (*)
    │   ├── h2 v0.3.15
    │   │   ├── bytes v1.3.0
    │   │   ├── fnv v1.0.7
    │   │   ├── futures-core v0.3.25
    │   │   ├── futures-sink v0.3.25
    │   │   ├── futures-util v0.3.25 (*)
    │   │   ├── http v0.2.8 (*)
    │   │   ├── indexmap v1.9.2
    │   │   │   └── hashbrown v0.12.3
    │   │   │   [build-dependencies]
    │   │   │   └── autocfg v1.1.0
    │   │   ├── slab v0.4.7 (*)
    │   │   ├── tokio v1.24.1 (*)
    │   │   ├── tokio-util v0.7.4
    │   │   │   ├── bytes v1.3.0
    │   │   │   ├── futures-core v0.3.25
    │   │   │   ├── futures-sink v0.3.25
    │   │   │   ├── pin-project-lite v0.2.9
    │   │   │   ├── tokio v1.24.1 (*)
    │   │   │   └── tracing v0.1.37
    │   │   │       ├── cfg-if v1.0.0
    │   │   │       ├── log v0.4.17 (*)
    │   │   │       ├── pin-project-lite v0.2.9
    │   │   │       └── tracing-core v0.1.30
    │   │   │           └── once_cell v1.17.0
    │   │   └── tracing v0.1.37 (*)
    │   ├── http v0.2.8 (*)
    │   ├── http-body v0.4.5
    │   │   ├── bytes v1.3.0
    │   │   ├── http v0.2.8 (*)
    │   │   └── pin-project-lite v0.2.9
    │   ├── httparse v1.8.0
    │   ├── httpdate v1.0.2
    │   ├── itoa v1.0.5
    │   ├── pin-project-lite v0.2.9
    │   ├── socket2 v0.4.7 (*)
    │   ├── tokio v1.24.1 (*)
    │   ├── tower-service v0.3.2
    │   ├── tracing v0.1.37 (*)
    │   └── want v0.3.0
    │       ├── log v0.4.17 (*)
    │       └── try-lock v0.2.4
    ├── log v0.4.17 (*)
    ├── mime v0.3.16
    ├── mime_guess v2.0.4
    │   ├── mime v0.3.16
    │   └── unicase v2.6.0
    │       [build-dependencies]
    │       └── version_check v0.9.4
    │   [build-dependencies]
    │   └── unicase v2.6.0 (*)
    ├── multipart v0.18.0
    │   ├── buf_redux v0.8.4
    │   │   ├── memchr v2.5.0
    │   │   └── safemem v0.3.3
    │   ├── httparse v1.8.0
    │   ├── log v0.4.17 (*)
    │   ├── mime v0.3.16
    │   ├── mime_guess v2.0.4 (*)
    │   ├── quick-error v1.2.3
    │   ├── rand v0.8.5
    │   │   ├── libc v0.2.139
    │   │   ├── rand_chacha v0.3.1
    │   │   │   ├── ppv-lite86 v0.2.17
    │   │   │   └── rand_core v0.6.4
    │   │   │       └── getrandom v0.2.8
    │   │   │           ├── cfg-if v1.0.0
    │   │   │           └── libc v0.2.139
    │   │   └── rand_core v0.6.4 (*)
    │   ├── safemem v0.3.3
    │   ├── tempfile v3.3.0
    │   │   ├── cfg-if v1.0.0
    │   │   ├── fastrand v1.8.0
    │   │   ├── libc v0.2.139
    │   │   └── remove_dir_all v0.5.3
    │   └── twoway v0.1.8
    │       └── memchr v2.5.0
    ├── percent-encoding v2.2.0
    ├── pin-project v1.0.12
    │   └── pin-project-internal v1.0.12 (proc-macro)
    │       ├── proc-macro2 v1.0.49 (*)
    │       ├── quote v1.0.23 (*)
    │       └── syn v1.0.107 (*)
    ├── rustls-pemfile v0.2.1
    │   └── base64 v0.13.1
    ├── scoped-tls v1.0.1
    ├── serde v1.0.152
    ├── serde_json v1.0.91 (*)
    ├── serde_urlencoded v0.7.1
    │   ├── form_urlencoded v1.1.0
    │   │   └── percent-encoding v2.2.0
    │   ├── itoa v1.0.5
    │   ├── ryu v1.0.12
    │   └── serde v1.0.152
    ├── tokio v1.24.1 (*)
    ├── tokio-stream v0.1.11
    │   ├── futures-core v0.3.25
    │   ├── pin-project-lite v0.2.9
    │   └── tokio v1.24.1 (*)
    ├── tokio-tungstenite v0.17.2
    │   ├── futures-util v0.3.25 (*)
    │   ├── log v0.4.17 (*)
    │   ├── tokio v1.24.1 (*)
    │   └── tungstenite v0.17.3
    │       ├── base64 v0.13.1
    │       ├── byteorder v1.4.3
    │       ├── bytes v1.3.0
    │       ├── http v0.2.8 (*)
    │       ├── httparse v1.8.0
    │       ├── log v0.4.17 (*)
    │       ├── rand v0.8.5 (*)
    │       ├── sha-1 v0.10.1
    │       │   ├── cfg-if v1.0.0
    │       │   ├── cpufeatures v0.2.5
    │       │   └── digest v0.10.6 (*)
    │       ├── thiserror v1.0.38
    │       │   └── thiserror-impl v1.0.38 (proc-macro)
    │       │       ├── proc-macro2 v1.0.49 (*)
    │       │       ├── quote v1.0.23 (*)
    │       │       └── syn v1.0.107 (*)
    │       ├── url v2.3.1
    │       │   ├── form_urlencoded v1.1.0 (*)
    │       │   ├── idna v0.3.0
    │       │   │   ├── unicode-bidi v0.3.8
    │       │   │   └── unicode-normalization v0.1.22
    │       │   │       └── tinyvec v1.6.0
    │       │   │           └── tinyvec_macros v0.1.0
    │       │   └── percent-encoding v2.2.0
    │       └── utf-8 v0.7.6
    ├── tokio-util v0.7.4 (*)
    ├── tower-service v0.3.2
    └── tracing v0.1.37 (*)

Platform
Linux bad-ms7a38 6.1.3-zen1-1-zen #1 ZEN SMP PREEMPT_DYNAMIC Wed, 04 Jan 2023 16:28:17 +0000 x86_64 GNU/Linux

Description

This code is not working, there are various issues 1) in line 20, "let test .." when i go to localhost:3000/RUST_TEST/www/name_of_file_in_a_folder it responds with a HTTP method not allowed. 2) in the post method the /employees/:rate when i try to do a post request with js, it doesnt work

#![deny(warnings)]

use serde_derive::{Deserialize, Serialize};

use warp::Filter;


#[derive(Deserialize, Serialize)]
struct Employee {
    name: String,
    rate: u32,
}

#[tokio::main]
async fn main() {
    pretty_env_logger::init();
    // GET /
    let hello_world = warp::path::end().map(|| "Hello, World at root!");
    // POST /employees/:rate  {"name":"Sean","rate":2}
    let test = warp::path("static")
    .and(warp::fs::dir("RUST/www"));
    let promote = warp::post()
        .and(warp::path("employees"))
        .and(warp::path::param::<u32>())
        // Only accept bodies smaller than 16kb...
        .and(warp::body::content_length_limit(1024 * 16))
        .and(warp::body::json())
        .map(|rate, mut employee: Employee| {
            employee.rate = rate;
            warp::reply::json(&employee)
        });

        let routes = warp::get().and(
            test
            .or(hello_world)
                .or(promote)
                

        );

    warp::serve(routes).run(([127, 0, 0, 1], 3000)).await
}


the js code i referenced:

const data = {"name":"Sean","rate":2}
function test(){

    fetch('https://localhost:3000/employees/:rate', {
        method: 'POST', // or 'PUT'
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(data),
      })
}

test()

this being my project dir:
image

kaj commented

The server says "method not allowed" instead of "not found" since you essentially handle a route that is get().and(path("something")) instead of path("something").and(get()).

And it's not found since you ask for /RUST_TEST/etc but have nothing in the router that matches RUST_TEST (that the code is in a directory / project with that name does not matter).

I don't think any of this is a bug in warp (even if the first part is a bit peculiar).

hey so i someone explained me that on the discord, can you explain the post

kaj commented

Your routes are:

        let routes = warp::get().and(test.or(hello_world).or(promote));

Essentially, your code does not accept any POST requests, only GET.

oh, so thats the issue

how can i fix it then?

kaj commented

Maybe you ment to do:

let routes = warp::get().and(test)
            .or(hello_world)
            .or(promote);

Only one end-parenthesis moved from your code, but here the requirement for a GET request applies only to test, and not for the hello_world or promote routes?

To make it clearer, I would use:

let routes = test
            .or(hello_world)
            .or(promote);

and move the get into test:

let test = warp::path("static").and(warp::get())
    .and(warp::fs::dir("RUST/www"));

Hey but to make the post request where should i point it to?

kaj commented

Your promote router handles POST requests that seems to match the request you create in your js code:

let promote = warp::post()
        .and(warp::path("employees"))
        .and(warp::path::param::<u32>())
        // Only accept bodies smaller than 16kb...
        .and(warp::body::content_length_limit(1024 * 16))
        .and(warp::body::json())
        .map(|rate, mut employee: Employee| {
            employee.rate = rate;
            warp::reply::json(&employee)
        });

Now, I would move the warp::post() matcher here to after the url matching, where you have the comment, so it gets:

let promote = warp::path("employees")
        .and(warp::path::param::<u32>())
        .and(warp::post())
        // Only accept bodies smaller than 16kb...
        .and(warp::body::content_length_limit(1024 * 16))
        .and(warp::body::json())
        .map(|rate, mut employee: Employee| {
            employee.rate = rate;
            warp::reply::json(&employee)
        });

my fetch still fails with code i said before

my rust code now:

#![deny(warnings)]

use serde_derive::{Deserialize, Serialize};

use warp::Filter;


#[derive(Deserialize, Serialize)]
struct Employee {
    name: String,
    rate: u32,
}

#[tokio::main]
async fn main() {
    pretty_env_logger::init();
    // GET /
    let hello_world = warp::path::end().map(|| "Hello, World at root!");
    // POST /employees/:rate  {"name":"Sean","rate":2}
    let test = warp::path("static").and(warp::get())
    .and(warp::fs::dir("www"));
    let promote = warp::path("employees")
        .and(warp::path::param::<u32>())
        .and(warp::post())
        // Only accept bodies smaller than 16kb...
        .and(warp::body::content_length_limit(1024 * 16))
        .and(warp::body::json())
        .map(|rate, mut employee: Employee| {
            employee.rate = rate;
            warp::reply::json(&employee)
        });
        let routes = test
            .or(hello_world)
            .or(promote);

    warp::serve(routes).run(([127, 0, 0, 1], 3000)).await
}


kaj commented

I copied the code in your last example, and it seems to work:

:; curl http://localhost:3000/
Hello, World at root!
:; curl -t POST --data-raw '{"name":"Rasmus Kaj","rate":3500}' --header 'content-type: application/json' http://localhost:3000/employees/4711
{"name":"Rasmus Kaj","rate":4711} 

But does your javascript post where you intended it to post? It seems the :rate in the url parameter to fetch should be replaced with a number, but I don't see anything to replace it.

image
Im super confused, if i want to do a normal post request with js, how do i do it then. Also the command didnt work

kaj commented

Im super confused, if i want to do a normal post request with js, how do i do it then. Also the command didnt work

I'm afraid we're going of topic here. The Json on the end of your curl command is not supposed to be there, my curl command is one line only, you included the out json (the response from the server) from my comment when copying the command.

lets say i want to do a post request, where do i point it at?

kaj commented

With this server, you can post to the promote handler. That is, the url should look like http://localhost:3000/employees/4711. The number 4711 at the end can be replace with any number (any string that can be parsed into an u32). If it does, the handler goes on to check that the post body isn't to long. Then that the post body is json (according to content-type and syntax) and has the correct fields to be parsed into an Employee.

In my curl example, the arguments were:

  • -t POST -- make sure the request is a post request.
  • --data-raw '{"name":"Rasmus Kaj","rate":3500}' -- send some valid json Employee data
  • --header 'content-type: application/json' -- set content type (for the post data above) to json
  • http://localhost:3000/employees/4711 -- an url that is matched by the promote handler.

thanks