IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Développement Discussion :

Lecture d'un cookie sur une URL distante


Sujet :

Développement

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 89
    Par défaut Lecture d'un cookie sur une URL distante
    Bonjour,

    J'essaie désespérément de requêter le site "termobile.fr", hors ce site est extrêmement mal fait : lorsqu'on souhaite rechercher une gare, plutôt que de simplement envoyer le formulaire il va placer les infos du formulaire en session (donc cookie de session obligatoire) et rediriger vers la page des résultats.
    Et sur chaque page, si le cookie de session n'est pas là, on est redirigé à l'accueil.

    Ma première étape est donc de récupérer le cookie de session. Après, j'ose espérer que ça suivra son cours.

    Voici un code qui fonctionne en PHP :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    curl_setopt($s, CURLOPT_HTTPHEADER, array(
      'Keep-Alive: 300',
      'Connection: keep-alive',
      'Cache-Control: max-age=0',
    ));
    curl_setopt($s, CURLOPT_TIMEOUT, 10);
    curl_setopt($s, CURLOPT_MAXREDIRS, 4);
    curl_setopt($s, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($s, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; U; Linux i686; fr; rv:1.9.1.8) Gecko/20100214 Ubuntu/9.10 (karmic) Firefox/3.5.8 GTB6');
    curl_setopt($s, CURLOPT_HEADER, true);
    curl_setopt($s, CURLOPT_NO_BODY, true);
    curl_setopt($s, CURLOPT_URL, 'http://www.termobile.fr/pages/imode/accueil.jsp');
    $header_string = curl_exec($s);
    $header = http_parse_headers($header_string);
    $cookie = $header['Set-Cookie'];

    J'essaie de faire la même chose en Java (le langage est contraint sur mon projet), mais là c'est l'échec.
    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    URL url = new URL("http://www.termobile.fr/pages/imode/accueil.jsp");
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setRequestProperty("Keep-Alive", "300");
    connection.setRequestProperty("Connection", "keep-alive");
    connection.setRequestProperty("Cache-Control", "max-age=0");
    connection.setReadTimeout(10000);
    // ??? curl_setopt($s, CURLOPT_MAXREDIRS, 4);
    // ??? curl_setopt($s, CURLOPT_RETURNTRANSFER, true);
    connection.setRequestProperty("User-Agent", "Mozilla/5.0 (X11; U; Linux i686; fr; rv:1.9.1.8) Gecko/20100214 Ubuntu/9.10 (karmic) Firefox/3.5.8 GTB6");
    // ??? curl_setopt($s, CURLOPT_HEADER, true);
    // ??? curl_setopt($s, CURLOPT_NO_BODY, true);
    connection.setRequestMethod("GET");
    connection.connect();
     
    Map<String, List<String>> headers = connection.getHeaderFields();
    sessionCookie = connection.getHeaderField("Set-Cookie");

    Comme vous le voyez, il y a certaines instructions cUrl que je n'ai pas su traduire en Java.

    Pour info, voici les headers complets que je reçois avec la connection Java :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    {
      keep-alive=[timeout=15, max=100], 
      content-type=[text/html;charset=ISO-8859-1], 
      content-length=[1044], 
      date=[Mon, 08 Mar 2010 23:59:51 GMT], 
      server=[Apache-Coyote/1.1], 
      connection=[Keep-Alive]
    }
    Je pensais que ce que je souhaitais faire était simple, mais j'ai beau essayer avec HttpClient (du package org.apache.http.client) ou en extrayant le contenu de la page (j'ai lu que mon problème pouvait aussi venir de la connexion keep-alive), j'ai systématiquement la même réponse.
    Je n'ai hélas pas assez de connaissances dans le protocole HTTP pour comprendre exactement ce qui se passe.

  2. #2
    Membre émérite Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Par défaut
    Bonjour,

    As tu parcouru ce document http://julp.developpez.com/php/curl/ qui explique notamment la signification des options Curl?

    A partir de là, tu pourras surement faire des recherches afin de trouver comment définir l'entête HTTP.


  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 89
    Par défaut
    Merci de ta réponse
    Je vais éplucher ça, mais entre temps j'en ai justement lu un peu plus sur ces options et les 3 dont je n'étais pas sûr n'ont a priori pas de rapport avec mon problème (ce sont uniquement des options qui définissent la façon dont curl va me renvoyer ces résultats) et d'ailleurs en testant sans, j'ai le même résultat.

    La seule différence entre les deux serait donc le traitement des redirections... Le problème étant que dans la version Java je ne reçois certes pas de header "Set-Cookie", mais pas non plus de "Location", j'en perds mon latin ^^

    Je pense changer mon fusil d'épaule et tenter une connexion "brute" en ouvrant un socket et en écrivant mes headers dedans pour voir le "vrai" retour. Je ne sais pas comment se comporte l'objet HTTPUrlConnection vis-à-vis des Location, donc je veux en avoir le cœur net par ce biais.

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 89
    Par défaut
    Pour info, j'ai fait un retour aux fondamentaux en utilisant Socket directement. Le code d'interrogation lui-même est assez simple : on ouvre un socket, on lui parle en HTTP (voir RFC pour la syntaxe, et voir firebug pour connaître les headers envoyés par le navigateur histoire d'envoyer les mêmes), et on lit la réponse. À l'ancienne, et là ça marche

    Voici la petite API que je me suis écrite du coup :
    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
     
    class TERMobileBrowser {
     
    	public static final class Response {
     
    		private Map<String, List<String>> headers = new HashMap<String, List<String>>();
    		private String body = null;
    		private Integer statusCode = null;
    		private String statusDescription = null;
     
    		private static final Pattern PATTERN_STATUS = Pattern.compile("^[A-Z/0-9\\.]+ ([0-9]+) (.*)$");
     
    		public Response(BufferedReader r) throws IOException {
    			this(r, true);
    		}
     
    		public Response(BufferedReader r, boolean readBody) throws IOException {
    			boolean inBody = false;
    			boolean parsedStatus = false;
    			String line;
    			while ((line = r.readLine()) != null) {
    				if (!inBody) {
    					line = line.trim();
    					if (!parsedStatus) {
    						Matcher m = PATTERN_STATUS.matcher(line);
    						parsedStatus = true;
    						if (m.find()) {
    							statusCode = Integer.parseInt(m.group(1));
    							statusDescription = m.group(2);
    							continue;
    						} else {
    							statusCode = 0;
    							statusDescription = null;
    						}
    					}
    					if (line.equals("")) {
    						if (!readBody) {
    							break;
    						} else {
    							inBody = true;
    						}
    					} else {
    						addHeader(line);
    					}
    				} else {
    					body += line;
    				}
    			}
    			r.close();
    		}
     
    		public void addHeader(String line) {
    			int sepPos = line.indexOf(':');
    			String headerName = line.substring(0, sepPos).trim().toLowerCase();
    			String headerValue = line.substring(sepPos+1).trim();
    			if (!headers.containsKey(headerName)) {
    				headers.put(headerName, new ArrayList<String>());
    			}
    			headers.get(headerName).add(headerValue);
    		}
     
    		public String getBody() {
    			return body;
    		}
     
    		public List<String> getHeaderList(String name) {
    			if (headers.containsKey(name)) {
    				return headers.get(name);
    			}
    			return null;
    		}
     
    		public String getHeader(String name, int index) {
    			if (headers.containsKey(name)) {
    				List<String> values = headers.get(name);
    				if (0 <= index && index < values.size()) {
    					return values.get(index);
    				}
    			}
    			return null;
    		}
     
    		public String getHeader(String name) {
    			return getHeader(name, 0);
    		}
     
    		public String[] getHeaderNames() {
    			return headers.keySet().toArray(new String[0]);
    		}
     
    		public Integer getStatusCode() {
    			return statusCode;
    		}
     
    		public String getStatusDescription() {
    			return statusDescription;
    		}
     
    	}
     
    	private Map<String, String> getDefaultHeaders() {
    		Map<String, String> headers = new HashMap<String, String>();
    		headers.put("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.0; fr; rv:1.9.2) Gecko/20100115 Firefox/3.6 (.NET CLR 3.5.30729)");
    		headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
    		headers.put("Accept-Language", "fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3");
    		headers.put("Accept-Encoding", "gzip,deflate");
    		headers.put("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
    		headers.put("Keep-Alive", "115");
    		headers.put("Connection", "keep-alive");
     
    		return headers;
    	}
     
    	private Response readURL(String host, int port, String path, Map<String, String> headers) throws IOException {
    		return readURL(host, port, path, "GET", headers);
    	}
     
    	private Response readURL(String host, int port, String path, String method, Map<String, String> headers) throws IOException {
    		Socket s = new Socket(host, port);
    		OutputStreamWriter w = new OutputStreamWriter(s.getOutputStream());
    		BufferedReader r = new BufferedReader(new InputStreamReader(s.getInputStream()));
    		w.write(method + " " + path + " HTTP/1.1\n");
    		w.write("Host: " + host + "\n");
    		for (Map.Entry<String, String> header : headers.entrySet()) {
    			String name = header.getKey();
    			String value = header.getValue();
    			String headerLine = name + ": " + value + "\n";
    			w.write(headerLine);
    		}
    		w.write("\n");
    		w.flush();
    		while (!r.ready()) {
    			// FIXME add timeout
    			continue;
    		}
    		w.close();
     
    		return new Response(r, false);
    	}
     
    	private String getSessionCookie() throws IOException {
    		Map<String, String> headers = getDefaultHeaders();
    		Response response = readURL("www.termobile.fr", 80, "/pages/imode/accueil.jsp", headers);
     
    		return response.getHeader("set-cookie");
    	}
     
    }

    Pour recoller les morceaux, ça revient en gros à faire ça :
    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    Socket s = new Socket("www.termobile.fr", 80);
    OutputStreamWriter w = new OutputStreamWriter(s.getOutputStream());
    BufferedReader r = new BufferedReader(new InputStreamReader(s.getInputStream()));
     
    // Requête
    w.write("GET  / HTTP/1.1\n");
    w.write("Host: www.termobile.fr\n");
    w.write("User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; fr; rv:1.9.2) Gecko/20100115 Firefox/3.6 (.NET CLR 3.5.30729)\n");
    w.write("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\n");
    w.write(("Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3\n");
    w.write("Accept-Encoding: gzip,deflate\n");
    w.write("Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\n");
    w.write("Keep-Alive: 115\n");
    w.write("Connection: keep-alive\n");
    w.write("\n");
    w.flush();
    w.close();
     
    // Réponse
    while (!r.ready()) {
    	// FIXME add timeout
    	continue;
    }
    String line;
    while ((line = r.readLine()) != null) {
    	// Première ligne = status
    	// Lignes suivantes = entêtes au format "clé: valeur"
    	// Première ligne vide = fin des entêtes
    	// Tout le reste = corps de la réponse (html)
    	if (line.match("(?i)^set-cookie *:")) {
    		// Récupérer la valeur du cookie
    		break;
    	}
    }
    r.close();


    Je réinvente très certainement la roue, mais il y a donc bien des traitements faits par URLConnection que je ne maîtrise pas, donc là au moins je sais exactement ce qui se passe et je récupère pile ce que je veux.
    À mon avis le problème avec URLConnection est qu'il suit les "Location:" mais sans reconnaître les cookies entre les redirections. Un jour j'essaierai d'identifier ça, mais en l'occurrence mon pb est résolu

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [C#]Accéder à un répertoire partagé sur une machine distante
    Par spaceclic dans le forum Windows Forms
    Réponses: 15
    Dernier message: 14/05/2007, 15h43
  2. Tuer un processus sur une machine distante
    Par nuke_y dans le forum Autres Logiciels
    Réponses: 2
    Dernier message: 16/11/2004, 09h55
  3. Réponses: 8
    Dernier message: 13/07/2004, 09h00
  4. Alter user sur une base distante
    Par bilo2000 dans le forum Administration
    Réponses: 13
    Dernier message: 09/03/2004, 17h18
  5. [Débutant] Connexion sur une machine distante protégée
    Par arthix dans le forum Développement
    Réponses: 3
    Dernier message: 28/08/2003, 09h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo