I did quite a lot search and pratical trials before asking this question.
Long story:
I found a (non-English)tutorial about how to write a http proxy with Node.js.
So far what I've known and tried:
- A HTTP proxy can handle both HTTP request and HTTPS request, but in different ways. It handles HTTP request by reading the client's request and make a new request to the target and return the response to the client. As for HTTPS request, it's dealt with a HTTP Tunnel.
- The
SSL proxy
field in Firefox proxy settings and theSecure
field in IE proxy settings (Windows) are all about setting the HTTP Tunnel. If aSSL proxy
orSecure proxy
is set, when a brower wants to connect to a https site, it sends aCONNECT
request instead of an ordinary request.
Problems:
The CONNECT
request is plain text, so firewalls can see what host I want to connect to and cut the connection. So I was thinking whether I can use https to talk to the proxy server from the very beginning. I read all related posts, but couldn't find an answer directly talking about this. And some answers also say "There's no such thing as a https proxy server".
But the tutorial says this can be done (HTTPS between client and proxy server and nothing else changes). So I give it try. I changed the server into https with my website's certificate. But eventually it only works with Proxy SwitchOmega in Chrome. It doesn't work in traditional settings like in Firefox proxy or IE proxy settings.
Proxy SwitchOmega setting:
Scheme|Protocol|Server|Port
.... | https | .... |...
I have to select https
protocol here, if I starts the https server. similarly, I have to select http
protocol, if I starts the http server. Also I don't know what this protocol
field stands for.
To sum it up:
proxy server | Firefox proxy setting |work? | SwitchOmega setting |work?|
http | http + ssl setting | yes | protocol http |yes |
https | http + ssl setting | no | protocol https |yes |
https | - | - | protocal http |no |
So my questions are:
- Can I connect to the https proxy server through the ordinary way(without an extension)? If possible, how?
- Why can I connect to the https proxy server through SwitchOmega?
- I think I build a https proxy server. But why others are saying that "There's no such thing as a https proxy server?
Source code
https server
var http = require('http');
var https = require('https');
var fs = require('fs');
var net = require('net');
var url = require('url');
console.log("qqqqq2");
function request(cReq, cRes) {
console.log("request=====start");
console.log(cReq.headers);
console.log(cReq.url);
console.log(cReq.method);
console.log("request=====end");
var u = url.parse(cReq.url);
var options = {
hostname : u.hostname,
port : u.port || 80,
path : u.path,
method : cReq.method,
headers : cReq.headers
};
var pReq = http.request(options, function(pRes) {
cRes.writeHead(pRes.statusCode, pRes.headers);
pRes.pipe(cRes);
}).on('error', function(e) {
cRes.end();
});
cReq.pipe(pReq);
// console.log(cReq.headers);
// console.log(cReq.method);
// console.log(cReq.url);
// console.log("^_^^_^^_^^_^^_^^_^");
// cRes.writeHead('200');
// cRes.end('hello world2222\n');
}
function connect(cReq, cSock) {
console.log("connect=====start");
console.log(cReq.headers);
console.log(cReq.url);
console.log(cReq.method);
console.log("connect=====end");
var u = url.parse('http://' + cReq.url);
var pSock = net.connect(u.port, u.hostname, function() {
cSock.write('HTTP/1.1 200 Connection Established\r\n\r\n');
pSock.pipe(cSock);
}).on('error', function(e) {
cSock.end();
});
cSock.pipe(pSock);
}
var options = {
key: fs.readFileSync('./privkey1.pem'),
cert: fs.readFileSync('./fullchain1.pem')
};
https.createServer(options)
.on('request', request)
.on('connect', connect)
.listen(9999, '0.0.0.0');
http server
var http = require('http');
var net = require('net');
var url = require('url');
console.log('qqqqq2');
function request(cReq, cRes) {
console.log("request=====start");
console.log(cReq.headers);
console.log(cReq.url);
console.log(cReq.method);
console.log("request=====end");
var u = url.parse(cReq.url);
var options = {
hostname : u.hostname,
port : u.port || 80,
path : u.path,
method : cReq.method,
headers : cReq.headers
};
var pReq = http.request(options, function(pRes) {
cRes.writeHead(pRes.statusCode, pRes.headers);
pRes.pipe(cRes);
}).on('error', function(e) {
cRes.end();
});
cReq.pipe(pReq);
}
function connect(cReq, cSock) {
console.log("connect=====start");
console.log(cReq.headers);
console.log(cReq.url);
console.log(cReq.method);
console.log("connect=====end");
var u = url.parse('http://' + cReq.url);
var pSock = net.connect(u.port, u.hostname, function() {
cSock.write('HTTP/1.1 200 Connection Established\r\n\r\n');
pSock.pipe(cSock);
}).on('error', function(e) {
cSock.end();
});
cSock.pipe(pSock);
}
http.createServer()
.on('request', request)
.on('connect', connect)
.listen(9999, '0.0.0.0');
Test Server
You can easily build a http proxy server and test it. But it may be cumbersome to build a https proxy server, because you need to deploy certificates. So a https proxy test server is provided, based on the code above.
Test server is deleted since I've found the answer.
pac
file that do the tricks. The SwitchOmega interface seems to merely act as a front end GUI to thepac
file setting. I am going to read something about thepac
file. – SpradlingManual proxy configuration
andAutomatic proxy configuration URL
in browsers may be 2 different kinds of settings. I used to think that one is the subset of the other. – Spradlingnetwork.proxy.proxy_over_tls
? Also did you see this page? "Squid can accept regular proxy traffic using https_port in the same way Squid does it using an http_port directive. Unfortunately, popular modern browsers do not permit configuration of TLS/SSL encrypted proxy connections. There are open bug reports against most of those browsers now, waiting for support to appear. If you have any interest, please assist browser teams with getting that to happen. " – Aguedapac
file not GUI (neither Chrome nor Firefox). I will make an answer to my question later. – Spradling