iron / router Goto Github PK
View Code? Open in Web Editor NEWRouter middleware for the Iron web framework.
Router middleware for the Iron web framework.
I am working with iron
to build a JSON-API. The idea is to have one API
struct that puts the different namespaces upon the root URL /api
, which would then allow to seperate the different namespaces in their own files. e.g.
let mut router = Router::new();
router.get("/api/", namespace1());
router.get("/api/", namespace2());
fn namespace1() -> Router {
let mut router = Router::new();
router.get("namespace1", some_fn);
router.post("namespace1", some_post_fn);
router;
}
My expectation was, that after a call to /api/namespace1
the result from some_fn
get's returned. I could not get it to work though.
I think that makes some sense as Router
has already the Handler
trait implemented and it would allow for the creation of bigger applications.
extern crate http;
extern crate iron;
extern crate router;
use std::io::net::ip::Ipv4Addr;
use iron::{status, Iron, Request, Response, IronResult};
use router::{Router};
fn main(){
let mut router = Router::new();
router.get("/", handler);
Iron::new(router).listen(Ipv4Addr(127, 0, 0, 1), 3000);
println!("On 3000");
fn handler(_: &mut Request) -> IronResult<Response> {
Ok(Response::with(status::Ok, "Hello, world"))
}
}
Parameters should be separated from their query strings, beginning with the ?
or the url.
Hey,
currently in router.rs
it says:
self.handle_method(req, &path).unwrap_or(
Err(IronError::new(NoRoute, status::NotFound))
)
It would be nice if this was less hardcoded and if it was possible to create a custom NotFound
error page. Maybe add an optional special handler to the Router
struct?
unstabilizing #[bench]
(rust-lang/rust#62507) has broken the route-recognizer
crate's ability to build on nightly:
$ cargo +nigtly build
...
error[E0658]: use of unstable library feature 'test': `bench` is a part of custom test frameworks which are unstable
#[bench]
^^^^^
help: add `#![feature(test)]` to the crate attributes to enable
I have a PR open... http-rs/route-recognizer#25
To clarify:
nightly-2019-07-31
- ✔️nightly-2019-07-31-x86_64-unknown-linux-gnu installed - rustc 1.38.0-nightly (dddb7fca0 2019-07-30)
)nightly-2019-08-01
- ✔️nightly-2019-08-01-x86_64-unknown-linux-gnu installed - rustc 1.38.0-nightly (8a58268b5 2019-07-31)
)nightly-2019-08-02
- ❌nightly-2019-08-02-x86_64-unknown-linux-gnu installed - rustc 1.38.0-nightly (435236b88 2019-08-01)
)/Users/david/.cargo/registry/src/github.com-1ecc6299db9ec823/router-0.0.9/src/lib.rs:8:14: 8:32 error: expected ident, found `"route-recognizer"`
/Users/david/.cargo/registry/src/github.com-1ecc6299db9ec823/router-0.0.9/src/lib.rs:8 extern crate "route-recognizer" as recognizer;
I grabbed the router example and ran it so I'm not sure what the problem is : (
let's say I mounted a router to admin/
and use url_for
within a handler of that router.
let routes = router!(
foo: post "foo" => |req: &mut Request| {
Ok(Response::with(Redirect(url_for!(req, "dashboard"))))
});
let admin = Chain::new(router);
let mut mounts = Mount::new();
mounts.mount("/admin", routes);
The redirect url points to /dashboard
instead of /admin/dashboard
.
How would you solve this?
Trying to compile this router example currently fails with the latest Iron release (0.6.0).
Tested with a new project containing the above code, and Cargo.toml
containing:
iron = "*"
router = "*"
This give the following compiler errors:
error[E0281]: type mismatch: `fn(&mut iron::Request<'_, '_>) -> std::result::Result<iron::Response, iron::IronError> {main::handler}` implements the trait `for<'r, 'r, 'r> std::ops::Fn<(&'r mut iron::Request<'r, 'r>,)>`, but the trait `for<'r, 'r, 'r> std::ops::Fn<(&'r mut iron::request::Request<'r, 'r>,)>` is required
--> src/main.rs:10:12
|
10 | router.get("/", handler, "index"); // let router = router!(index: get "/" => handler,
| ^^^ expected struct `iron::request::Request`, found struct `iron::Request`
|
= note: required because of the requirements on the impl of `iron::middleware::Handler` for `fn(&mut iron::Request<'_, '_>) -> std::result::Result<iron::Response, iron::IronError> {main::handler}`
error[E0281]: type mismatch: `fn(&mut iron::Request<'_, '_>) -> std::result::Result<iron::Response, iron::IronError> {main::handler}` implements the trait `for<'r, 'r, 'r> std::ops::Fn<(&'r mut iron::Request<'r, 'r>,)>`, but the trait `for<'r, 'r, 'r> std::ops::Fn<(&'r mut iron::request::Request<'r, 'r>,)>` is required
--> src/main.rs:11:12
|
11 | router.get("/:query", handler, "query"); // query: get "/:query" => handler);
| ^^^ expected struct `iron::request::Request`, found struct `iron::Request`
|
= note: required because of the requirements on the impl of `iron::middleware::Handler` for `fn(&mut iron::Request<'_, '_>) -> std::result::Result<iron::Response, iron::IronError> {main::handler}`
error[E0277]: the trait bound `for<'r, 'r, 'r> router::Router: std::ops::Fn<(&'r mut iron::Request<'r, 'r>,)>` is not satisfied
--> src/main.rs:13:5
|
13 | Iron::new(router).http("localhost:3000").unwrap();
| ^^^^^^^^^ the trait `for<'r, 'r, 'r> std::ops::Fn<(&'r mut iron::Request<'r, 'r>,)>` is not implemented for `router::Router`
|
= note: required because of the requirements on the impl of `iron::Handler` for `router::Router`
= note: required by `<iron::Iron<H>>::new`
error[E0599]: no method named `http` found for type `iron::Iron<router::Router>` in the current scope
--> src/main.rs:13:23
|
13 | Iron::new(router).http("localhost:3000").unwrap();
| ^^^^
|
= note: the method `http` exists but the following trait bounds were not satisfied:
`router::Router : iron::Handler`
error: aborting due to 4 previous errors
the example mentions:
method::Get
https://github.com/iron/router/blob/master/src/router.rs#L63
where is this method::Get defined anyway?
The Python webframework Flask has the following syntax for routing expressions:
/foo/<var1>/bar/ # var1 is a string
/foo/var2:int/bar/ # var2 is matched iff it is parseable as int
/foo/var3:customtype/bar/ # var3 is matched against a custom type that has to be registered upfront
The whole typesystem is a thing I'd like to see in the Iron router middleware, but I'm primarily interested in the following:
/foo/<var4:path>/bar/
That route will match against:
var4="baz"
var4="baz/bam"
and so on. I know that I can match against wildcards, but I need a way to access the matched path segments.
Hi. In case I'd contribute a CHANGELOG file for the current history, would you merge it and keep it up to date?
See also: https://blog.dbrgn.ch/2015/12/1/rust-crates-keep-a-changelog/
See the specification.
The Core bundle seems to be deprecated, yet it is still referenced in the README.
Maybe should be removed?
Just though I'd let you know about this one.
Compiling router v0.1.0 (https://github.com/iron/router.git#e32e187d)
src/router.rs:122:22: 122:38 error: use of deprecated item: Use `Response::new().set(Status(status))` instead., #[deny(deprecated)] on by default
src/router.rs:122 None => (Response::status(status::InternalServerError), Err(err))
^~~~~~~~~~~~~~~~
error: aborting due to previous error
Could not compile `router`.
As always, thank you for maintaining these libraries!
I would like to write this, but the current structure does not allow it:
let router = Router::new().get("/", handler);
Iron::new(router);
It's really a pain to keep the whole family up to date with Iron.
my Cargo.toml
[package]
name = "iron-fib-rs"
version = "0.0.1"
authors = ["jlgoldb2 <[email protected]>"]
[dependencies.iron]
git = "https://github.com/iron/iron.git"
[dependencies.router]
git = "https://github.com/iron/router.git"
my cargo run
command produces:
Updating git repository `https://github.com/iron/router.git`
Updating git repository `https://github.com/iron/iron.git`
Updating registry `https://github.com/rust-lang/crates.io-index`
Downloading typemap v0.0.4
Downloading url v0.2.1
Downloading openssl-sys v0.2.2
Downloading cookie v0.0.1
Downloading plugin v0.0.0
Downloading mime v0.0.1
Downloading error v0.0.1
Downloading openssl v0.2.2
Downloading iron v0.0.5
Downloading hyper v0.0.6
Downloading pkg-config v0.1.0
Downloading gcc v0.1.0
Downloading phantom v0.0.1
Downloading typeable v0.0.2
Downloading modifier v0.0.3
Downloading unsafe-any v0.1.1
Downloading route-recognizer v0.1.1
Downloading time v0.1.0
Compiling gcc v0.1.0
Compiling url v0.2.1
Compiling mime v0.0.1
Compiling pkg-config v0.1.0
Compiling typeable v0.0.2
Compiling unsafe-any v0.1.1
Compiling phantom v0.0.1
Compiling modifier v0.0.3
src/lib.rs:1:1: 1:20 error: unused attribute, #[deny(unused_attributes)] on by default
src/lib.rs:1 #![license = "MIT"]
^~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
Compiling route-recognizer v0.1.1
Build failed, waiting for other jobs to finish...
src/lib.rs:1:1: 1:20 error: unused attribute, #[deny(unused_attributes)] on by default
src/lib.rs:1 #![license = "MIT"]
^~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
Could not compile `typeable`.
To learn more, run the command again with --verbose.
my cargo --version
:
cargo 0.0.1-pre-nightly (da789a6 2014-11-30 08:14:16 +0000)
my rustc --version
:
rustc 0.13.0-nightly (5484d6f6d 2014-12-02 00:22:00 +0000)
I want to write a middleware that provides custom error pages for the NoRoute
error, but I didn't figure out how to know whether an IronError
is caused by NoRoute
.
This is what I've got:
impl AfterMiddleware for MyErrorHandler {
fn catch(&self, req: &mut Request, err: IronError) -> IronResult<Response> {
if /* ??? err.error is NoRoute */ {
// custom handling happens
} else {
Ok(err.response)
}
}
}
Currently, to have a router forward requests for "/" and "/index.html" (and "/js/example.js", etc) to the same handler, I currently have to do something like:
router.get("/", Static::new(Path::new("public")));
router.get("/*", Static::new(Path::new("public"))); // notice the "*"
It would be convenient if I could have both of those redirect to the same handler. For example, this syntax would make sense to me:
router.get("*", Static::new(Path::new("public")));
If there's an option everyone can settle on, I'm happy to take a crack at implementing this.
Thoughts?
When running the example on the front page, I get this dastardly output from the compiler:
error[E0281]: type mismatch: the type
fn(&mut iron::Request<', '>) -> std::result::Result<iron::Response, iron::IronError> {main::handler}implements the trait
for<'r, 'r, 'r> std::ops::Fn<(&'r mut iron::Request<'r, 'r>,)>, but the trait
for<'r, 'r, 'r> std::ops::Fn<(&'r mut iron::request::Request<'r, 'r>,)>is required (expected struct
iron::request::Request, found struct
iron::Request)
Could this be related to rustc's problems with higher-ranked trait bounds?
There shouldn't be a difference between iron::request::Request and iron::Request.
Hi,
this happens both with beta version and to nightly version 1.0.0-nightly (083b8a404 2015-04-05) (built 2015-04-05).
This issue #23037 is open at rust repo. Not sure if the lib authors can solve alone.
src/router.rs:158:1: 158:45 error: internal compiler error: coherence failed to report ambiguity: cannot locate the impl of the trait `core::marker::MarkerTrait` for the type `iron::middleware::Handler`
src/router.rs:158 impl Key for Router { type Value = Params; }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports
note: run with `RUST_BACKTRACE=1` for a backtrace
thread 'rustc' panicked at 'Box<Any>', /home/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libsyntax/diagnostic.rs:130
stack backtrace:
1: 0x7fb7a59807b8 - sys::backtrace::write::h4618bbda30a2c1fakHC
2: 0x7fb7a59abb87 - panicking::on_panic::h94b32ff0a2406463uUI
3: 0x7fb7a58e3893 - rt::unwind::begin_unwind_inner::h310b6bce2d1d1820CzI
4: 0x7fb7a2c8af1d - rt::unwind::begin_unwind::h11208009626465183390
5: 0x7fb7a2c8aec3 - diagnostic::SpanHandler::span_bug::he0c1a59febe6c207YmB
6: 0x7fb7a385106d - middle::traits::error_reporting::report_fulfillment_error::h978d9d7604a71a71FQN
7: 0x7fb7a36cf1c1 - middle::traits::error_reporting::report_fulfillment_errors::hecc972a8fd21c54dVPN
8: 0x7fb7a45c65ec - check::vtable::select_all_fcx_obligations_or_error::haf7db39d8950f48dX1b
9: 0x7fb7a4650389 - check::wf::CheckTypeWellFormedVisitor<'ccx, 'tcx>::check_item_well_formed::h857600b69cfccd2amWk
10: 0x7fb7a4658b52 - visit::walk_item::h9604823204726736875
11: 0x7fb7a4752ec9 - check_crate::closure.36365
12: 0x7fb7a474d473 - check_crate::hda9802680caa3ff01oC
13: 0x7fb7a6000efd - driver::phase_3_run_analysis_passes::h763b1cd8b2718376gGa
14: 0x7fb7a5fe4d55 - driver::compile_input::hd78076fc32781e7dQba
15: 0x7fb7a609c3c5 - run_compiler::hff161264a18135f2S4b
16: 0x7fb7a6099cdd - boxed::F.FnBox<A>::call_box::h610426945469311335
17: 0x7fb7a6099219 - rt::unwind::try::try_fn::h14135578949834830543
18: 0x7fb7a5a28338 - rust_try_inner
19: 0x7fb7a5a28325 - rust_try
20: 0x7fb7a60994eb - boxed::F.FnBox<A>::call_box::h11897562677317506333
21: 0x7fb7a5996b71 - sys::thread::create::thread_start::h0a2c84bef4c472f7MuH
22: 0x7fb79f76a181 - start_thread
23: 0x7fb7a554647c - __clone
24: 0x0 - <unknown>
Could not compile `router`.
Bests
I'm using iron v0.4.0 and router v0.1.1 . When I try to compile the example code from the README I get the following error output:
src/main.rs:12:12: 12:15 error: type mismatch: the type `fn(&mut iron::Request<'_, '_>) -> std::result::Result<iron::Response, iron::IronError> {main::handler}` implements the trait `for<'r, 'r, 'r> std::ops::Fn<(&'r mut iron::Request<'r, 'r>,)>`, but the trait `for<'r, 'r, 'r> std::ops::Fn<(&'r mut iron::request::Request<'r, 'r>,)>` is required (expected struct `iron::request::Request`, found struct `iron::Request`) [E0281]
src/main.rs:12 router.get("/", handler);
^~~
src/main.rs:12:12: 12:15 help: run `rustc --explain E0281` to see a detailed explanation
src/main.rs:12:12: 12:15 note: required because of the requirements on the impl of `iron::middleware::Handler` for `fn(&mut iron::Request<'_, '_>) -> std::result::Result<iron::Response, iron::IronError> {main::handler}`
src/main.rs:12:12: 12:15 error: type mismatch: the type `fn(&mut iron::Request<'_, '_>) -> std::result::Result<iron::Response, iron::IronError> {main::handler}` implements the trait `for<'r, 'r, 'r> std::ops::FnOnce<(&'r mut iron::Request<'r, 'r>,)>`, but the trait `for<'r, 'r, 'r> std::ops::FnOnce<(&'r mut iron::request::Request<'r, 'r>,)>` is required (expected struct `iron::request::Request`, found struct `iron::Request`) [E0281]
src/main.rs:12 router.get("/", handler);
^~~
src/main.rs:12:12: 12:15 help: run `rustc --explain E0281` to see a detailed explanation
src/main.rs:12:12: 12:15 note: required because of the requirements on the impl of `iron::middleware::Handler` for `fn(&mut iron::Request<'_, '_>) -> std::result::Result<iron::Response, iron::IronError> {main::handler}`
src/main.rs:13:12: 13:15 error: type mismatch: the type `fn(&mut iron::Request<'_, '_>) -> std::result::Result<iron::Response, iron::IronError> {main::handler}` implements the trait `for<'r, 'r, 'r> std::ops::Fn<(&'r mut iron::Request<'r, 'r>,)>`, but the trait `for<'r, 'r, 'r> std::ops::Fn<(&'r mut iron::request::Request<'r, 'r>,)>` is required (expected struct `iron::request::Request`, found struct `iron::Request`) [E0281]
src/main.rs:13 router.get("/:query", handler);
^~~
src/main.rs:13:12: 13:15 help: run `rustc --explain E0281` to see a detailed explanation
src/main.rs:13:12: 13:15 note: required because of the requirements on the impl of `iron::middleware::Handler` for `fn(&mut iron::Request<'_, '_>) -> std::result::Result<iron::Response, iron::IronError> {main::handler}`
src/main.rs:13:12: 13:15 error: type mismatch: the type `fn(&mut iron::Request<'_, '_>) -> std::result::Result<iron::Response, iron::IronError> {main::handler}` implements the trait `for<'r, 'r, 'r> std::ops::FnOnce<(&'r mut iron::Request<'r, 'r>,)>`, but the trait `for<'r, 'r, 'r> std::ops::FnOnce<(&'r mut iron::request::Request<'r, 'r>,)>` is required (expected struct `iron::request::Request`, found struct `iron::Request`) [E0281]
src/main.rs:13 router.get("/:query", handler);
^~~
src/main.rs:13:12: 13:15 help: run `rustc --explain E0281` to see a detailed explanation
src/main.rs:13:12: 13:15 note: required because of the requirements on the impl of `iron::middleware::Handler` for `fn(&mut iron::Request<'_, '_>) -> std::result::Result<iron::Response, iron::IronError> {main::handler}`
src/main.rs:15:5: 15:14 error: the trait bound `for<'r, 'r, 'r> router::Router: std::ops::Fn<(&'r mut iron::Request<'r, 'r>,)>` is not satisfied [E0277]
src/main.rs:15 Iron::new(router).http("localhost:3000").unwrap();
^~~~~~~~~
src/main.rs:15:5: 15:14 help: run `rustc --explain E0277` to see a detailed explanation
src/main.rs:15:5: 15:14 note: required because of the requirements on the impl of `iron::Handler` for `router::Router`
src/main.rs:15:5: 15:14 note: required by `iron::Iron::new`
src/main.rs:15:5: 15:14 error: the trait bound `for<'r, 'r, 'r> router::Router: std::ops::FnOnce<(&'r mut iron::Request<'r, 'r>,)>` is not satisfied [E0277]
src/main.rs:15 Iron::new(router).http("localhost:3000").unwrap();
^~~~~~~~~
src/main.rs:15:5: 15:14 help: run `rustc --explain E0277` to see a detailed explanation
src/main.rs:15:5: 15:14 note: required because of the requirements on the impl of `iron::Handler` for `router::Router`
src/main.rs:15:5: 15:14 note: required by `iron::Iron::new`
src/main.rs:15:23: 15:27 error: no method named `http` found for type `iron::Iron<router::Router>` in the current scope
src/main.rs:15 Iron::new(router).http("localhost:3000").unwrap();
^~~~
src/main.rs:15:23: 15:27 note: the method `http` exists but the following trait bounds were not satisfied: `router::Router : iron::Handler`
error: aborting due to 7 previous errors
I don't have time tonight to dig into this but will be happy to explore more tomorrow.
Also - if this is indeed an error can I suggest that this example be included in the lib
module documentation to prevent breakage in future.
It'd be great if iron router supported URL patterns as regexes. This way we would be able to declare patterns without any ambiguities and offload some param validation to router (e.g. make sure given ID is 3-digit). Coming from Python community, I am familiar with Django URL dispatch module, which I see as a great fit. Right now router uses router-recognizer module, which, IMHO, is quite complicated compared to plain regexes. I've heard Rust has excellent support for regular expressions, so there is some chance it wouldn't be that hard to write some POC implementation, perhaps with same or even better performance. Any thoughts?
Example:
extern crate iron;
#[macro_use]
extern crate router;
use std::env;
use iron::prelude::{
Iron, IronResult, Request, Response
};
fn hello_world(_: &mut Request) -> IronResult<Response> {
Ok(Response::with((iron::status::Ok, "Hello World")))
}
fn main() {
let router = router!(
get "/" => hello_world
);
Iron::new(router)
.http(("0.0.0.0", 5000))
.unwrap();
}
This code probably should compile, but doesn't: the expansion of router!
refers to router::Router
as Router
rather than using $crate::Router
to expand to the correct qualified name.
<router macros>:3:18: 3:30 error: failed to resolve. Use of undeclared type or module `Router` [E0433]
<router macros>:3 let mut router = Router:: new ( ) ; $ (
^~~~~~~~~~~~
<router macros>:1:1: 4:60 note: in expansion of router!
src/main.rs:17:18: 19:6 note: expansion site
<router macros>:3:18: 3:30 help: run `rustc --explain E0433` to see a detailed explanation
<router macros>:3:18: 3:30 error: unresolved name `Router::new` [E0425]
<router macros>:3 let mut router = Router:: new ( ) ; $ (
^~~~~~~~~~~~
<router macros>:1:1: 4:60 note: in expansion of router!
src/main.rs:17:18: 19:6 note: expansion site
<router macros>:3:18: 3:30 help: run `rustc --explain E0425` to see a detailed explanation
error: aborting due to 2 previous errors
Compiling router v0.0.8 ( [removed]/router)
src/router.rs:157:1: 172:2 error: overflow evaluating the requirement `Box<iron::middleware::Handler> : core::marker::Send` [E0275]
src/router.rs:157 impl Handler for Router {
src/router.rs:158 fn handle(&self, req: &mut Request) -> IronResult<Response> {
src/router.rs:159 if req.url.path.len() != 1 && Some(&String::new()) == req.url.path.last() {
src/router.rs:160 return self.handle_trailing_slash(req);
src/router.rs:161 }
src/router.rs:162
...
src/router.rs:157:1: 172:2 note: consider adding a `#![recursion_limit="128"]` attribute to your crate
src/router.rs:157 impl Handler for Router {
src/router.rs:158 fn handle(&self, req: &mut Request) -> IronResult<Response> {
src/router.rs:159 if req.url.path.len() != 1 && Some(&String::new()) == req.url.path.last() {
src/router.rs:160 return self.handle_trailing_slash(req);
src/router.rs:161 }
src/router.rs:162
...
...rest is truncated...
This happens with rustc 1.0.0-nightly (2b01a37ec 2015-02-21) (built 2015-02-21)
.
I wonder if it has something to do with this: rust-lang/rust#22655
This page has no explaining text. I've found this snippet let ref query = req.extensions.get::<Router>().unwrap().find("query").unwrap_or("/");
that's probably enough for me to implement what I want and I think it uses this. I think I'm starting to understand it but without the example I wouldn't stand a chance.
I want to proxy the requests through another domain.(CDN)
The problem is that the it redirects to the underlying server domain address and not the domain that the CDN uses.
Right now I'd have to depend on url
to achieve this task.
This will match with Mount and Filter as a verb. Wanted to throw this out for discussion.
@iron/dev-team Thoughts?
I opened rust-lang/rust#24037 for the ICE. I will keep this ticket for reference until the ICE is fixed.
Iron should write "hello " in plain text to the client.
Nothing is returned to the client.
It would be great if router would return a "HTTP 405 Method Not Allowed" for routes where a route exists, but a non-matching request method was used.
Example:
router.get("/things", thing_list_handler);
router.post("/things", thing_create_handler);
Here a PUT request to /things should result in a HTTP 405.
I realize that this could be implemented with an any
route for all paths, but turning this on globally would make things much simpler.
It would be nice to be able to create (and check) a Router
at compile-time, since the routes are almost always constant and created at the beginning of the program. It could look like this:
router!(get: "/" => index,
get: "/:query" => queryHandler,
post: "/" => postHandler)
We could also allow the plugin to read a text file with the routes, something like router_file!("routes.txt")
.
Do you think this would be a good idea?
I have a use case in which some routes need to dispatch requests to wrapper handlers which then forward those requests on to a dynamic set of handlers; the set of handlers and the methods they handle are only determined at runtime.
Currently, I have to map each HTTP method to the same glob and have multiple instances of each wrapper handler. Would it be possible to introduce a forwarding route that just matches the glob and does not care about the HTTP method?
Or perhaps multiple match rules could be specified for each handler and then the forwarding route is just a regular route with no rule to match the HTTP method.
Hi guys. I saw that already there are two issue with such behavior. However, they have not solution. I had some problem with crate mount and crate route.
Simple example
extern crate iron;
extern crate router;
extern crate mount;
use iron::{Iron, Request, Response, IronResult};
use iron::status;
use router::{Router};
fn main() {
let mut router = Router::new();
router.get("/get", query_handler, "query_handler");
fn handler(_: &mut Request) -> IronResult<Response> {
Ok(Response::with((status::Ok, "OK")))
}
fn query_handler(_: &mut Request) -> IronResult<Response> {
Ok(Response::with((status::Ok, "query")))
}
let mut mount = mount::Mount::new();
mount
.mount("/", handler)
.mount("/api", router)
;
Iron::new(mount).http("127.0.0.1:3000").unwrap();
}
When i create request like GET http://www.example.com/api/get/
i had redirect to http://www.example.com/get . This because the mount crate cuts url in there https://github.com/iron/mount/blob/master/src/mount.rs#L119
To use both the crates I had fork this project and add dependency route to mount and add this
let original = req.extensions.get::<mount::OriginalUrl>();
if original.is_some() {
url = original.unwrap().clone();
}
To https://github.com/iron/router/blob/master/src/router.rs#L178
Now all work fine. But the decision I do not like.
The only reasonable solution to move in iron crate this struct
pub struct OriginalUrl;
impl typemap::Key for OriginalUrl { type Value = Url; }
And use in mount and route crate
/home/xav/.cargo/registry/src/github.com-1ecc6299db9ec823/router-0.0.7/src/lib.rs:2:10: 2:18 error: unknown `allow` attribute: `unstable`, #[deny(unknown_lints)] on by default
/home/xav/.cargo/registry/src/github.com-1ecc6299db9ec823/router-0.0.7/src/lib.rs:2 #![allow(unstable)]
^~~~~~~~
error: aborting due to previous error
Build failed, waiting for other jobs to finish...
Example not compiled:
error[E0281]: type mismatch: the type `fn(&mut iron::Request<'_, '_>) -> std::result::Result<iron::Response, iron::IronError> {main::handler}` implements the trait `for<'r, 'r, 'r> std::ops::Fn<(&'r mut iron::Request<'r, 'r>,)>`, but the trait `for<'r, 'r, 'r> std::ops::Fn<(&'r mut iron::request::Request<'r, 'r>,)>` is required (expected struct `iron::request::Request`, found struct `iron::Request`)
--> src\main.rs:10:12
|
10 | router.get("/", handler, "index"); // let router = router!(index: get "/" => handler,
| ^^^
|
= note: required because of the requirements on the impl of `iron::middleware::Handler` for `fn(&mut iron::Request<'_, '_>) -> std::result::Result<iron::Response, iron::IronError> {main::handler}`
The example on project read me is just plain unhelpful. I'd propose a change:
A trailing slash in a URL is important. A URL with a trailing slash is a completely different URL from a URL without a trailing slash. For example, relative links are treated differently.
The router should allow users to treat these URLs differently.
More information:
https://cdivilly.wordpress.com/2014/03/11/why-trailing-slashes-on-uris-are-important/
Flask provides this: http://flask.pocoo.org/docs/0.10/quickstart/#url-building This requires giving each route a unique identifier.
I don't want to hardcode my routes into the application. Is there another established pattern that I am missing?
Just a normal nightly build error:
/home/travis/.cargo/git/checkouts/router-ed914fc2bd2a44a9/master/src/router.rs:2:34: 2:42 error: unresolved import
std::collections::hash_map::Occupied
. There is noOccupied
instd::collections::hash_map
/home/travis/.cargo/git/checkouts/router-ed914fc2bd2a44a9/master/src/router.rs:2 use std::collections::hash_map::{Occupied, Vacant};
I read README sample and try it.
but can't compile this code successfully.
Ok(Response::with(status::Ok, *query))
This is OK.
Ok(Response::with((status::Ok, *query)))
I got started Iron just now, so I'm confused :(
please fix this because I want everybody to enjoy Iron.
Whenever I do a redirect, I get a 404 on the page redirected to, even though the url exists when I reload the exact same url. I have checked the http responses of /auth/login and the page redirected to, and they are both valid.
This is what my handler looks like at the moment.
impl AuthenticationController {
// Route: POST /auth/login
pub fn login(req: &mut Request) -> IronResult<Response> {
let url: Url;
if try!(req.session().get::<middleware::sessions::Login>()).is_some() {
url = url_for!(req, "index", "status" => "already_loggedin");
} else {
if User::authenticate("[email protected]", "password") {
url = url_for!(req, "index", "status" => "success");
} else {
url = url_for!(req, "index", "status" => "failure");
}
}
Ok(Response::with((status::Found, Redirect(url.clone()))))
}
}
It would be great to have support for routes of non-constant lengths, like for instance matching the beginning of a path, and then getting the remainder:
Since there is only one remainder, a useful API would be:
router.get_nonstrict("/constant/:A/:B")
This would match /constant//, store the first two segments in A and B, respectively, and add the remainder of the path in a slice in the extensions TypeMap.
(sorry if this is already possible, maybe it's just a documentation issue).
/home/xav/.cargo/registry/src/github.com-1ecc6299db9ec823/router-0.0.6/src/router.rs:113:5: 122:6 error: method `call` is not a member of trait `Handler`
/home/xav/.cargo/registry/src/github.com-1ecc6299db9ec823/router-0.0.6/src/router.rs:113 fn call(&self, req: &mut Request) -> IronResult<Response> {
/home/xav/.cargo/registry/src/github.com-1ecc6299db9ec823/router-0.0.6/src/router.rs:114 let matched = match self.recognize(&req.method, req.url.path.connect("/").as_slice()) {
/home/xav/.cargo/registry/src/github.com-1ecc6299db9ec823/router-0.0.6/src/router.rs:115 Some(matched) => matched,
/home/xav/.cargo/registry/src/github.com-1ecc6299db9ec823/router-0.0.6/src/router.rs:116 // No match.
/home/xav/.cargo/registry/src/github.com-1ecc6299db9ec823/router-0.0.6/src/router.rs:117 None => return Err(Box::new(NoRoute) as IronError)
/home/xav/.cargo/registry/src/github.com-1ecc6299db9ec823/router-0.0.6/src/router.rs:118 };
...
/home/xav/.cargo/registry/src/github.com-1ecc6299db9ec823/router-0.0.6/src/router.rs:124:5: 130:6 error: method `catch` is not a member of trait `Handler`
/home/xav/.cargo/registry/src/github.com-1ecc6299db9ec823/router-0.0.6/src/router.rs:124 fn catch(&self, req: &mut Request, err: IronError) -> (Response, IronResult<()>) {
/home/xav/.cargo/registry/src/github.com-1ecc6299db9ec823/router-0.0.6/src/router.rs:125 match self.error {
/home/xav/.cargo/registry/src/github.com-1ecc6299db9ec823/router-0.0.6/src/router.rs:126 Some(ref error_handler) => error_handler.catch(req, err),
/home/xav/.cargo/registry/src/github.com-1ecc6299db9ec823/router-0.0.6/src/router.rs:127 // Error that is not caught by anything!
/home/xav/.cargo/registry/src/github.com-1ecc6299db9ec823/router-0.0.6/src/router.rs:128 None => (Response::with(status::InternalServerError), Err(err))
/home/xav/.cargo/registry/src/github.com-1ecc6299db9ec823/router-0.0.6/src/router.rs:129 }
...
error: aborting due to 2 previous errors
Build failed, waiting for other jobs to finish...
Hey there, thanks for fixing the iron core package for Rust nightly.
Unfortunately this broke the compatibility with the router middleware:
This is the error I get:
native library `openssl` is being linked to by more than one package, and can only be linked to by one package
openssl-sys v0.0.2 (https://github.com/sfackler/rust-openssl.git#b7c88101)
openssl-sys v0.0.2
in my toml:
[dependencies.iron]
git = "https://github.com/iron/iron.git"
[dependencies.router]
git = "https://github.com/iron/router.git"
from what I see in my Cargo.lock file the problem is that the iron libs include the openssl-sys package from crates.io and rust-http takes the one from sfackler
on github
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.