Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

weird redirect issue when using apache proxy #9

Closed
danschumann opened this issue Jul 7, 2014 · 19 comments
Closed

weird redirect issue when using apache proxy #9

danschumann opened this issue Jul 7, 2014 · 19 comments
Labels

Comments

@danschumann
Copy link

So, I had no idea why my app was breaking, but apparently it was being redirected for no apparent reason.

apache redirects /mypath to my node app

when it wasn't behind apache it was fine, but then suddenly it was being picked up by the serve-static middleware. and only sometimes. i'm using serve static for /vendor and /public. Several sub applications nested under the main node app each have a public and a vendor dir. Only the sub apps that have a vendor are having this issue ( very weird since the hooks are identical ).

normally(not behind apache) going to /subapp will load the sub app just fine, doesn't pick up the directory serve-static.

when nested under apache, going to /mypath/subapp, your application will redirect my app to /subapp/, which is not picked up by apache. This is totally unexpected, and it should be going to /mypath/subapp/. I would think this middleware would just give me files not mess with my redirects at all. So I had to set redirect: false.

I think this should be opt-in, since this middleware is supposed to be boilerplate basic serving files and not redirecting. That or make the detect for redirect better since it is being overzealous and breaking my url.

@dougwilson
Copy link
Contributor

I think this should be opt-in, since this middleware is supposed to be boilerplate basic serving files and not redirecting.

Yes, it should be opt-in, I agree. I'll make sure to swap the default value on the next major version bump.

That or make the detect for redirect better since it is being overzealous and breaking my url.

When the redirect occurs, what does Node.js see as the req.url? If Apache is removing the /mypath from the URL before giving the request to Node.js, I don't see how anything in Node.js could redirect to the proper URL.

@danschumann
Copy link
Author

node sees req.url as / since this is a sub-app. the thing is, when not nested under apache, the same is true. original url is /subapp. the same is true when not nested under apache. So strange, really.

@danschumann
Copy link
Author

as far as redirecting, i use config.baseURL to redirect properly when nested under apache. so potentially you could redirect relatively.. since yea, you couldn't know my config values.

@dougwilson
Copy link
Contributor

Yea, how about req.originalUrl? That is the true URL that node.js saw.

@dougwilson
Copy link
Contributor

as far as redirecting, i use config.baseURL to redirect properly when nested under apache. so potentially you could redirect relatively.. since yea, you couldn't know my config values.

What you could do is use a module like on-headers and dynamically alter all outgoing Location headers to fix the path based on your config.baseURL, then redirects would work magically.

@danschumann
Copy link
Author

hmmmm.. now that i went through my whole app adding the prefix.. i'll look into it. is that a proper standard or is it still a good idea for you to redirect relatively?

@dougwilson
Copy link
Contributor

is that a proper standard or is it still a good idea for you to redirect relatively?

sorry, I don't understand the question :) technically the Location header must be an absolute URL, but most browsers will allow relative URLs, if that's what you're asking.

@danschumann
Copy link
Author

hmm so on-headers fires last, right before the request goes out, and i should add /mypath base route then? if a redirect happened? Seems okay, since my current adding of config.baseURL to every redirect is wet. I might use it to clean up my code, however I don't think you should require people to use it if they use serve-static nested under apache, but you already said you agree about opt-in.

I'm kind of curious about the redirect code anyway, does it just add slash? And just for the purpose of cleaning up the url? because if so I think you could get away with removing it unless it has a bigger use.
Sounds like relative redirects aren't supported as a standard, so that wouldn't work.

If you really need the redirect part, could I suggest opt-in by letting the user input either redirect: true, or redirect: '/mypath' ? That way if someone wanted to use redirects and apache, they could with relative ease

@dougwilson
Copy link
Contributor

hmm so on-headers fires last, right before the request goes out, and i should add /mypath base route then? if a redirect happened?

Simple example (added very high in your middleware stack):

var onHeaders = require('on-headers')

app.use(function (req, res, next) {
  onHeaders(res, function () {
    var location = this.getHeader('Location')
    if (location) {
      this.setHeader('Location', config.baseURL + location)
    }
  })
  next()
})

but you already said you agree about opt-in.

Yea, I don't think should do that by default.

I'm kind of curious about the redirect code anyway, does it just add slash? And just for the purpose of cleaning up the url? because if so I think you could get away with removing it unless it has a bigger use.

https://github.com/expressjs/serve-static/blob/master/index.js#L91 it adds a / to the end if the referenced URL is a directory on the file system. This was so it would be used in conjunction with serve-index.

If you really need the redirect part, could I suggest opt-in by letting the user input either redirect: true, or redirect: '/prefix' ?

Yea, I can probably change the send module to accept a string value that would be treated as a prefix.

@danschumann
Copy link
Author

It doesn't seem to include serve-index though. So, why is it better to massage the path in this module rather than in serve-index?

This is what I was wondering when I originally saw the piece of code since I didn't think there was much directory support.

is the index: ['index.html'] pointing to an existing file or will it serve index.html as a list of directory contents? I can't seem to get that to do anything.

@dougwilson
Copy link
Contributor

is the index: ['index.html'] pointing to an existing file or will it serve index.html as a list of directory contents? I can't seem to get that to do anything.

If you put a index.html file in a directly, it'll serve that file if you just ask for the directly, just like Apache would do.

@dougwilson
Copy link
Contributor

For example, put a file index.html in __dirname, 'public' and then load /limby_static and it'll display the index.html file, but the reason the redirect occurs is because that URL must be /limby_static/ (with the trailing slash), otherwise you cannot link to things reliably on the page.

@dougwilson
Copy link
Contributor

In case it helps, you were talking about Apache, so giving you some examples may help.

The index option here is just like http://httpd.apache.org/docs/2.2/mod/mod_dir.html#directoryindex (notice it is index.html by default, just like with this module)
The redirect options here is just like http://httpd.apache.org/docs/2.2/mod/mod_dir.html#directoryslash (notice it is On by default, just like with this module)

@danschumann
Copy link
Author

I see what you mean now. Serving index.html when they hit the parent directory just like an apache www will do. I was thinking hitting the parent directory would give you a list of the files in that directory, as if you were on a read only ftp client.

I guess I didn't really expect people to use node to serve straight html like that but I guess they could.

I still don't see the need to redirect, even if you're serving indexes like this though, right?

@dougwilson
Copy link
Contributor

I still don't see the need to redirect, even if you're serving indexes like this though, right?

Say your index.html page as the following HTML:

<img src="ball.gif">

to show a bouncing ball. The ball.gif file would be located in the same folder as index.html. I'm sure you can agree this makes sense. Now, say that folder is example. If you go to http://localhost/example/, the index.html file will load and the browser will load http://localhost/example/ball.gif and you'll see a bouncing ball!

Now, if you don't redirect, when a user goes to http://localhost/example, then the browser will resolve the image to http://localhost/ball.gif and it'll be a broken image.

@danschumann
Copy link
Author

ah.. hmm. It's unlikely that anyone will find the solution would be {redirect: true} in serve-static if they had that issue and it was opt-in. They'd most likely change their links. I could see leaving it default or changing it, since not many people use html anyway. Do more people nest under apache or use flat html files?

@dougwilson
Copy link
Contributor

Do more people nest under apache or use flat html files?

hm, I'm not sure what the question really means, but this is a common problem with using index.html pages, which is very common.

@danschumann
Copy link
Author

well it might be better to leave it in as default then, since nesting under an apache route is probably more rare.

@dougwilson
Copy link
Contributor

So yea. As long as this module is doing index.html serving, I'm going to keep it with the redirect stuff.

@expressjs expressjs locked and limited conversation to collaborators Sep 5, 2014
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants