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

To be congruent with other popular http clients the port should be stripped from the 'Host' field when the port is 80. #404

Closed
wants to merge 1 commit into from

Conversation

celer
Copy link

@celer celer commented Apr 15, 2013

Hi,

So we encountered an interesting problem today, less so a bug with node-http-proxy but more of a incongruent behavior from when compared against other browsers and client's we've tested.

When working with cloudfoundry.com we found that their proxy did not consider a request to port 80 the same if the port was explicitly specified in the 'Host' header field.

So a request to http://foo.cloudfoundry.com:80/ and http://foo.cloudfoundry.com/ behaved differently. We narrowed it down to the difference in the Host field. The changeOrign logic included the port when crafting the 'Host' header regardless of the port number.

No big deal right? Well so everyone else strips port 80 because it is the default :(

  • Curl strips port 80 from the Host header
  • wget strips port 80 from the Host header
  • Safari strips port 80 from the Host header
  • Firefox strips port 80 from the Host header
  • Chrome strips port 80 from the Host header

You can test the behavior using "http://helloworld-ng.cloudify.com:80/" and "http://helloworld-ng.cloudify.com/" - notice that both URLs work the same in all of the above listed browsers

In curl we can see the failure case

$ curl http://helloworld-ng.cloudfoundry.com:80/ -H "Host: helloworld-ng.cloudfoundry.com:80"
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
$ curl http://helloworld-ng.cloudfoundry.com:80/ -H "Host: helloworld-ng.cloudfoundry.com"
Hello from Cloud Foundry

(We've asked cloudfoundry to fix this issue, but to be clear the behavior in node-http-proxy is incongruent with every other client and browser we've tested)

So then the question becomes - should node-http-proxy do the same? Sadly it seems like this shouldn't be an issue but it is an unexpected behavior and no one else does it - hence why I think node-http-proxy should strip port 80 from the Host field if it is specified.

…some *cough-cloudfoundry.com* services to have issues
@celer
Copy link
Author

celer commented Apr 16, 2013

Please see

request/request#515

For details about how each client handles a URL with port 80 specified.

@mikeal
Copy link

mikeal commented Apr 16, 2013

this assumes 80 is default, what about https?

@celer
Copy link
Author

celer commented Apr 17, 2013

So the behavior appears to be he same with all the clients - although a bit harder to test. But they all strip 443 from the host field when using https.

So I used a simple nodejs server and the various development tools with the browsers to verify the behavior.

var fs = require('fs');
var http = require('https');
var privateKey  = fs.readFileSync('privatekey.pem').toString();
var certificate = fs.readFileSync('certificate.pem').toString();

var credentials = {key: privateKey, cert: certificate};
var express = require('express');
var server = express();

var app = express();

app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);

app.get("/",function(req,res){
  console.log(req.headers);
  console.log("Got /");
  res.send("hello");
});

var https = http.createServer(credentials, app);

https.listen(443);

@@ -237,7 +237,8 @@ HttpProxy.prototype.proxyRequest = function (req, res, buffer) {
// don't revert this without documenting it!
//
if (this.changeOrigin) {
outgoing.headers.host = this.target.host + ':' + this.target.port;
var port = (this.target.port-80==0?"":":"+this.target.port);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use this.target.port == 80 for type coercion

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use this.target.protocol to determine if it should be 443 or 80.

@indexzero
Copy link
Contributor

No updates from @celer. Closing.

@indexzero indexzero closed this Dec 27, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants