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

 C++ Discussion :

winsock GET API Wikipedia


Sujet :

C++

  1. #1
    Futur Membre du Club
    Homme Profil pro
    electricien
    Inscrit en
    Octobre 2014
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Haute Saône (Franche Comté)

    Informations professionnelles :
    Activité : electricien
    Secteur : Bâtiment

    Informations forums :
    Inscription : Octobre 2014
    Messages : 4
    Points : 6
    Points
    6
    Par défaut winsock GET API Wikipedia
    Bonjour!

    Voila j'essaye de récupérer les définitions de wikipedia grace a un GET avec winsock.
    Si je tape sous un navigateur "fr.wikipedia.org/w/api.php?format=xml&action=query&prop=extracts&redirects&exintro=&explaintext=&titles=automobile" je récupère bien la definition de "automobile"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <api batchcomplete="">
    <query>
    <normalized>
    <n from="automobile" to="Automobile"/>
    </normalized>
    <pages>
    <page _idx="3141765" pageid="3141765" ns="0" title="Automobile">
    <extract xml:space="preserve">
    Une automobile ou, plus précisément, une voiture automobile, (l'abréviation populaire en « voiture » est assez courante même si ce terme imprécis peut désigner de nombreux types de véhicules qui ne sont pas tous motorisés) est un véhicule automobile à roues propulsé par un moteur et destiné au transport terrestre de personnes, de leurs bagages et de petits objets. L'automobile est un moyen de transport parmi les plus répandus, sa capacité est généralement de deux à cinq personnes, mais peut varier de une à neuf places. L'usage limite l'emploi du terme automobile aux véhicules possédant quatre roues, de dimensions inférieures à celle des autobus et des camions, mais englobe parfois les camionnettes. Bien qu'étant des « véhicules automobiles », les motocyclettes ne sont pas habituellement classées dans cette catégorie.
    </extract>
    </page>
    </pages>
    </query>
    </api>
    mais avec mon GET le serveur me renvois HTTP/1.1 301 TLS Redirect.

    Comment faire la redirection avec ma requette GET Winsock?

    Merci

    mon code C
    Code : 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
     
            int result;
    	WSADATA WsaDat;
    	SOCKET theSocket;
    	ADDRINFO hints;
    	ADDRINFO* pResult;
    	sockaddr_in servAddr{ 0 };
    	char recvBuf[4096];
    	string request;
    	string Host = "fr.wikipedia.org";
    	string Buffer;
     
     
    	request = "GET /w/api.php?format=xml&action=query&prop=extracts&redirects&exintro=&explaintext=&titles=automobile HTTP/1.1\r\n";
    	request += "Host: fr.wikipedia.org\r\n";
    	request += "Connection: clode\r\n\r\n";
     
    	WSAStartup(MAKEWORD(2, 2), &WsaDat);
     
    	memset(&hints, 0, sizeof(hints));
    	hints.ai_flags = AI_ALL;
    	hints.ai_family = PF_INET;
    	hints.ai_protocol = IPPROTO_IPV4;
     
    	getaddrinfo(Host.c_str(), nullptr, &hints, &pResult);
     
    	servAddr.sin_family = AF_INET;
    	servAddr.sin_addr.S_un.S_addr = *((ULONG*)&(((sockaddr_in*)pResult->ai_addr)->sin_addr));
    	servAddr.sin_port = htons(80);
     
     
    	theSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
     
    	connect(theSocket, (struct sockaddr*)&servAddr, sizeof(servAddr));
    	send(theSocket, request.c_str(), request.length(), 0);
     
    	while (true)
    	{
    		result = recv(theSocket, recvBuf, 4096, 0);
     
    		if (result == 0)
    		{
    			cout << "Récuperation Wiki" << "\n";
     
    			break;
    		}
    		else
    		{
    			Buffer.append(recvBuf, result);
    		}
    	}

  2. #2
    Membre expert Avatar de jopopmk
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    1 856
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 1 856
    Points : 3 570
    Points
    3 570
    Par défaut
    Salut,

    deux possibilités :
    - gérer les redirects de manière générale : il faut alors lire les autres entêtes, trouver celle qui s'appelle Location et refaire une requête vers l'URL indiquée (10 redirect max d'après la RFC 2616 de souvenir),
    - gérer les redirects pour wiki en particulier : si tu regardes l'URL de Location tu verras qu'il s'agit simplement de rediriger vers la même URL mais via HTTPS. En fin de compte pas besoin
    de manip', juste de pointer au bon endroit directement.

    Dans les deux cas tu te retrouveras avec une nouvelle question : comment requêter un serveur via HTTPS ?
    Plus je connais de langages, plus j'aime le C.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    electricien
    Inscrit en
    Octobre 2014
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Haute Saône (Franche Comté)

    Informations professionnelles :
    Activité : electricien
    Secteur : Bâtiment

    Informations forums :
    Inscription : Octobre 2014
    Messages : 4
    Points : 6
    Points
    6
    Par défaut
    Oui c'est tout a fait ça,mais je n'ai pas trouvé beaucoup d'info sur les requettes https avec winsock ou j'ai mal cherché, si tu as un tuto ou autre je suis preneur.
    Merci bcp

  4. #4
    Membre expert Avatar de jopopmk
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    1 856
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 1 856
    Points : 3 570
    Points
    3 570
    Par défaut
    Yep, pas simple de trouver des info sur le sujet (j'ai aussi galéré à trouver de la matière) et nop, j'ai pas de tuto sous la main.

    Si j'ai un peu de temps je regarderai ça de plus près
    Plus je connais de langages, plus j'aime le C.

  5. #5
    Futur Membre du Club
    Homme Profil pro
    electricien
    Inscrit en
    Octobre 2014
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Haute Saône (Franche Comté)

    Informations professionnelles :
    Activité : electricien
    Secteur : Bâtiment

    Informations forums :
    Inscription : Octobre 2014
    Messages : 4
    Points : 6
    Points
    6
    Par défaut
    OK merci je vais jeter un oeil sur OpenSSL.

  6. #6
    Membre expert Avatar de jopopmk
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    1 856
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 1 856
    Points : 3 570
    Points
    3 570
    Par défaut
    Re,

    J'ai testé un bout de code que entre midi et deux. Codé pour Zindozs, il utilise OpenSSL pour gérer le TLS :
    (y'a certainement plein de choses à redire sur ce code mais il est fonctionnel et pourra te servir de base de recherche)
    Code : 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
     
    #define WIKI_REQ	"GET /w/api.php?format=xml&action=query&prop=extracts&redirects&exintro=&explaintext=&titles=automobile HTTP/1.1\r\n" \
    			"Host: fr.wikipedia.org\r\n" \
    			"Connection: close\r\n\r\n"
    #define WIKI_IP "91.198.174.192"
    #define BUF_LEN 512
     
    int main(int argc, char *argv[], char *envp[]) {
    	static WSADATA wsaData;
    	SSL_CTX *context = NULL;
    	SSL* ssl = NULL;
    	SOCKET sockette;
    	struct sockaddr_in addr;
    	int ret;
    	char buffer[BUF_LEN] = "";
     
    	printf("OPENSSL_VERSION:\n");
     
    	if (WSAStartup(MAKEWORD(2, 2), &wsaData)) {
    		MSG("ERROR WSAStartup !");
    		return 10;
    	}
     
    	SSL_load_error_strings();
    	SSL_library_init();
    	OpenSSL_add_all_algorithms();
     
    	if ((context = SSL_CTX_new(SSLv23_client_method())) == NULL) {
    		MSG("ERROR SSL_CTX_new");
    		goto close_all;
    	}
    	SSL_CTX_set_mode(context, SSL_MODE_AUTO_RETRY);
     
    	if ((sockette = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
    		MSG("ERROR socket");
    		goto close_all;
    	}
    	memset(&addr, 0, sizeof(addr));
    	addr.sin_family = AF_INET;
    	addr.sin_port = htons(443);
    	addr.sin_addr.s_addr = inet_addr(WIKI_IP);
     
    	if ((ssl = SSL_new(context)) == NULL) {
    		MSG("ERROR SSL_new");
    		goto close_all;
    	}
     
    	if ((connect(sockette, (struct sockaddr*)&addr, sizeof(addr))) == SOCKET_ERROR) {
    		MSG("ERROR connect");
    		goto close_all;
    	}
     
    	if (!SSL_set_fd(ssl, sockette)) {
    		MSG("ERROR SSL_set_fd");
    		goto close_all;
    	}
    	SSL_set_connect_state(ssl);
    	if ((ret = SSL_connect(ssl)) != 1) {
    		MSG("ERROR SSL_connect");
    		goto close_all;
    	}
    	ret = SSL_write(ssl, WIKI_REQ, strlen(WIKI_REQ));
     
    	printf("-------------- RESPONSE START ---------------\n");
    	while ((ret = SSL_read(ssl, buffer, BUF_LEN -1)) > 0) {
    		buffer[ret] = 0;
    		printf("%s", buffer);
    	}
    	printf("\n-------------- RESPONSE STOP ---------------\n");
     
    close_all:
    	if (ssl) {
    		SSL_shutdown(ssl);
    		SSL_free(ssl);
    	}
    	if (context) SSL_CTX_free(context);
    	closesocket(sockette);
    	WSACleanup();
    	return 0;
    }
    Bon dev.
    Plus je connais de langages, plus j'aime le C.

  7. #7
    Futur Membre du Club
    Homme Profil pro
    electricien
    Inscrit en
    Octobre 2014
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Haute Saône (Franche Comté)

    Informations professionnelles :
    Activité : electricien
    Secteur : Bâtiment

    Informations forums :
    Inscription : Octobre 2014
    Messages : 4
    Points : 6
    Points
    6
    Par défaut
    Merci beaucoup ton code ma bien aidé et j'ai pu résoudre mon problème voilà le premier jet de la fonction qui récupère la définition d'un mot sur Wikipedia

    Code : 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
    void WikiPedia(string mot)
    {
     
    	static		WSADATA		wsaData;
    	SSL_CTX		*Context= NULL;
    	SSL		*SSL	=NULL;
    	SOCKET		Socket;
    	sockaddr_in addr{ 0 };
    	ADDRINFO	hints;
    	ADDRINFO	*pResult;
    	int		ret;
    	char		CBuffer[BUF_LEN] = "";
    	std::string	 SBufferUTF8;
     
            //forme requette fr.wikipedia.org/w/api.php?format=xml&action=query&prop=extracts&redirects&exintro=&explaintext=&titles=voiture
     
            std::string	 Request = "GET /w/api.php?format=xml&action=query&prop=extracts&redirects&exintro=&explaintext=&titles="+ mot + " HTTP/1.1\r\n" \
    				"Host: fr.wikipedia.org\r\n" \
    			        "Connection: close\r\n\r\n";
    	std::string	 HOST = "fr.wikipedia.org";
     
     
    	//Init Open SSL et Winsock
     
    	WSAStartup(MAKEWORD(2, 2), &wsaData);
     
            SSL_load_error_strings();
    	SSL_library_init();
    	OpenSSL_add_all_algorithms();
    	Context = SSL_CTX_new(SSLv23_client_method());
    	SSL_CTX_set_mode(Context, SSL_MODE_AUTO_RETRY);
    	SSL = SSL_new(Context);
     
    	Socket = socket(AF_INET, SOCK_STREAM, 0);
     
    	memset(&hints, 0, sizeof(hints));
    	hints.ai_flags = AI_ALL;
    	hints.ai_family = PF_INET;
    	hints.ai_protocol = IPPROTO_IPV4;
     
    	getaddrinfo(HOST.c_str(), nullptr, &hints, &pResult);
     
    	addr.sin_family = AF_INET;
    	addr.sin_addr.S_un.S_addr = *((ULONG*)&(((sockaddr_in*)pResult->ai_addr)->sin_addr));
    	addr.sin_port = htons(443);
     
    	connect(Socket, (struct sockaddr*)&addr, sizeof(addr));
     
    	SSL_set_fd(SSL, Socket);
    	SSL_set_connect_state(SSL);
    	ret = SSL_connect(SSL);
     
    	ret = SSL_write(SSL, Request.c_str(), Request.size());
     
            // Récuperation des données
    	while ((ret = SSL_read(SSL, CBuffer, BUF_LEN - 1)) > 0)
     
    	{
     
    		SBufferUTF8.append(CBuffer, ret);
     
    	}
     
    	//Conversion UTF8 en windows-1252
    	int size_needed = MultiByteToWideChar(CP_UTF8, 0, &SBufferUTF8[0], SBufferUTF8.size(), NULL, 0);
     
    	std::wstring SBuffer1252(size_needed, 0);
    	MultiByteToWideChar(CP_UTF8, 0, &SBufferUTF8[0], SBufferUTF8.size(), &SBuffer1252[0], size_needed);
     
     
    	//Garder que la définition
    	std::string::size_type Position = SBuffer1252.find(L"preserve");
    	std::string::size_type Position2 = SBuffer1252.find(L"</api>");
    	std::wstring Definition = SBuffer1252.substr(Position+10, Position2-Position-43);
     
            //affiche la définition
    	wcout << Definition;
     
     
            //Nettoyage,Close SSL et Winsock
    	SSL_shutdown(SSL);
    	SSL_free(SSL);
    	SSL_CTX_free(Context);
            closesocket(Socket);
            WSACleanup();
     
    }

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

Discussions similaires

  1. [Python 2.X] Problème d'extraction des contenus Wikipédia en utilisant l'api Wikipedia
    Par daniel1985 dans le forum Général Python
    Réponses: 0
    Dernier message: 04/09/2015, 11h09
  2. Importer des recherches avec l'API wikipedia vers mediawiki
    Par wofty dans le forum Web sémantique
    Réponses: 1
    Dernier message: 20/05/2013, 10h17
  3. Réponses: 3
    Dernier message: 05/12/2008, 11h59
  4. API winsock WSAIsBlocking
    Par chuko dans le forum Réseau
    Réponses: 3
    Dernier message: 21/09/2008, 14h32
  5. API réseau multi plates-formes style Wininet/Winsock
    Par jmmolina dans le forum Développement
    Réponses: 6
    Dernier message: 22/10/2003, 14h31

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