Servidor https

Olá pessoal, eu fiz um servidor http e agora preciso modificar ele para funcionar com sockets seguros (SSL) alguém já fez um servidor utilizando estes sockets ou sabe como fazer a comunicação utilizando eles? Estou perdido pois eu fiz e quando vou executar ele da o seguinte erro: “Could not generate DH keypair” alguém sabe o que isto quer dizer? Logo abaixo está o código do meu servidor http se alguém souber modificar ele para https por favor me de uma ajuda.

Esse é o meu servidor http

import java.io.*;
import java.net.*;
import java.util.*;
import java.util.regex.*;

public class ServidorHTTP
{
	public static void main(String[] args)
	{
		// numero da porta para fazer a conexao
		int porta = Integer.parseInt(args[0]);
		
		// nome do diretório que irá conter o site
        File diretorioDoSite = new File("www");
        
        // testa se diretório localhost não existe
        if (!diretorioDoSite.exists() && !diretorioDoSite.isDirectory())
        {
            System.out.println("Não existe um diretório ["
            + diretorioDoSite.getAbsolutePath() + " ]\nCrie um diretório www e ponha uma página da internet");
        }
        // se existe executa o servidor
        else
        {	
            System.out.println("Servidor executando");
            
            try
            {
            	ServerSocket socketServidor = new ServerSocket(porta);
            	
            	try
            	{
					// loop infinito para processar pedidos
	        		while (true)
	                {
	        			// aguarda uma conexão na porta especificada e retorna o socket que irá comunicar com o cliente
	        			Socket socket = socketServidor.accept();
	        			
	        			System.out.println("Processando solicitacao de " + socket.getInetAddress().getHostAddress());
	        			
	        			// cria uma nova thread para cada requisição
	        			new Thread(new Pedido(socket, diretorioDoSite)).start();
	                }
            	}
	        	catch(IOException e)
                {
	        		System.out.println(e);
                }
                finally
                {
                    socketServidor.close();
                }
			}
            catch (IOException e)
            {
				System.out.println(e);
			}
        }
	}
}

final class Pedido implements Runnable
{
	/* Um atributo static indica que o atributo é da classe, não do objeto, logo, todos os objetos da
	 * classe compartilham o mesmo valor deste atributo.
	 */
	private static final Pattern formatoDoGet = Pattern.compile("^GET (/.*) HTTP/1.1");
	private static final Pattern formatoDoHead = Pattern.compile("^HEAD (/.*) HTTP/1.1");
	
	/* Um atributo final indica que o valor do atributo não pode ser alterado (constante) */
	private final Socket socket;
	private final File diretorioDoSite;
	
	public Pedido(Socket socket, File diretorioDoSite)
    {
    	this.socket = socket;
    	this.diretorioDoSite = diretorioDoSite;
    }
	
	/* método que pega o caminho do pedido feito pelo browser */
    private String leCaminhoDoPedido() throws IOException
    {
        BufferedReader leitor = null;
    	String primeiraLinha = null;
		
		leitor = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
		primeiraLinha = leitor.readLine();
        
        if (primeiraLinha == null)
        {
        	return null;
        }
	    
	    Matcher combinacaoGet = formatoDoGet.matcher(primeiraLinha);
	    Matcher combinacaoHead = formatoDoHead.matcher(primeiraLinha);
	    
	    if(combinacaoHead.matches())
	    {
	    	/* adiciona um H no final da string para dizer que é um HEAD o que vai ser retornado */
	    	return combinacaoHead.group(1).concat("H");
	    }
	    else
	    {
		    if(combinacaoGet.matches())
		    {
		    	/* adiciona um G no final da string para dizer que é um GET o que vai ser retornado */
		    	return combinacaoGet.group(1).concat("G");
		    }
		    else
		    {
		    	return null;
		    }
	    }
    }
    
    private void mandaMensagemDeErro(int status, String mensagem) throws IOException
    {
    	OutputStream saida = enviaCabecalho(status, mensagem, mensagem.length());
		saida.write((mensagem+"\nerror number: " + status + "\n").getBytes());
	    saida.flush();
    }
    
    private OutputStream enviaCabecalho(int status, String mensagem, long tamanho) throws IOException
    {
    	Date dataDeHoje = new Date();
	    StringBuffer cabecalho = new StringBuffer();
	    OutputStream saida = this.socket.getOutputStream();
	    
	    cabecalho.append("HTTP/1.1 ");
	    cabecalho.append(status).append(' ').append(mensagem).append("\r\n");
	    cabecalho.append("Date: ");
	    cabecalho.append(dataDeHoje.toString()).append(("\r\n"));
	    cabecalho.append("Content-Length: ").append(tamanho).append("\r\n\r\n");
	    
	    // escreve os dados do cabeçalho para o socket
	    saida.write(cabecalho.toString().getBytes());
	    // força a escrita dos dados imediatamente
	    saida.flush();
	    return saida;
    }
    
    /* le o arquivo, byte a byte, do diretório e envia seu conteúdo pelo socket para que o navegador possa ter acesso pela porta */
    private void enviaArquivo(File arquivo) throws IOException
    {
    	long tamanhoDoArquivo = arquivo.length();
    	OutputStream saida = enviaCabecalho(200, "OK", tamanhoDoArquivo);
    	InputStream entrada = new FileInputStream(arquivo);
    	
    	try
    	{
    		byte[] buffer = new byte[1024];
    		int ultimoByte = 0;
    		while ((ultimoByte = entrada.read(buffer)) > 0)
            {
    			saida.write(buffer, 0, ultimoByte);
            }
        }
    	finally
        {
            entrada.close();
        }
    	saida.flush();
    }
    
	@Override
	public void run()
	{
		String retorno = null;
		String caminhoDoArquivo = null;
		
		try
		{
			retorno = leCaminhoDoPedido();
			
			/* testa se o pedido é um GET */
			if (retorno.substring(retorno.length()-1).equals("G"))
			{
				caminhoDoArquivo = retorno.substring(0, retorno.length()-1);
				
				if(caminhoDoArquivo == null)
				{
					mandaMensagemDeErro(400, "Bad Request");
				}
				else
				{
					if(caminhoDoArquivo.equals("/"))
					{
						caminhoDoArquivo = caminhoDoArquivo+"index.html";
			            
			            File arquivo = new File(this.diretorioDoSite, caminhoDoArquivo);
			            
			            if (!arquivo.exists())
			        	{
							mandaMensagemDeErro(404, "Not Found");
			        	}
			            else
			            {
							enviaArquivo(arquivo);
			            }
					}
					// tenta achar o arquivo pedido se foi em um diretorio diferente do /
			        else
			        {
			            File arquivo = new File(this.diretorioDoSite, caminhoDoArquivo);
			            
			           /* testa se o arquivo pedido está no diretório do site 
			            * ou se o arquivo existe e se não é um diretório e pode ser lido
			            * se o arquivo pedido não está no diretório do site
			            * ou se o arquivo não existe ou é um diretório ou não pode ser lido pelo browser
			            * então manda uma mensagem de erro
			            * caso contrário apenas testa se o arquivo existe
			            * se não existe diz que não foi achado senão manda o arquivo pedido
			            */
			            if (!arquivo.getAbsolutePath().startsWith(this.diretorioDoSite.getAbsolutePath()) || (arquivo.exists() && (!arquivo.isFile() || !arquivo.canRead())))
			            {
							mandaMensagemDeErro(403, "Forbidden");
			            }
			            else
			            {
			            	if (!arquivo.exists())
			            	{
								mandaMensagemDeErro(404, "Not Found");
			            	}
			            	else
			                {
								enviaArquivo(arquivo);
			                }
			        	}
			        }
				}
			}
			else
			{
				/* testa se o pedido é um HEAD */
				if (retorno.substring(retorno.length()-1).equals("H"))
				{
					caminhoDoArquivo = retorno.substring(0, retorno.length()-1);
					
					if(caminhoDoArquivo == null)
					{
						mandaMensagemDeErro(400, "Bad Request");
					}
					else
					{
						if(caminhoDoArquivo.equals("/"))
						{
							caminhoDoArquivo = caminhoDoArquivo+"index.html";
				            //System.out.println("O arquivo pedido está em: "+this.diretorioDoSite.getAbsolutePath()+caminhoDoArquivo);
				            
				            File arquivo = new File(this.diretorioDoSite, caminhoDoArquivo);
				            
				            if (!arquivo.exists())
				        	{
								mandaMensagemDeErro(404, "Not Found");
				        	}
				            else
				            {
				            	enviaCabecalho(200, "OK", arquivo.length());
				            }
						}
						// tenta achar o arquivo pedido se foi em um diretorio diferente do /
				        else
				        {
				            File arquivo = new File(this.diretorioDoSite, caminhoDoArquivo);
				            
				           /* testa se o arquivo pedido está no diretório do site 
				            * ou se o arquivo existe e se não é um diretório e pode ser lido
				            * se o arquivo pedido não está no diretório do site
				            * ou se o arquivo não existe ou é um diretório ou não pode ser lido pelo browser
				            * então manda uma mensagem de erro
				            * caso contrário apenas testa se o arquivo existe
				            * se não existe diz que não foi achado senão manda o arquivo pedido
				            */
				            if (!arquivo.getAbsolutePath().startsWith(this.diretorioDoSite.getAbsolutePath()) || (arquivo.exists() && (!arquivo.isFile() || !arquivo.canRead())))
				            {
								mandaMensagemDeErro(403, "Forbidden");
				            }
				            else
				            {
				            	if (!arquivo.exists())
				            	{
									mandaMensagemDeErro(404, "Not Found");
				            	}
				            	else
				                {
				            		enviaCabecalho(200, "OK", arquivo.length());
				                }
				        	}
				        }
					}
				}
			}
		}
		catch (IOException e)
		{
			System.out.println(e);
		}
		finally
        {
            try
            {
            	this.socket.close();
            }
            catch (IOException e)
            {
                System.out.println(e);
            }
        }
	}
}

Já não tem uma API que já faz isso ?

Existem classes tipo SSLSocket, SSLServerSocket e outras mais. Eu já gerei um certificado usando o keytool mas não consigo fazer funcionar da o erro: “Could not generate DH keypair” eu gostaria de saber o que é isso e como posso resolver.

O padrão java.net.URL classe não suporta o protocolo HTTPS.

Até a VM que você esta causando concorrentemente exception

Então como eu devo fazer para modificar meu servidor e fazer funcionar com SSL?

Use HTTPS in your Java client code Ai tem um artificio que faz suporta JVM 1.4 usando JSSE

Pedi para o meu colega testar o servidor https no mac dele e funcionou muito bem. Eu peguei o mesmo código com o mesmo certificado executei no meu computador com ubuntu 10.10 e continua dando o mesmo erro: “Could not generate DH keypair”. Alguém sabe o qual o problema com o ubuntu? É muito estranho isso, no mac funciona muito bem, mas no ubuntu da esse erro.

veja esse post


Use maquina virtual Java 6