有一个普通的套接字服务器侦听端口12345;
ServerSocket s = new ServerSocket(12345);
我想知道的是有可能:
>如果客户端发送http请求,服务器直接处理请求,
>如果客户端发送https请求,服务器将客户端套接字更改为SSLSocket?
谢谢
解决方法
Is it possible to change plain socket
to SSLSocket?
是的.在服务器端,以下工作:
ServerSocketFactory ssf = ServerSocketFactory.getDefault(); ServerSocket serverSocket = ssf.createServerSocket(12345); // I've initialised an sslContext with a keystore,as you normally would. Socket socket = serverSocket.accept(); SSLSocketFactory sslSf = sslContext.getSocketFactory(); // The host name doesn't really matter,since we're turning it into a server socket // (No need to match the host name to the certificate on this side). SSLSocket sslSocket = (SSLSocket) sslSf.createSocket(socket,null,socket.getPort(),false); sslSocket.setUseClientMode(false); // Use the sslSocket InputStream/OutputStream as usual.
SSLSocketFactory.createSocket(Socket,…)将默认将现有Socket转换为客户端模式SSLSocket.由于握手仅在您开始使用I / O流读/写时开始,所以仍然需要使用setUseClientMode(false)更改模式.
关于其余的问题:
What I want to know is that it is
possible that:
- If the client send a http request,the server handle the request
directly,- If the client send a https request,the server change client
socket to SSLSocket?
再次,是的,这是可能的.有时被称为“港口统一”,是implemented in Grizzly,因此是Glassfish.
它的工作原理是因为HTTP和TLS(在其上工作)是客户端首先讨论的协议.因此,服务器可以检测客户端最初发送的是TLS ClientHello消息(在这种情况下应该尝试继续进行TLS握手)或纯HTTP请求(例如GET / HTTP / 1.1 …).
我怀疑端口统一使用SSLEngine是“更容易”的,否则可能很难在普通套接字上实现一个预读,您仍然可以通过SSLSocketFactory.createSocket(Socket,…)进行转换.
请注意,这仍然是非常不寻常的.