Como posso usar meias com HtmlUnit?
Pergunta
É possível usar HtmlUnit através de proxy SOCKS? Alguém poderia fornecer uma amostra de código?
====
Então eu cavado já através de fontes WebClient, aqui está a melhor maneira que eu posso pensar em:
-
subclasse
MultiThreadedHttpConnectionManager
modo que permite definir informações meias e se estiver definido, antes de retornar uma ligação, conjuntos SOCKS parâmetros -
subclasse
WebConnection
- reescritacreateHttpClient
para que ele use um gerente do passo 1 e adicione um método para obter esse gerente direta ou http cliente em primeiro lugar (é protegido agora - tão ruim. ..) -
Para usar 1) criar uma instância
WebClient
2) CriarWebConnection
subclasse 3) Set-lo para ser usado pelo gerenteWebClient
4) da conexão de acesso e utilizar métodos que seja para uso meias
Solução
HtmlUnit usa HttpClient como a biblioteca de conexões subjacente, investiguei isso um pouco, mas:
1- Couldn't find a way to configure HttpClient (except by the generic Java Socks mechanism defined in http://java.sun.com/javase/6/docs/technotes/guides/net/proxies.html)
2- Do not have access to a public Socks Proxy to test against
Outras dicas
Tudo que você precisa fazer é definir o apropriada propriedades do sistema antes de criar seu objeto WebClient
. Por exemplo:
System.setProperty("socksProxyHost", "localhost"); // replace "localhost" with your proxy server
System.setProperty("socksProxyPort", "9999"); // replace "9999" with your proxy port number
WebClient client = new WebClient();
Neste ponto, HttpClient (que é usado por HtmlUnit debaixo das cobertas) vai pegar as configurações e usar o proxy SOCKS para todas as comunicações de rede.
UPDATE: eu li sua pergunta revista (e seu comentário) e eu acho que você está no caminho certo. O problema é que se você implementar o passo 1 utilizando as propriedades do sistema acima, então seu código não é thread-safe (porque essas propriedades do sistema são globais). Uma solução é para sincronizar em algo, mas é claro que isso pode introduzir problemas de desempenho (pode não importa para você).
Se você realmente quiser controlar isso em uma base per-socket, então eu acho que você vai precisar fazer algo como o seguinte:
- Criar um
ProtocolSocketFactory
personalizado que passa um objetojava.net.Proxy
para o construtorSocket
(como em este exemplo ). - Criar um
Protocol
personalizado que usa esteProtocolSocketFactory
. - Aplicar esta
Protocol
às novas conexões em seu gerenciador de conexões personalizado usandoHttpConnection.setProtocol()
.
Eu realmente não tenho testado isso, mas com base em uma rápida olhada na HttpClient 3,1 código fonte, acho que é assim que seria feito. Gostaria muito de ouvir como você finalmente resolver este problema :-). Boa sorte!