Coder Social home page Coder Social logo

Simplify path handling about vertx-web HOT 19 CLOSED

vert-x3 avatar vert-x3 commented on July 17, 2024
Simplify path handling

from vertx-web.

Comments (19)

stephanebastian avatar stephanebastian commented on July 17, 2024

+1, makes perfect sens

from vertx-web.

leolux avatar leolux commented on July 17, 2024

I am not sure about the implementation. Would it restrict the current flexibility to a value below 100%?

It might make sense to some application to handle also parts of a resource for example in RPC-style approaches.

Matrix-parameters in a REST-style application might query multiple levels of resources and sub-resources:
http://example.com/res/categories;name=foo/objects;name=green/?page=1

from vertx-web.

leolux avatar leolux commented on July 17, 2024

Three additional subjects to consider:

  1. Are the paths "/foo/" and "/foo" equivalent in respect to the HTTP specification?
  2. Handling of the asterisk after the trailing slash: The current implementation (since #84) only prevents a matching of other resources before the wildcard asterisk. So "/some/path/" would match "/some/path/wibble" but not "/some/pathwibble". A matching of subresources after the asterisk is not prevented. So "/some/path/" would match "/some/path/resource" but it would also match "/some/path/resource/subresource"
  3. Handling of the asterisk before the trailing slash: Example is given in the first post by purplefox. The issue is the same as in subject 2, so limitless deep paths after the asterisk would match any subresource

from vertx-web.

pmlopes avatar pmlopes commented on July 17, 2024

@leolux

Regarding item 1: HTTP does not state that /foo and /foo/ are the same, in fact they are expected to be different, however the vast majority of web frameworks makes the assumption that they are. In Yoke this was solved like this:

https://github.com/pmlopes/yoke/blob/develop/framework/src/main/java/com/jetdrone/vertx/yoke/middleware/Router.java#L682

So if the user explicitly defines a trailing slash then the route is matched exactly to /foo/ otherwise to /foo/?$.

About 2: this is more tricky because one could do a find and replace of * with any char except / however what if the user really wants anything? then we break the semantic meaning of *.

An alternative for this would be not rely on regex matches but use something like and matches e.g.:

  • /foo/* - one level
  • /foo/** - any level
  • /foo/*.jsp - one jsp in the foo resource
  • /foo/**.jsp - one jsp anywhere under foo resource

from vertx-web.

purplefox avatar purplefox commented on July 17, 2024

What is the behaviour of Node.js Express here?

from vertx-web.

pmlopes avatar pmlopes commented on July 17, 2024

In express 4, * catches everything, they use this middleware for that:

https://github.com/pillarjs/path-to-regexp/blob/master/index.js

See the comment on the regexp on the top of the file:

// "/" => ["/", undefined, undefined, undefined, undefined, ""]

from vertx-web.

HenryBarnett avatar HenryBarnett commented on July 17, 2024

I just came across this issue whilst converting a web application to Vertx 3.0.

Is it possible to have a compromise for those who don't want to follow the standard and redirect one type "/foo" to "/foo/" for instance? It would also stop static resource pages like http://localhost/index.html/ being served and sometimes causing issues (say a developer uses a tag like img src="./img/image.jpg" this could then resolve to index.html/img/image.jpg).

A good discussion and compromise was achieved on backbone jashkenas/backbone#848

from vertx-web.

apatrida avatar apatrida commented on July 17, 2024

Having canonical auto-redirects is very useful. For example:

http => https
/foo/ => /foo
www.mydomain.com => mydomain.com

These typically SHOULD be standardized within an app, and having help to enforce them is very useful.

from vertx-web.

pmlopes avatar pmlopes commented on July 17, 2024

those redirects are now trivial:

http -> https for example needs to have knowledge on which port the https server is listening and what is the FQN of the server to construct the url back to redirect to.

/foo/ -> /foo in REST terms and in HTTP terms are different resources, although we can make a trade off by ignoring the trailing slash in special cases as already described before.

domain redirects are also tricky in the sense that if you are running your app behind a load balancer/proxy (e.g.: ngnix) you need to assume that the origin domain is in some header since you cannot rely on the request itself, and what about the protocol you might make a ssl connection to ngnix but ngnix connect to your app with plain http, etc...

from vertx-web.

apatrida avatar apatrida commented on July 17, 2024

see issue #157 for more of what would be covered for some of these redirects

from vertx-web.

beders avatar beders commented on July 17, 2024

express has a separate 'strict' mode that considers /foo and /foo/ to be two different things.

I would welcome a strict mode that doesn't try to do anything surprising when defining routing matches.
i.e. /foo/* should not match /foo.
Instead it should be trivial to return 301 for cases where you /foo -> /foo/ which would then be matched by /foo/*

from vertx-web.

pmlopes avatar pmlopes commented on July 17, 2024

the current implementation behaves just like the strict mode of express.

from vertx-web.

HenryBarnett avatar HenryBarnett commented on July 17, 2024

Since which release is that in?

Unless there was a change since my last comment I have experienced that it doesn't work in that way, or I have done some incorrect configuration.

from vertx-web.

pmlopes avatar pmlopes commented on July 17, 2024

well i've just noticed a bad behavior but if you write a test like:

  @Test
  public void testRouteTrailingSlash() throws Exception {
    router.route("/foo/:id/bar/").handler(rc -> {
      rc.response().setStatusMessage("slash").end();
    });
    router.route("/foo/:id/bar").handler(rc -> {
      rc.response().setStatusMessage("noslash").end();
    });
    testRequest(HttpMethod.GET, "/foo/1/bar", 200, "noslash");
    testRequest(HttpMethod.GET, "/foo/1/bar/", 200, "slash");
  }

it passes

it fails if you don't use path params

from vertx-web.

pmlopes avatar pmlopes commented on July 17, 2024

This change would create a bahavior change of the current API and break existing apps, i think we cannot do this? for examples all current apps that use * will be affected and this is quite a breaking change... WDYT?

from vertx-web.

leolux avatar leolux commented on July 17, 2024

I haven't understood the bad behaviour completely . Does it mean that the router for "/foo/1/bar/" handles both requests instead of only one?

Another questions bothers me: Why should an app handle the paths "/foo/1/bar" and "/foo/1/bar/" differently?

from vertx-web.

HenryBarnett avatar HenryBarnett commented on July 17, 2024

Basically yes, the routing for one of the two handles both requests with and without the trailing slash.

The reason why they should handle them differently is because they are different. The resource "/foo" is generally referring to a file, and the resource "/foo/" is generally a member of a hierarchy.

The two strings are also different and so it should be possible for them to point to different resources giving a greater level of flexibility.

from vertx-web.

gcarwardine avatar gcarwardine commented on July 17, 2024

How are people handling images and other static resources with a relative path from URLs when the trailing / is left off?

Currently I have:
http://localhost/app/loadprofiles/ which serves up http://localhost/app/loadprofiles/index.html.

However http://localhost/app/loadprofiles serves up the same index.html file, but all the relative references when the trailing slash is not there do not work. E.g. when using: http://localhost/app/loadprofiles it serves http://localhost/app/loadprofiles/index.html, but the browser looks for static resources at the wrong level, e.g http://localhost/app/scripts/loadprofiles.js. I need them to be found in http://localhost/app/loadprofiles/scripts/loadprofiles.js. All the relative references work fine when the trailing slash is included in the URL.

What I currently have to do is have a static handler for a wildcard route at http://localhost/app/loadprofiles/\* but then have another route with a regex match http://localhost/app/loadprofiles$ which replies with a 301 redirect to http://localhost/app/loadprofiles/.

from vertx-web.

pmlopes avatar pmlopes commented on July 17, 2024

Changing how we do the mapping would be a major break and would require all users to review their code and probably adapt. The benefit is probably not worth the risk. I'm closing it as re-open if needed in the future.

from vertx-web.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.