2010-09-18 2 views
2

J'utilise HttpClient 4.02 pour créer une connexion via proxy (en utilisant la méthode CONNECT) pour acheminer une connexion à un serveur distant. HttpClient est très pratique pour cela, mais je suis nouveau à l'API et ne peux pas voir comment obtenir au Socket sous-jacent de la connexion tunnelée.HttpClient: comment obtenir le socket sous-jacent à partir d'une connexion existante?

Le code suivant extrait de: http://svn.apache.org/repos/asf/httpcomponents/httpclient/tags/4.0.1/httpclient/src/examples/org/apache/http/examples/client/ClientExecuteProxy.java

// make sure to use a proxy that supports CONNECT 
    HttpHost target = new HttpHost("target.server.net", 443, "https"); 
    HttpHost proxy = new HttpHost("some.proxy.net", 8080, "http"); 

    // general setup 
    SchemeRegistry supportedSchemes = new SchemeRegistry(); 

    // Register the "http" and "https" protocol schemes, they are 
    // required by the default operator to look up socket factories. 
    supportedSchemes.register(new Scheme("http", 
      PlainSocketFactory.getSocketFactory(), 80)); 
    supportedSchemes.register(new Scheme("https", 
      SSLSocketFactory.getSocketFactory(), 443)); 

    // prepare parameters 
    HttpParams params = new BasicHttpParams(); 
    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 

    ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, 
      supportedSchemes); 

    DefaultHttpClient httpclient = new DefaultHttpClient(ccm, params); 

    httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy); 

    HttpGet req = new HttpGet("/"); 

    System.out.println("executing request to " + target + " via " + proxy); 
    HttpResponse rsp = httpclient.execute(target, req); 
    HttpEntity entity = rsp.getEntity(); 

Ceci définit la connexion bien, mais est-il un moyen d'obtenir au Socket sous-jacente afin pour moi d'utiliser un protocole personnalisé pour parler au serveur à target.server.net?

+0

HTTP est un protocole en lui-même, est-il une raison que vous ne pouvez pas utiliser à la place emboîtements lisses? – dekz

+0

@dekz C'est pour que mon application soit utilisable par les personnes derrière les pare-feu, où la seule issue serait un proxy web. En se connectant au proxy, il transmettra les données au serveur cible en tant que HTTPS, donnant une connexion sécurisée au serveur cible. – willjcroz

+0

Quel est le protocole personnalisé que vous essayez d'utiliser? –

Répondre

2

Ouvrez une demande de modification dans la JIRA du projet. Cette fonctionnalité a simplement été négligée. Alors qu'il devrait être assez trivial d'assembler un équivalent de ProxyClient à partir de 3.x, il est logique d'en expédier un avec la version stock de HttpClient.

Edit:

Disponible depuis la version 4.2. Voir http://hc.apache.org/httpcomponents-client-4.3.x/httpclient/apidocs/org/apache/http/impl/client/ProxyClient.html

+0

OK, je le ferai quand j'aurai le temps. Merci pour votre excellent travail sur HttpClient btw. – willjcroz

+1

Je n'ai pas trouvé de changement sur ce sujet dans jira. Cette fonctionnalité est-elle déjà implémentée? – Zappi

+0

Presque 4 ans plus tard, je suis confronté au même problème. Y a-t-il déjà une solution? – mdzh

2

Pas sûr que je comprends parfaitement vos besoins, mais je vais le faire de mon mieux ...

Essayez ceci: http://svn.apache.org/viewvc/httpcomponents/oac.hc3x/trunk/src/examples/ProxyTunnelDemo.java?view=markup

+0

Merci pour cela, je vais essayer de traduire en API HttpClient 4.x (ils ont complètement changé l'API entre 3.x et 4.x) et il semble plus difficile de faire ce genre de chose. – willjcroz

+0

confirmé (grâce à vous me menant à la classe ProxyClient) ici: http://mail-archives.apache.org/mod_mbox/hc-httpclient-users/201004.mbox/%[email protected]%3E – willjcroz

0

Dans un commentaire, @willjcroz dit:

C'est ainsi que mon application est utilisable pour les personnes derrière les pare-feu où la seule issue serait un proxy web. En se connectant au proxy, il transmettra les données au serveur cible en tant que HTTPS, donnant une connexion sécurisée au serveur cible.

Si vous allez tunnel avec succès votre protocole par proxy Web, pare-feu au courant du protocole et ainsi de suite, les côtés client et serveur de votre application doivent être conformes aux spécifications du protocole HTTP. Si vous (d'une façon ou d'une autre) avez réussi à forer au niveau de la socket, il y a de fortes chances que vous violiez le protocole ...

Au lieu de cela, vous devez implémenter votre protocole personnalisé en mettant vos données dans le contenu des requêtes HTTP et réponses, en utilisant des en-têtes HTTP personnalisés dans les messages/réponses, les types de contenu personnalisés, etc.

+1

Je pense que @willjcroz veut une connexion qui reste ouverte, et HttpClient ne vous le donne pas vraiment.C'est pourquoi (je pense) il veut mettre la main sur le socket. –

+0

Si HttpClient ferme la connexion, c'est parce que le protocole HTTP indique qu'il doit être fermé. Obtenir la prise sous-jacente ne vous aidera probablement pas. Un proxy ne va pas (ou du moins ne devrait pas) relayer des données supplémentaires en violation de la spécification HTTP. –

+1

Je pense que vous devez lire ce que fait la méthode CONNECT. Ce que fait le PO est absolument légitime. Il est vrai que certains firewalls peuvent le bloquer, et de nombreux proxies n'implémenteront simplement pas CONNECT, mais si les utilisateurs ont accès à des proxies qui leur font confiance et qui supportent CONNECT, cela devrait fonctionner correctement. –

Questions connexes