Requette http sur une page web

Requette http sur une page web - C++ - Programmation

Marsh Posté le 26-04-2006 à 17:41:21    

:hello:  :bounce:  salut les gens....  :hello:  
 
Je voudrais savoir s'il existe une librairie ou une methode quelconque de faire une requete http sur un serveur web ... :??:  
 
J'ai vu tout un tas de solution en .net .... mais rien en c++.    :pfff:    :(    
Faut il passer par un socket, utiliser une classe particulière.... si vous avez des solutions... je prends...
 :hello:  
 
 
Merci d avance.


---------------
triste époque ou il est plus difficile de casser un préjugé qu'un atome(A.Einstein)
Reply

Marsh Posté le 26-04-2006 à 17:41:21   

Reply

Marsh Posté le 26-04-2006 à 18:01:11    

rien de bien portable.
par contre si ce que tu veut faire est relativement simple, tu peut ouvrir une socket, envoyer une fausse entête HTTP, et récupérer le résultat.

Reply

Marsh Posté le 26-04-2006 à 18:40:04    

Portable ou non ca me va...  
 
je suis sur un serveur web (linux), je dois juste exuter mon script c++ c'est tout.  
(me demandez pas pourquoi c'est asseze compliqué...  :na: )
Reponse ou pas...c'est egale;  tant que j'arrive à envoyer une requette http avec 2 variables posts ca suffit :)  :bounce:
 
PS:
si t'avais une bonne url explicant le fonctionnement et la mise en place de socket ca serait cool  :)


Message édité par bakastef le 26-04-2006 à 18:41:01

---------------
triste époque ou il est plus difficile de casser un préjugé qu'un atome(A.Einstein)
Reply

Marsh Posté le 26-04-2006 à 19:23:42    

Pourquoi ne pas utiliser libcurl et le binding C++ ?
 
http://curl.haxx.se/libcurl/
http://rrette.com/curlpp.html
 
Y'a une tripotée d'exemples.

Reply

Marsh Posté le 26-04-2006 à 19:41:43    

J'ai pas d'url particulière à te conseiller.
Il doit y avoir ce qu'il faut pour ouvrir une socket sur le forum.
Sinon, j'ai ce morceau de code:

Code :
  1. // connects to a server
  2. FILE* server_connect(const char* _hostip, int _port)
  3. {
  4.   // initialize variables, check for default values
  5.   const char* hostip=_hostip?_hostip:"127.0.0.1";
  6.   int port=_port?_port:80;
  7.   // opens a socket
  8.   int s=socket(PF_INET,SOCK_STREAM,0);
  9.   if (s==-1)
  10.   {
  11.     perror(NULL);
  12.     return 0;
  13.   }
  14.   // assign remote IP/port
  15.   struct sockaddr_in addr;
  16.   addr.sin_family=AF_INET;
  17.   addr.sin_port=htons(port);
  18.   if (!inet_aton(hostip,&addr.sin_addr))
  19.   {
  20.     fprintf(stderr,"Bad IP adress format\n" );
  21.     close(s);
  22.     return 0;
  23.   }
  24.   // connects to remote server
  25.   else if (connect(s, (const struct sockaddr*)&addr, sizeof(struct sockaddr_in)))
  26.   {
  27.     perror(NULL);
  28.     close(s);
  29.     return 0;
  30.   }
  31.   // make a file from the socket
  32.   FILE* fd=fdopen(s,"r+" );
  33.   if (!fd)
  34.   {
  35.     perror(NULL);
  36.     close(s);
  37.     return 0;
  38.   }
  39.   // returns socket file
  40.   return fd;
  41. }


C'est pas compliqué, consulte <<man -a socket>> pour plus d'info.
Ensuite, tu peut utiliser le fichier retourné par la fonction pour écrire et lire dedans, utilise fclose() pour le fermer.
 
Sinon, pour envoyer une requête POST, tu n'a qu'à écrire:
POST /url HTTP/1.1
Connection: Close
Content-Type: application/x-www-form-urlencoded
... dans la socket, suivi de la longueur de tes variables, suivi de tes variables POST, au même format qu'une url GET, par exemple:
Content-Length: 15
arg1=10&arg2=20
... puis pour valider l'entête tu envoie deux '\n' à la suite.
enfin, comme tu n'a pas besoin de récupérer le résultat, tu ferme la connexion.

Reply

Marsh Posté le 27-04-2006 à 09:10:57    

je vais regarder tout ca.... je repasserais par la site je galere comme un tit fou :)


---------------
triste époque ou il est plus difficile de casser un préjugé qu'un atome(A.Einstein)
Reply

Marsh Posté le 27-04-2006 à 15:12:31    

Bon, j'ai pas mal avancé mais j'aiun nouveau tit probleme....
 
J'ai créé mon socket, je lui passe en paramettre une url est une variable (à poster), je créé ma connexion et  lance ma requete http. Le probleme c'est que j'arrive pas au bon endroit. :(
 
Je voudrais poster ma variable sur une page , mais malheureusement il semble que ma requete arrive à la racine du serveur.
 
Deja voila le code:
 

Code :
  1. #define LINUX_OS
  2. // #define WIN_OS
  3. #define _DEBUG_PRINT(X)   /* X */
  4. //For commn
  5. #include <iostream>
  6. #include <fstream>
  7. #include <string>
  8. #include <stdlib.h>
  9. #include <assert.h>
  10. #ifdef LINUX_OS
  11. #include <netdb.h>
  12. #endif
  13. #ifdef WIN_OS
  14. #include <Winsock2.h>
  15. #endif
  16. #define SEND_RQ(MSG) \
  17.                 /*cout<<send_str;*/ \
  18.   send(sock,MSG,strlen(MSG),0);
  19. using namespace std;
  20. //<exe> hostname api parameters
  21. int request (char* hostname, char* api, char* parameters, string& message)
  22. {
  23. #ifdef WIN_OS
  24. {
  25.  WSADATA WsaData;
  26.  WSAStartup (0x0101, &WsaData);
  27. }
  28. #endif
  29.     sockaddr_in       sin;
  30.     int sock = socket (AF_INET, SOCK_STREAM, 0);
  31.     if (sock == -1) {
  32.  return -100;
  33. }
  34.     sin.sin_family = AF_INET;
  35.     sin.sin_port = htons( (unsigned short)80);
  36.     struct hostent * host_addr = gethostbyname(hostname);
  37.     if(host_addr==NULL) {
  38.       _DEBUG_PRINT( cout<<"Unable to locate host"<<endl );
  39.       return -103;
  40.     }
  41.     sin.sin_addr.s_addr = *((int*)*host_addr->h_addr_list) ;
  42.     _DEBUG_PRINT( cout<<"Port :"<<sin.sin_port<<", Address : "<< sin.sin_addr.s_addr<<endl);
  43.     if( connect (sock,(const struct sockaddr *)&sin, sizeof(sockaddr_in) ) == -1 ) {
  44.      _DEBUG_PRINT( cout<<"connect failed"<<endl ) ;
  45.      return -101;
  46.     }
  47.     cout << "\nadr: " << sin.sin_addr.s_addr << "\n" << endl;
  48. string send_str;
  49. SEND_RQ("POST " );
  50. SEND_RQ(api);
  51. SEND_RQ(" HTTP/1.0\r\n" );
  52. SEND_RQ("Accept: */*\r\n" );
  53. SEND_RQ("User-Agent: Mozilla/4.0\r\n" );
  54. char content_header[100];
  55. sprintf(content_header,"Content-Length: %d\r\n",strlen(parameters));
  56. SEND_RQ(content_header);
  57. SEND_RQ("Accept-Language: en-us\r\n" );
  58. SEND_RQ("Accept-Encoding: gzip, deflate\r\n" );
  59. SEND_RQ("Host: " );
  60. SEND_RQ("hostname" );
  61. SEND_RQ("\r\n" );
  62. SEND_RQ("Content-Type: application/x-www-form-urlencoded\r\n" );
  63. //If you need to send a basic authorization
  64. //string Auth        = "username:password";
  65. //Figureout a way to encode test into base64 !
  66. //string AuthInfo    = base64_encode(reinterpret_cast<const unsigned char*>(Auth.c_str()),Auth.length());
  67. //string sPassReq    = "Authorization: Basic " + AuthInfo;
  68. //SEND_RQ(sPassReq.c_str());
  69. SEND_RQ("\r\n" );
  70. SEND_RQ("\r\n" );
  71. SEND_RQ(parameters);
  72. SEND_RQ("\r\n" );
  73. _DEBUG_PRINT(cout<<"####HEADER####"<<endl);
  74. char c1[1];
  75. int l,line_length;
  76. bool loop = true;
  77. bool bHeader = false;
  78. while(loop) {
  79.    l = recv(sock, c1, 1, 0);
  80.    if(l<0) loop = false;
  81.    if(c1[0]=='\n') {
  82.        if(line_length == 0) loop = false;
  83.        line_length = 0;
  84.        if(message.find("200" ) != string::npos)
  85.        bHeader = true;
  86.    }
  87.    else if(c1[0]!='\r') line_length++;
  88.    _DEBUG_PRINT( cout<<c1[0]);
  89.    message += c1[0];
  90. }
  91. message="";
  92. if(bHeader) {
  93.      _DEBUG_PRINT( cout<<"####BODY####"<<endl) ;
  94.      char p[1024];
  95.      while((l = recv(sock,p,1023,0)) > 0)  {
  96.          _DEBUG_PRINT( cout.write(p,l)) ;
  97.      p[l] = '\0';
  98.      message += p;
  99.      }
  100.      _DEBUG_PRINT( cout << message.c_str());
  101. } else {
  102.  return -102;
  103. }
  104. #ifdef WIN_OS
  105.    WSACleanup( );
  106. #endif
  107. return 0;
  108. }
  109. int main(int argc, char *argv[])
  110. {
  111. // 2 parametres doivent etre passés au prog:
  112. // - l'url de retour sur le site
  113. // - la variable data contenant le resultat de RESPONSE
  114. cout << "argc: " << argc << endl;
  115. char* url;
  116. char* param;
  117. string message;
  118. int codeRetour;
  119. if ( argc > 1 )
  120. {
  121.  for (int i=0; i<= argc; i++)
  122.  {
  123.   //cout<<"arg "<< i <<"= "<< argv[i] <<endl;
  124.   switch(i)
  125.   {
  126.    case 0 :cout << "- nom / chemin exec:" << argv[i] << endl; break;
  127.    case 1 :cout << "- param_n 1: url = " << argv[i] << endl;
  128.     url= argv[i];
  129.     break;
  130.    case 2 :cout << "- param_n 2: data= " << argv[i] << endl;
  131.     param= argv[i];
  132.     break;
  133.    default : cout << "param_supplementaire: " << endl;
  134.   }
  135.  }
  136.  codeRetour= request (url, "/post_url.pl", param, message);
  137.  // message contains response!
  138.  /* Ouverture du fichier  en mode ecriture */
  139.  ofstream fichier("res.html" );
  140.  if (!fichier) {
  141.  cerr << "Impossible d'ouvrir le fichier!" << endl;
  142.  return (-1);
  143.  }
  144.  /* Désormais on peut écrire dans le fichier comme avec cout */
  145.  fichier << message << endl;
  146.  /* Fermeture du fichier */
  147.  fichier.close();;
  148.  cout << "resultat:\ncode retour: " << codeRetour << "\nmessage:"<< message << endl;
  149. }
  150. else
  151. {
  152.  cout << "pas de parametres. " << endl;
  153.  return -1;
  154.  // erreur: pas de parametres passé au programme
  155.  // on ne peut rediriger vers le site
  156. }
  157.  
  158. }


 
et voila la reponse du serveur( exemple si j essai de me connecter à  google):
 
[url] http://bakastef.free.fr/images/res.html[/url]
 
 
don si kelkun sait comment regler mon pb... ca serait super mega trop cool de la mort ^ ^


---------------
triste époque ou il est plus difficile de casser un préjugé qu'un atome(A.Einstein)
Reply

Marsh Posté le 27-04-2006 à 15:41:48    

tu ferais mieux à mon avis de commencer à tester ton programme en envoyant des requêtes HTTP simples (genre "HEAD / HTTP/1.0" ) juste pour voir si la communicaion à travers les sockets passe bien.
 
commencer directement avec un POST me paraît un peu ambitieux :)


Message édité par franceso le 27-04-2006 à 15:44:35

---------------
TriScale innov
Reply

Marsh Posté le 27-04-2006 à 15:49:55    

ha mais je suis ambitieux et ca marche ^^ .... j'ai tester sur d autre serveur que google et il me reponde bien que j'ai executer un post ds les regles...(protocole/HTTP1.0, methode POST ect)
 
J ai peut etre pas ete tres clair avant... le probleme se pose pas lors de la connexion ni de format de la requete, le prb c'est le :" gethostbyname"
 
ma requete est envoyé au serveur et c'est pas ca que je veux.... Ce que je veux c'est accedez à une page php et lui passer une variable en post. Hors, lorsque j'envoie ma requete sur un site hebergé par ovh, infomaniak ou free... je tombe sur le serveur web et pas sur le site  :(


---------------
triste époque ou il est plus difficile de casser un préjugé qu'un atome(A.Einstein)
Reply

Marsh Posté le 27-04-2006 à 16:10:09    

je suis pas spécialiste et je dis ça un peu au pif, mais c'est peut-être parce que les serveurs à qui tu t'adresses ont des configurations basées sur des hôtes virtuels. Du coup, le gethostbyname te renvoie la même IP pour tous les sites persos free. Quand tu contactes cette adresse IP sans préciser quel nom d'hôte tu vises, tu te retrouves sur le serveur de base.
 
Peut-être que si tu envoies des requêtes http contenant le nom d'hôte, ça marcherait mieux.

Code :
  1. request ("login.free.fr", "http://login.free.fr/post_url.pl", param, message);


---------------
TriScale innov
Reply

Marsh Posté le 27-04-2006 à 16:10:09   

Reply

Marsh Posté le 27-04-2006 à 21:46:08    

ben la encore je bloque... je pense que ce qui vient etre dis est tout a fait sensé, mais j'ai effectué quekques tests a la recherche des pages du site, et le serveur me retourne un code erreur 103 ou 404 ---> page non trouvée   :sweat:


---------------
triste époque ou il est plus difficile de casser un préjugé qu'un atome(A.Einstein)
Reply

Marsh Posté le 28-04-2006 à 08:38:39    

attends, comment tu as fait le truc?
pour les serveur virtuels, tu ajoute dans l'entête:
Host: bidule.free.fr
 
PS: le format de la méthode POST commence par:
POST /path/fichier.ext?args HTTP/1.1
tout autre format renverra 404 ou pire 501


Message édité par nargy le 28-04-2006 à 08:40:03
Reply

Marsh Posté le 28-04-2006 à 09:13:27    

Je viens de relire ton code, et je remarque que tu n'a pas de fonction pour url-encoder les paramètres post. Il peut être utile d'en avoir une. Le plus simple est de transformer tous les caractères pour lesquels (isalnum(c)) est faux en leur équivalent hexa à 2 chiffres avec % devant: %20 pour ``espace``, pour le nom des variables POST et leur valeur.
 
Quelques remarques suplpémentaires:

  • certains sites necessitent une identification, cherche du côté de WWW-Authentificate sur le web pour avoir les bonnes entêtes,
  • certaines applications web supportent mal quand tu coupe la communication avant qu'elles n'aient renvoyé leur page, je vois que tu en tiens compte, cependant fais gaffe à ce que si l'application retourne un contenu binaire il peut y avoir des caractères nuls.
  • si tu lis proprement la première ligne d'entête renvoyé par le serveur, tu as le code d'erreur, et un message, par exemple:

HTTP 200 OK
HTTP 404 "Not Found"

Reply

Marsh Posté le 28-04-2006 à 15:59:27    

Bon ya beaucoup de mieux, mais c'est tjs pas fini...  :sweat:
 
Aye je suis connecté a mon serveur, je post sur ma page de destination, mais je post peu  :(
 
J'arrive pas a poster plus d'une variable... Quel est le format de la requete http..???
 
1- Concatener:

Code :
  1. #
  2. SEND_RQ("\r\n" );
  3. SEND_RQ("\r\n );
  4. SEND_RQ("param1=12 param2=32 ..." );
  5. SEND_RQ("\r\n" );


 
2-Multiplier :

Code :
  1. #
  2. SEND_RQ("\r\n" );
  3. SEND_RQ("\r\n );
  4. SEND_RQ("param1=12" );
  5. SEND_RQ("\r\n" );
  6. SEND_RQ("\r\n" );
  7. SEND_RQ("\r\n );
  8. SEND_RQ("param2=22" );
  9. SEND_RQ("\r\n" );
  10. SEND_RQ("\r\n" );
  11. SEND_RQ("\r\n );
  12. SEND_RQ("param3=33" );
  13. SEND_RQ("\r\n" );


 
3- A la suite:

Code :
  1. #
  2. SEND_RQ("\r\n" );
  3. SEND_RQ("\r\n );
  4. SEND_RQ("param1=12 " );
  5. SEND_RQ("param2=22 " );
  6. SEND_RQ("param3=33 " );
  7. SEND_RQ("\r\n" );


 
 
je sais comment structurer ca , helppppp!!!!!!!!!


---------------
triste époque ou il est plus difficile de casser un préjugé qu'un atome(A.Einstein)
Reply

Marsh Posté le 28-04-2006 à 22:23:21    

c'est comme une requête GET:
param1=un%20texte&param2=10&parma3=un%20autre%20texte
content-length= taille de la ligne ci dessus en caractères

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed