我正在用Java编写一个简单的HTTPS代理程序用于教育目的.我的程序在一个端口(比如7443)上侦听来自浏览器(比如Firefox)的传入HTTPS请求,解析请求并将其转发到所需的目的地(比如https://www.comodo.com).
Firefox的代理设置设置为使用我的端口进行SSL连接(127.0.0.1 : 7443).
我的代码简短而简单:
static // initializer
{
System.setProperty("javax.net.ssl.keyStore", "MyKeyStore");
System.setProperty("javax.net.ssl.keyStorePassword", "password");
}
SSLServerSocketFactory ssFactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
try {
SSLServerSocket listener = (SSLServerSocket) ssFactory.createServerSocket(port, 64);
listener.setUseClientMode(false);
listener.setWantClientAuth(false);
listener.setNeedClientAuth(false);
SSLSocket connection = (SSLSocket) listener.accept();
browser.startHandshake(); /* <<== Exception throws at this line */
} catch (IOException ex) {
ex.printStackTrace(System.err);
}
Run Code Online (Sandbox Code Playgroud)
但是我抓住了以下异常:
javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
Run Code Online (Sandbox Code Playgroud)
例外情况表明连接可以是纯文本,但只有来自Firefox的HTTPS连接设置为使用此端口.我已经记录了Firefox发送到我的应用程序的内容,这是:
CONNECT www.comodo.com:443 HTTP/1.1
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:20.0) Gecko/20100101 Firefox/20.0
Proxy-Connection: …Run Code Online (Sandbox Code Playgroud) 从这篇文章开始,我尝试实现一个处理GET和POST请求的小代理服务器(只需用Handler下面的类替换):
public static class Handler extends Thread {
public static final Pattern CONNECT_PATTERN
= Pattern.compile("CONNECT (.+):(.+) HTTP/(1\\.[01])", Pattern.CASE_INSENSITIVE);
public static final Pattern GET_POST_PATTERN
= Pattern.compile("(GET|POST) (?:http)://([^/:]*)(?::([^/]*))?(/.*) HTTP/(1\\.[01])", Pattern.CASE_INSENSITIVE);
private final Socket clientSocket;
private boolean previousWasR = false;
public Handler(Socket clientSocket) {
this.clientSocket = clientSocket;
}
@Override
public void run() {
try {
String request = readLine(clientSocket, Integer.MAX_VALUE);
Matcher connectMatcher = CONNECT_PATTERN.matcher(request);
Matcher getNpostMatcher = GET_POST_PATTERN.matcher(request);
System.out.println("Request: " +request);
if (connectMatcher.matches()) {
// …Run Code Online (Sandbox Code Playgroud) 我已经有一个可以处理多个HTTP请求的工作HTTP代理服务器.现在我的问题是如何处理https请求?
这是我正在使用的简化代码:
class Daemon
{
public static void main(String[] args)
{
ServerSocket cDaemonSocket = new ServerSocket(3128);
while(true)
{
try
{
Socket ClientSocket = cDaemonSocket.accept();
(new ClientHandler(ClientSocket )).start();
}catch(Exception e) { }
}
}
}
Run Code Online (Sandbox Code Playgroud)
和ClientHandler
class ClientHandler extends Thread
{
private Socket socket = null;
private Socket remoteSocket = null;
private HTTPReqHeader request = null;
ClientHandler(Socket socket)
{
this.socket = socket;
request = new HTTPReqHeader();
request.parse(socket); // I read and parse the HTTP request here
}
public void run()
{ …Run Code Online (Sandbox Code Playgroud) 我正在使用tcp套接字使用JDK 1.3(BD-J平台).
我似乎在客户端收到一些错误.如果我已完成写入并关闭较低的套接字输出流,我似乎尝试从服务器端读取异常(大多数消息如果没有关闭则通过),但是当它关闭时我遇到了麻烦.
尝试使用服务器进行调试,即使套接字关闭,我也不应该读取客户端发送的所有内容吗?只需在服务器端使用低套接字输入流.如果我正常运行它得到大多数消息,尝试在调试器中运行服务器我得到1消息然后一个Socket异常连接重置.
这是客户端上的部分代码,它如何发送消息,然后在完成写入时关闭,等待所有输入完成然后完全关闭套接字.
http://pastie.org/private/cwc5uijl1x2ndwjwsun4lg
真的很沮丧,我找不到问题