Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Allow for HTTP/1.0 requests #2259

Closed
wants to merge 2 commits into from
Closed

Allow for HTTP/1.0 requests #2259

wants to merge 2 commits into from

Conversation

alexwhitman
Copy link

Our work proxy requires a HTTP/1.0 CONNECT to tunnel HTTPS over HTTP. This patch adds the ability to specify which HTTP version should be used with http.request(). Defaults to '1.1' for backwards compatibility.

Adds a `version` option to `http.request()`. Defaults to '1.1' for
backwards compatibility.
@bnoordhuis
Copy link
Member

@ry I know this is a touchy subject for you. Can you review the patch?

@alexwhitman
Copy link
Author

Looking at this again this might not be needed and can instead be done with net:

var net = require('net');

var proxyPort = 8080;
var proxyHost = 'proxy.domain.com';
var requestHost = 'www.google.co.uk';
var requestPort = 443;

var proxy = net.connect(proxyPort, proxyHost, function() {
    proxy.write('CONNECT ' + requestHost + ':' + requestPort + ' HTTP/1.0\r\n');
    proxy.write('Connection: keep-alive\r\n');
    proxy.write('\r\n');
});

proxy.on('data', function(data) {
    var responseCode = data.toString().split('\r\n')[0].split(' ', 2)[1];
    if (responseCode == 200) {
        // connected to the proxy, but how to stream https requests?
    }
});

What I'm not sure about now is how to stream https.request() via this tunnel. Is this currently possible?

@bnoordhuis
Copy link
Member

What I'm not sure about now is how to stream https.request() via this tunnel. Is this currently possible?

With a bit of work. Pass a custom https.Agent to https.request() that knows how to tunnel traffic. Your agent will have to establish the secure channel itself but you can hand off most of the heavy lifting to the tls module.

@alexwhitman
Copy link
Author

Hmm, that's going over my head.

@ry
Copy link

ry commented Dec 6, 2011

Why do you need this? What does your proxy do with HTTP/1.1 clients?

Our client is HTTP/1.1 and should not ever need to pretend to be HTTP/1.0. You must justify why what this is needed.

@alexwhitman
Copy link
Author

The HTTP/1.0 request is needed to use the CONNECT verb create a tunnel to send HTTPS requests via a HTTP proxy. That said this probably wouldn't be the best place for it given what @bnoordhuis has said and this pull request can be closed.

@alexwhitman alexwhitman closed this Dec 6, 2011
@ry
Copy link

ry commented Dec 6, 2011

Why do you need 1.0 for CONNECT

@alexwhitman
Copy link
Author

Doing some further tests it's not the 1.0 that's the problem, it's the Transfer-Encoding: chunked header that causes the 501. Taking that out makes it work. Updating https://github.com/joyent/node/blob/master/lib/http.js#L1027 to

if (method === 'GET' || method === 'HEAD' || method === 'CONNECT') {

should fix it.

@ry
Copy link

ry commented Dec 6, 2011

@alexwhitman
Copy link
Author

I patched a local clone (cloned from v0.6) and it worked against the proxy but when writing a test for it it seems that a server created by http.createServer() doesn't like the CONNECT verb. (This is also present in an un-patched v0.6 branch build).

The following works and prints 200:

var http = require('http');
var server = http.createServer(function(req, res) {
    req.on('end', function() {
        res.end();
        server.close();
    });
}).listen(12345, "localhost");
server.on('listening', function() {
    var options = {
        host: 'localhost',
        port: 12345,
        path: '/foo',
        method: 'GET'
    };
    var req = http.request(options, function(res) {
        console.log(res.statusCode);
    });
    req.on('error', function(e) {
        console.log(e);
    })
    req.end();
});

If I change method to CONNECT then I get:

{ [Error: socket hang up] code: 'ECONNRESET' }

I know with CONNECT that path should be a host/port and not a path so I removed the / at the beginning and I get the same error. Is this a bug in the server or something I'm doing wrong?

@bnoordhuis
Copy link
Member

path should be example.com:80. Note that http.Server doesn't really support or understand CONNECT, your request handler won't get called.

@pselden
Copy link

pselden commented Jan 6, 2012

Whitman, how did you get it to work with your proxy? What kind of proxy are you using? I ran into the same issue today and am struggling to get it to work (apache and mod_proxy) even with Transfer-Encoding: chunked disabled.

Where I stumble is how you would be able to write back out to it after you do the connect.

@alexwhitman
Copy link
Author

I couldn't get it to work in the end. I could CONNECT to the proxy but then, like you, couldn't figure out what to do with it next. As bnoordhuis said in a previous comment it could probably be done with a custom http.Agent but I wasn't really sure what I was doing with it so I abandoned it.

koichik added a commit that referenced this pull request Jan 9, 2012
This is necessary to use SSL over HTTP tunnels.

Refs #2259, #2474.
Fixes #2489.
koichik added a commit that referenced this pull request Jan 9, 2012
Introduces 'connect' event on both client (http.ClientRequest) and
server (http.Server).

Refs: #2259, #2474.
Fixes #1576.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants