[Socket] Envoi d'image par requête http post

Résolu
sleepersh Messages postés 16 Date d'inscription samedi 21 février 2009 Statut Membre Dernière intervention 21 mars 2013 - 28 déc. 2011 à 14:01
sleepersh Messages postés 16 Date d'inscription samedi 21 février 2009 Statut Membre Dernière intervention 21 mars 2013 - 21 mars 2013 à 17:39
Alors voilà, je viens poster ici car vous êtes sûrement ma dernière chance. Ca fait des jours que je cherche une solution à mon problème mais rien, personne n'a l'air de vraiment s'y connaître ou du moins, personne ne veut se donner la peine de répondre.

Voici mon problème (j'ai recopié-collé du site du zéro car c'est un peu long):

Bonjour,
Alors voilà depuis plusieurs jours déjà, je recherche à faire un uploader d'image qui utiliserait Qt et donnerait le lien de l'image uploadé après un drag and drop sur celui-ci (glissement de l'image sur le logiciel). Ce logiciel est destiné à être publique.

Mais nous n'en sommes pas là encore. Je n'en suis qu'au début et j'ai déjà des problèmes d'envoi d'image simple.
Mon image que j'essaie d'envoyer est celle-ci: (104 octets d'après windows).

Pour envoyer mon image, j'utilise une requête http de type POST sur un formulaire déjà créé au préalable.

Cela évite donc de passer par le ftp (peut être risqué).

Oui mais voilà, quand je fais ça je n'ai pas 104 octets (ou plus) qui arrivent sur le serveur mais seulement 8 comme en témoigne cette image:

Il y a sûrement un problème d'envoi ou de lecture du fichier quelque part. Voici mon code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "windows.h"

int main()
{
    char *buffer;
    char requete[1500];
    int lSize = 0;
    size_t result = 0;
    WSADATA WSAData;
    int erreur = WSAStartup(MAKEWORD(2,2), &WSAData);

    SOCKET sock;
    SOCKADDR_IN sin;
    FILE* image = fopen("C:\\Users\\Dardanboy\\Pictures\\w.png", "rb");
    if (image == NULL){printf("Erreur !\n"); system("PAUSE"); return 0;}

    fseek (image , 0 , SEEK_END);
    lSize = ftell (image);
    rewind (image);

    // allocate memory to contain the whole file:
    buffer = (char*) malloc (sizeof(char)*lSize);
    if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);}

    // copy the file into the buffer:
    result = fread (buffer,1,lSize,image);
    if (result != lSize)
    {
        printf("lSize (taille image) %d, result %d, buffer = %02x\n", lSize, result, buffer);
        fputs ("Reading error",stderr); exit (3);
    }

    printf("lSize (taille image) %d, result %d, buffer = %x\n", lSize, result, buffer);

    sprintf(requete, "POST /upload/cible_envoi.php HTTP/1.1\r\n"
                     "Accept: text/html, application/xhtml+xml, */*\r\n"
                     "Referer: http://dardanboy.franceserv.com/upload/upload.php\r\n"
                     "Accept-Language: fr-CH\r\n"
                     "User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)\r\n"
                     "Content-Type: multipart/form-data; boundary=---------------------------7db2c7420378\r\n"
                     "Accept-Encoding: gzip, deflate\r\n"
                     "Host: dardanboy.franceserv.com\r\n"
                     "Content-Length: 292\r\n"
                     "Connection: Keep-Alive\r\n"
                     "Cache-Control: no-cache\r\n\r\n"
                     "-----------------------------7db2c7420378\r\n"
                     "Content-Disposition: form-data; name="monfichier"; filename="w.png"\r\n"
                     "Content-Type: image/x-png\r\n\r\n"
                     "%s\r\n"
                     "-----------------------------7db2c7420378--\r\n\r\n"
                     "\r\n", buffer);
               
    sock = socket(AF_INET, SOCK_STREAM, 0);
    /* Configuration de la connexion */
    sin.sin_addr.s_addr = inet_addr("178.33.214.192"); // ip de l'hébergeur
    sin.sin_family = AF_INET;
    sin.sin_port = htons(80);

    if(!erreur)
    {
        /* connexion grâce à connect */
            if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR)
            {
                printf("Connexion à %s sur le port %d\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port));
                printf("strlen(requete) %d sizeof(requete) %d\n", strlen(requete), sizeof(requete));
                printf("\n\nrequete = %s\n\n", requete);
                send(sock, requete, strlen(requete), 0);

                    /* On ferme la connexion */
                    fclose (image);
                    free (buffer);
                    closesocket(sock);
                    WSACleanup();
                    return 1;
            }

             else{
                fclose (image);
                free (buffer);
                closesocket(sock);
                WSACleanup();
                printf("ERREUR: Impossible de se connecter à %s sur le port %d !", inet_ntoa(sin.sin_addr), htons(sin.sin_port));
                system("PAUSE");
                return 0;
            }

    }
    else{
        printf("ERREUR !\n");
        system("PAUSE");
        return 0;
    }

        return 0;
}


Voici le résultat de la console:


Merci d'avance,
Dardanboy.

13 réponses

Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
29 déc. 2011 à 07:22
en pseudo code, ca donne :

pos = sprintf(requete, [...HEADER...]);
memcpy(requete + pos, [...IMAGE...], imageSize);
pos += sprintf(requete + pos + imageSize, [...FOOTER...]);

send(requete, pos + imageSize);

en veillant bien au départ a allouer une zone mémoire suffisamment grande...

Un autre solution, plus simple serait d'envoyer l'image en base 64, si ton serveur le gère.

Renfield - Admin CodeS-SourceS - MVP Visual Basic & Spécialiste des RegExp
1
sleepersh Messages postés 16 Date d'inscription samedi 21 février 2009 Statut Membre Dernière intervention 21 mars 2013 2
19 mars 2012 à 16:44
J'ai trouvé la réponse depuis un bout de temps mais je la poste ici car il est possible que quelqu'un la recherche.

Pour ça j'ai fait une page sur mon site mais voici comment procéder:

Vous créez une page sur votre ftp qui se nomme par exemple envoiFichier.php
Dans cette page, vous insérez le code basique trouvé sur le siteduzero suivant:
<?php
// Testons si le fichier a bien été envoyé et s'il n'y a pas d'erreur
if (isset($_FILES['monfichier']) AND $_FILES['monfichier']['error'] == 0)
{
        // Testons si le fichier n'est pas trop gros
        if ($_FILES['monfichier']['size'] <= 8000000)
        {
                // Testons si l'extension est autorisée
                $infosfichier = pathinfo($_FILES['monfichier']['name']);
                $extension_upload = $infosfichier['extension'];
                $extensions_autorisees = array('jpg', 'jpeg', 'gif', 'png');
                if (in_array($extension_upload, $extensions_autorisees))
                {
                        // On peut valider le fichier et le stocker définitivement
                        move_uploaded_file($_FILES['monfichier']['tmp_name'], '/uploads' . basename($_FILES['monfichier']['name']));
                        echo "L'envoi a bien été effectué !";
                }
        }
}
else
{
    echo 'erreur';
}
?>


Comme on remarque ici, le fichier uploadé ira dans le dossier /uploads (qui doit être mis en CHMOD 733 pour pouvoir écrire dedans).

Pour ce qui en est du code, il va simplement faire une requête http et envoyer l'image comme si on avait envoyé via un formulaire:

/* Uploader d'images par requête http by Dardanboy
Merci à l'équipe CPPFrance de m'avoir guidé et aidé à finaliser ma requête */
 
#include <stdio.h>
#include <stdlib.h>
#include "windows.h"
 
#define REPERTOIRE_FICHIER_FTP "/tests/envoiFichier.php" // Repertoire de votre site où se trouve l'envoi de fichier
#define CHEMIN_IMAGE "imageTest.png" // Chemin d'accès vers l'images avec deux slash à chaque fois
#define NOM_SITE "www.bobba.franceserv.com" // Le nom de votre site (sans le http://)
#define IP_SERVEUR "88.190.228.182" // L'ip du serveur
#define PORT 80 // A ne surtout pas toucher, il sera toujours de 80 pour les requêtes http
 
int main()
{
    int tailleImage 0, result 0;
    char *contenuImage, requete_post[100000]; // Mauvaise manière de fixer la taille du tableau de requete_post
    char reception[1000]; // Pareille pour reception, fixer une taille alors qu'on ne sait pas combien on va recevoir de réponse du serveur n'est pas conseillé
 
    FILE* image = fopen(CHEMIN_IMAGE, "rb"); // On ouvre l'image en mode rb (read binary) ce qui veut dire lire en binaire
    if (image == NULL)
    {
        printf("Erreur ! Impossible d'ouvrir l'image\n");
        system("PAUSE");
        return 0;
    }
 
    // On calcul la taille de l'image
    fseek(image, 0 ,SEEK_END);
    tailleImage = ftell(image);
    rewind(image);
 
    // On alloue le mémoire  nécessaire dinamyquement pour mettre le contenu de l'image (en binaire) dans contenuImage.
    contenuImage = (char*) malloc (sizeof(char)*tailleImage);
    if (contenuImage == NULL)
    {
        perror("Problème lors de l'allocation dinamyque de mémoire avec contenuImage\n");
        system("PAUSE");
        return 0;
    }
 
    // On copie les informations binaires
    result = fread (contenuImage, 1, tailleImage, image);
    if (result != tailleImage)
    {
        perror("Reading error");
        system("PAUSE");
        return 0;
    }
 
    /* On construit le footer (le bas) de la requête http pour compléter la requête juste en-dessous.
    On aurait pu le faire en un morceau mais techniquement parlant, il fallait qu'on ajoute l'image (en binaire) juste avant la fin de la requête.
    Du coup on va rajouter le code ci-dessous juste après ce qu'on a écrit en binaire */
    char footer[] =
            "\r\n"
            "------WebKitFormBoundaryJoQ8t8QN1IBafcHA--\r\n";
 
    // On construit la requête http (plus d'informations sur les requêtes http: http://www.siteduzero.com/tutoriel-3-35613-les-requetes-http.html)
    int pos = sprintf(requete_post,
            "POST %s HTTP/1.1\r\n"
            "Host: %s\r\n"
            "Connection: keep-alive\r\n"
            "Content-Length: %d\r\n"
            "Cache-Control: max-age=0\r\n"
            "Origin: http://%s\r\n"
            "Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryJoQ8t8QN1IBafcHA\r\n"
            "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
            "\r\n"
            "------WebKitFormBoundaryJoQ8t8QN1IBafcHA\r\n"
            "Content-Disposition: form-data; name="monfichier"; filename="imageTest.png"\r\n"
            "Content-Type: image/png\r\n" /* image/png est un type MIME. Plus d'informations sur http://www.commentcamarche.net/contents/systemes/mime.php3.
                                             Voici la liste des types MIME des autres extensions:
                                             Image gif:                       image/gif
                                             Images jpeg (.jpg, .jpeg, .jpe): image/jpeg
                                             En pratique, on ne déclare pas un type MIME comme je l'ai fait car il est impossible d'enmvyer une image d'une autre
                                             extension (testImage.gif par exemple).
                                             Ce qu'il faudrait faire c'est de lire l'extension de l'image que nous envoyons à travers CHEMIN_IMAGE et de mettre le type MIME en conséquence.*/
            "\r\n"
            , REPERTOIRE_FICHIER_FTP, NOM_SITE, tailleImage + strlen(footer), NOM_SITE);
 
            memcpy(requete_post + pos, contenuImage, tailleImage); // On copie dans requete_post et pos le contenu de l'image (en binaire encore)
 
            pos += sprintf(requete_post + pos + tailleImage, footer); // On ajoute à la fin de la requête notre footer qui dit au serveur que notre requête est finie
 
 
 
    WSADATA WSAData;
    WSAStartup(MAKEWORD(2,0), &WSAData);
    SOCKET sock;
    SOCKADDR_IN sin;
    // On configure la connexion au serveur au port 80 (http) et l'adresse du serveur
    sock = socket(AF_INET, SOCK_STREAM, 0);
    /* Configuration de la connexion */
    sin.sin_addr.s_addr = inet_addr(IP_SERVEUR);
    sin.sin_family = AF_INET;
    sin.sin_port = htons(PORT);
 
        // On essaie de se connecter grâce à connect
        if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR)
        {
            printf("Connexion à %s sur le port %d\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port));
            // On essaie d'envoyer notre requête (requete_post) au serveur
            if(send(sock, requete_post, pos + tailleImage, 0) != SOCKET_ERROR)
            {
                // On fait une boucle tant qu'on reçoit une réponse du serveur.
                while(recv(sock, reception, sizeof(reception), 0))
                {
                    printf("reception = \n %s", reception);
                }
            }
            else
            {
                perror("Erreur avec send()");
                system("PAUSE");
                return 0;
            }
        }
        else
        {
            perror("Erreur avec connect, impossible de se connecter à %s sur le port %d !\n");
            system("PAUSE");
            return 0;
        }
 
    // On ferme tout ce qu'on a ouvert
    fclose (image);
    free (contenuImage);
    closesocket(sock);
    WSACleanup();
 
    system("PAUSE");
    return EXIT_SUCCESS;
}



Le code est dans une seule fonction (main) mais en réalité, pour une question de clarté il aurait mieux fallut séparer tout ça.

Si vous avez des conseils à me donner, n'hésitez pas à m'en faire part !
1
sleepersh Messages postés 16 Date d'inscription samedi 21 février 2009 Statut Membre Dernière intervention 21 mars 2013 2
21 mars 2013 à 17:39
J'en ai profité pour améliorer le code depuis mais l'ai quand même laissé dans un seul fichier:

Fichier envoieFichier.php présent à la racine du serveur:
<?php
// Testons si le fichier a bien été envoyé et s'il n'y a pas d'erreur
if (isset($_FILES['monfichier']) AND $_FILES['monfichier']['error'] == 0)
{
        // Testons si le fichier n'est pas trop gros
        if ($_FILES['monfichier']['size'] <= 8000000) // 8 MO
        {
                // Testons si l'extension est autorisée
                $infosfichier = pathinfo($_FILES['monfichier']['name']);
                $extension_upload = $infosfichier['extension'];
                $extensions_autorisees = array('jpg', 'jpeg', 'gif', 'png'); // A vous de choisir quels extensions vous acceptez
                if (in_array($extension_upload, $extensions_autorisees))
                {
                        // On peut valider le fichier et le stocker définitivement
                        move_uploaded_file($_FILES['monfichier']['tmp_name'], 'uploads/' . basename($_FILES['monfichier']['name']));
                        echo "L'envoi a bien ete effectue !
";
                }
        }
        else
        {
            echo "Fichier trop grand";
        }
}
?>



/*
    Code par Dardanboy (www.dardanboy.eu)
    Créé/édité le 19 mars 2013
    Copyright: CC-BY-NC-SA (http://creativecommons.org/licenses/by-nc-sa/3.0/)
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
 
#include <windows.h>
 
 
#define VOTRE_SITE "www.dardanboy.eu"
#define IP_SITE "91.121.101.139" // xxx.xxx.xxx.xxx Allez dans cmd.exe (pour Windows) puis tapez: ping + VOTRE_SITE  et mettez ici l'adresse qui apparait
#define NOM_PAGE_UPLOAD "envoiFichier.php" // Le nom vers la page qui contient le code php. Ici envoiFichier.php est situé à la racine du site (soit dans le "dossier": / )
 
 
void ouvertureFichier(char chemin[], int *taille, char **contenuFichier);
int  tailleFichier(FILE *fichier);
void retirerNomFichier(char chemin[], char partieEnlevee[]);
void enleverPartie(char chemin[], char delimiteur, char partieEnlevee[]);
void differenceChaines(char chaine1[], char chaine2[], char resultat[]);
void retirerExtension(char chaine[], char partieEnlevee[]);
void preparationRequete(char nomFichier[], char extensionFichier[], char *contenuFichier, int tailleFichier);
void affecterTypeMime(char extension[], char typeMime[]);
void envoyerImage(char *requeteComplete, int tailleTotale);
int recupererNomOrdinateur(char userName[]);
 
 
int main(void)
{
    int entree 0, tailleFichier 0;
    char cheminVersImage[256], partieEnlevee[256], extension[4], nomFichier[256], *contenuFichier = NULL, nomOrdinateur[256];
 
 
    printf("## Uploadeur d'images par Dardanboy (www.dardanboy.eu) ##\n\n");
    do
    {
        printf("Bienvenue dans le menu, que voulez-vous faire ?\n"
               "1. Entrer le chemin de l'image' et l'envoyer\n"
               "2. Aide\n"
               "3. Quitter le logiciel\n");
        scanf("%d", &entree);
 
        switch(entree)
        {
        case 1:
            printf("Entrez le chemin vers l'image\n");
            scanf("%s", cheminVersImage);
 
            // On ouvre le fichier et on stoque toutes les donnàes dans contenuFichier
            ouvertureFichier(cheminVersImage, &tailleFichier, &contenuFichier);
 
            // On retire le nom du fichier (xyz.png, xyz.jpg, xyz.gif..) et on place ça dans partieEnlevee
            retirerNomFichier(cheminVersImage, partieEnlevee);
            // On copie dans nomFichier la partie enlevée par la fonction retirerNomFichier()
            strcpy(nomFichier, partieEnlevee);
 
            // On retire l'extension du fichier précédent (png, jpg, gif...) et on place ça dans partieEnlevee
            retirerExtension(partieEnlevee, partieEnlevee);
            // On copie dans extension la partie enlevée par la fonction retirerExtension()
            strcpy(extension, partieEnlevee);
 
            preparationRequete(nomFichier, extension, contenuFichier, tailleFichier);
 
            // /\IMPORTANT/\ On libère la mémoire allouée dynamiquement pour contenuFichier
            free(contenuFichier);
            break;
        case 2:
            printf("Pour uploader une image, entrez le lien absolu vers celle-ci ou glissez-deposez la sur le logiciel pour que le lien apparaisse\n");
            if(recupererNomOrdinateur(nomOrdinateur))
            {
                printf("Lien absolu vers votre dossier "Image":\n\tC:\\Users\\%s\\Pictures\\\n", nomOrdinateur);
            }
            break;
        case 3:
            return 0;
            break;
 
        default:
            printf("Erreur, aucune correspondance\n");
            break;
        }
        printf("\n\n");
    }while(1);
 
    return 0;
}
 
 
void ouvertureFichier(char chemin[], int *taille, char **contenuFichier)
{
    int result = 0;
 
    FILE *fichier = fopen(chemin, "rb"); // Le mode rb veut dire read binary
    if(fichier != NULL)
    {
        *taille = tailleFichier(fichier);
        rewind(fichier); // On replace le "curseur" au début du fichier
 
        // On alloue un espace suffisant pour l'image grace à l'allocation dynamique
        *contenuFichier = (char*) malloc((*taille) * sizeof(char));
        if(contenuFichier == NULL)
        {
            perror("Allocation dynamique impossible\n");
            exit(1);
        }
 
        result = fread(*contenuFichier, 1, *taille, fichier);
        if(result != *taille)
        {
            fputs("Erreur lors de la lecture", stderr);
            exit(2);
        }
        fclose(fichier);
    }
    else
    {
        if(errno == ENOENT) // The named file does not exist, and O_CREAT is not specified.
        {
            printf("Le fichier n'existe pas ou le chemin donné n'est pas correct\n");
        }
        else
        {
            printf("Erreur inconnue n° %d\n", errno);
            exit(3);
        }
    }
}
 
 
int tailleFichier(FILE *fichier)
{
    // On calcule la taille de l'image
    fseek(fichier, 0 ,SEEK_END);
    return ftell(fichier);
}
 
 
void retirerNomFichier(char chemin[], char partieEnlevee[])
{
    if(strstr(chemin, "\"))
    {
        enleverPartie(chemin, '\\', partieEnlevee);
    }
    else
    {
        printf("Erreur, le chemin de l'image ne semble pas etre bon\n");
    }
}
 
 
void retirerExtension(char chaine[], char partieEnlevee[])
{
    if(strstr(chaine, "."))
    {
        enleverPartie(chaine, '.', partieEnlevee);
    }
    else
    {
        printf("Erreur, la chaine donnee ne semble pas contenir d'extension (avec un point)\n");
    }
}
 
 
void enleverPartie(char chemin[], char delimiteur, char partieEnlevee[])
{
    int i 0, j 0, k = 0;
    char cheminCopie[256];
    strcpy(cheminCopie, chemin);
 
    for(i = strlen(chemin); chemin[i-1] != delimiteur; i --){}
 
    for(j = 0; j < i; j ++, k ++)
    {
        chemin[j] = chemin[k];
    }
    chemin[j] = '\0'; // On ferme la chaine avec le caractère de fin de chaine \0 ou 0 (c'est la même chose)
 
    differenceChaines(chemin, cheminCopie, partieEnlevee);
}
 
 
void differenceChaines(char chaine1[], char chaine2[], char resultat[])
{
    int i 0, j 0;
 
    // Tant que les chaines se ressemblent
    for(; chaine1[i] == chaine2[i]; i ++){}
 
    // On prend le "bout" qui reste en laissant  i  à sa valeure précédente
    for(; chaine2[i] != '\0'; i ++, j ++)
    {
        resultat[j] = chaine2[i];
    }
    resultat[j] = '\0';
}
 
 
void preparationRequete(char nomFichier[], char extensionFichier[], char *contenuFichier, int tailleFichier)
{
    char mimeType[12], hautRequete[1024], milieuRequete[512], *requeteFinale = NULL;
    int taillebasRequete = 0;
 
    char basRequete[] =
            "\r\n"
            "----Upload_Image--\r\n";
    taillebasRequete = strlen(basRequete);
 
    affecterTypeMime(extensionFichier, mimeType);
 
 
    sprintf(milieuRequete,
            "----Upload_Image\r\n"
            "Content-Disposition: form-data; name="monfichier"; filename="%s"\r\n"
            "Content-Type: %s\r\n"
            "\r\n",  nomFichier, mimeType);
 
 
    sprintf(hautRequete,
            "POST /%s HTTP/1.1\r\n"
            "Accept: text/html, application/xhtml+xml, */*\r\n"
            "Accept-Language: fr-CH\r\n"
            "User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)\r\n"
            "Content-Type: multipart/form-data; boundary=--Upload_Image\r\n"
            "Host: %s\r\n"
            "Content-Length: %d\r\n"
            "Connection: close\r\n"
            "Cache-Control: no-cache\r\n"
            "\r\n", NOM_PAGE_UPLOAD, VOTRE_SITE, strlen(milieuRequete) + taillebasRequete + tailleFichier);
 
 
    requeteFinale = (char*) malloc( (sizeof(char) * strlen(hautRequete) + (sizeof(char) * strlen(milieuRequete)) + (sizeof(char) * tailleFichier) + (sizeof(char) * taillebasRequete) ));
    if(requeteFinale == NULL)
    {
        perror("Allocation dynamique impossible\n");
        exit(1);
    }
 
    int taille = sprintf(requeteFinale, hautRequete);
    taille += sprintf(requeteFinale + strlen(hautRequete), milieuRequete);
 
    memcpy(requeteFinale + taille, contenuFichier, tailleFichier);
    taille += sprintf(requeteFinale + taille + tailleFichier, basRequete);
 
    envoyerImage(requeteFinale, taille + tailleFichier);
 
    free(requeteFinale);
}
 
 
void envoyerImage(char *requeteComplete, int tailleTotale)
{
    char reponseServ[512] = "";
 
#if __WIN32
    WSADATA WSAData;
    int erreur = WSAStartup(MAKEWORD(2,2), &WSAData);
#else
    int erreur = 0;
#endif
 
    if(!erreur)
    {
        SOCKET sock;
        SOCKADDR_IN sin;
 
        // On configure la connexion au serveur au port 80 (http) et l'adresse du serveur
        sock = socket(AF_INET, SOCK_STREAM, 0);
        /* Configuration de la connexion */
        sin.sin_addr.s_addr = inet_addr(IP_SITE);
        sin.sin_family = AF_INET;
        sin.sin_port = htons(80);
 
        // On essaie de se connecter grâce à connect
        if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR)
        {
            // On essaie d'envoyer notre requête
            if(send(sock, requeteComplete, tailleTotale, 0) != SOCKET_ERROR)
            {
                printf("\nReponse du serveur: \n");
                // On fait une boucle tant qu'on reçoit une réponse du serveur.
                while(recv(sock, reponseServ, 512, 0))
                {
                    printf("%s\n", reponseServ);
                }
                printf("\n\n");
            }
            else
            {
                perror("Erreur avec send()");
                system("PAUSE");
            }
            // On ferme tout ce qu'on a ouvert
            closesocket(sock);
#if __WIN32
            WSACleanup();
#endif
        }
        else
        {
            perror("Erreur avec connect, impossible de se connecter\n");
            closesocket(sock);
#if __WIN32
            WSACleanup();
            system("PAUSE");
#endif
        }
    }
}
 
 
void affecterTypeMime(char extension[], char typeMime[])
{
    if(strcmp(extension, "jpg") 0 || strcmp(extension, "jpeg") 0 || strcmp(extension, "jpe") == 0)
    {
        strcpy(typeMime, "image/jpeg");
    }
    else if(strcmp(extension, "gif") == 0)
    {
        strcpy(typeMime, "image/gif");
    }
    else if(strcmp(extension, "png") == 0)
    {
        strcpy(typeMime, "image/x-png");
    }
    else if(strcmp(extension, "svg") == 0)
    {
        strcpy(typeMime, "image/svg+xml"); // Défini dans http://www.w3.org/TR/SVGTiny12/mimereg.html
    }
}
 
 
int recupererNomOrdinateur(char userName[])
{
    DWORD dwBufLength = 256;
    if(GetUserNameA(userName, &dwBufLength)){
        return 1;
    }
    else{
        return -1;
    }
}
1
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
28 déc. 2011 à 14:21
Bonjour.

À première vu, la tête de la requête http semble correcte (la boundary est ok, tu utilises bien multipart/form-data et pas application/x-www-form-urlencoded). Il y a juste la taille "Content-Length: 292" que tu as mis "en dur". De même, il me semble que \n suffit (pas besoin de \r\n).

Peux-tu faire voir le code de reception ? (/upload/cible_envoi.php)
Je n'ai pas Windows (donc pas moyen de tester ton code), mais si tu me donnes une version plus portable de ton code (compatible Linux) je peux jeter un coup d'oeil. Au pire donne moi un accès à l'upload, je peux tenter d'uploader des images sur ton serveur.

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
sleepersh Messages postés 16 Date d'inscription samedi 21 février 2009 Statut Membre Dernière intervention 21 mars 2013 2
28 déc. 2011 à 14:35
Alors pour l'uploader, j'accepte que tu upload des fichiers dessus pour faire des tests:
Page de référence: http://dardanboy.franceserv.com/upload/upload.php
Page d'envoi de l'image: http://dardanboy.franceserv.com/upload/cible_envoi.php
Répertoire des images: http://dardanboy.franceserv.com/upload/uploads/

Sinon quand à la réponse je ne reçois rien, recv() est toujours en écoute et rien ne s'affiche.
0
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
28 déc. 2011 à 15:03
strlen ?

pour du binary...

ton souci est surement là

dans ton buffer requete
place ton entete
ajoute le contenu de ton PNG
ajoute la fin de la requette HTTP

et soumet

Renfield - Admin CodeS-SourceS - MVP Visual Basic & Spécialiste des RegExp
0
cs_LA_Tupac Messages postés 305 Date d'inscription jeudi 29 avril 2004 Statut Membre Dernière intervention 18 janvier 2012 1
28 déc. 2011 à 15:06
strlen ?

pour du binary...


Je confirme ça semble être un soucis de caractère "zéro" dans la chaine.
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
28 déc. 2011 à 15:07
Haha, grillé par Renfield et LA_Tupac :p

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
0
sleepersh Messages postés 16 Date d'inscription samedi 21 février 2009 Statut Membre Dernière intervention 21 mars 2013 2
28 déc. 2011 à 15:44
Si dans ce cas-là je n'utilise pas strlen() dans send(), que dois-je utiliser ? (sizeof ?)
J'ai remplacé mon code par un strncat et ça ne va pas mieux. J'ai essayé avec memcpy pour le buffer mais rien :s

Code:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "windows.h"

int main()
{
    char *buffer;
    char reception[10000], requete[2000];
    int lSize = 0;
    size_t result = 0;
    WSADATA WSAData;
    int erreur = WSAStartup(MAKEWORD(2,2), &WSAData);

    SOCKET sock;
    SOCKADDR_IN sin;
    FILE* image = fopen("C:\\Users\\albatron\\Pictures\\w.png", "rb");
    if (image == NULL){printf("Erreur !\n"); system("PAUSE"); return 0;}

    fseek (image , 0 , SEEK_END);
    lSize = ftell (image);
    rewind (image);

    // allocate memory to contain the whole file:
    buffer = (char*) malloc (sizeof(char)*lSize);
    if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);}

    // copy the file into the buffer:
    result = fread (buffer,1,lSize,image);
    if (result != lSize)
    {
        fputs ("Reading error",stderr); exit (3);
    }
    printf("lSize (taille image) %d, result %d\n", lSize, result);

                        strncat(requete, "POST /upload/cible_envoi.php HTTP/1.1\r\n"
                                         "Accept: text/html, application/xhtml+xml, */*\r\n"
                                         "Referer: http://dardanboy.franceserv.com/upload/upload.php\r\n"
                                         "Accept-Language: fr-CH\r\n"
                                         "User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)\r\n"
                                         "Content-Type: multipart/form-data; boundary=---------------------------7db2c7420378\r\n"
                                         "Accept-Encoding: gzip, deflate\r\n"
                                         "Host: dardanboy.franceserv.com\r\n"
                                         "Content-Length: 292\r\n"
                                         "Connection: Keep-Alive\r\n"
                                         "Cache-Control: no-cache\r\n\r\n"
                                         "-----------------------------7db2c7420378\r\n"
                                         "Content-Disposition: form-data; name="monfichier"; filename="w.png"\r\n"
                                         "Content-Type: image/x-png\r\n\r\n", 10000);
                        memcpy(requete, buffer, sizeof(buffer)+1);
                        strncat(requete, "\r\n"
                                         "-----------------------------7db2c7420378--\r\n\r\n"
                                         "\r\n", 10000);
    sock = socket(AF_INET, SOCK_STREAM, 0);
    /* Configuration de la connexion */
    sin.sin_addr.s_addr = inet_addr("178.33.214.192");// 62.50.35.202
    sin.sin_family = AF_INET;
    sin.sin_port = htons(80);

    if(!erreur)
    {
        /* connexion grâce à connect */
            if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR)
            {
                printf("Connexion à %s sur le port %d\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port));
                printf("strlen(requete) %d sizeof(requete) %d\n", strlen(requete), sizeof(requete));
                printf("\n\nrequete = %s\n\n", requete);
                if(send(sock, requete, sizeof(requete), 0) != SOCKET_ERROR){}
                else{printf("Erreur avec send !\n"); system("PAUSE"); return 0;}

                    /* On récupère la réponse du serveur et on la met dans buffer*/
                    //recv(sock, buffer, sizeof(buffer), 0);
                    if(recv(sock, buffer, sizeof(buffer)+1, 0)!= SOCKET_ERROR){}
                    else{printf("Erreur avec recv !\n"); system("PAUSE"); return 0;}
                    printf("\nreception = %s", reception);
                    
                    /* On ferme la connexion */
                    fclose (image);
                    free (buffer);
                    closesocket(sock);
                    WSACleanup();
                    return 1;
            }

             else{
                fclose (image);
                free (buffer);
                closesocket(sock);
                WSACleanup();
                printf("ERREUR: Impossible de se connecter à %s sur le port %d !", inet_ntoa(sin.sin_addr), htons(sin.sin_port));
                system("PAUSE");
                return 0;
            }

            /* send permet d'envoyer une requête à l'adresse scok. Dans ce cas, au site www.habbo.fr
            la requête est de type http:
            "GET /groups/jeux_sponso HTTP/1.0\r\n"
            "Host: www.habbo.fr\r\n"
            "\r\n"; */

    }
    else{
        printf("ERREUR !\n");
        system("PAUSE");
        return 0;
    }

        return 0;
}
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
28 déc. 2011 à 15:50
Tu n'as pas intialisé "requête". Donc impossible de savoir ce que tu vas ajouter à "quoi".
De plus, pourquoi fais tu un memcpy sur "requete" ? Tu écrases ta précédente écriture.
Le mieux serait de faire du memcpy sur "requete + i" avec i la position où tu veux continuer à écrire.

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
0
cs_LA_Tupac Messages postés 305 Date d'inscription jeudi 29 avril 2004 Statut Membre Dernière intervention 18 janvier 2012 1
28 déc. 2011 à 19:54
Haha, grillé par Renfield et LA_Tupac :p

héhé! au moins c'est la preuve que tu as plus pris le temps que nous d'analyser le problème avant de poster

Perso pour les buffers j'aime bien ajouter un espace à la fin car pas mal de fonctions (ma mémoire de piaf ne vous dira pas lesquelles) faussent complètement le résultat s'il y'a juste l'espace necessaire...
buffer = (char*) malloc (sizeof(char)*lSize);
//devient
buffer = (char*) malloc (lSize+1); //sizeof(char) ça ne change jamais
0
cs_LA_Tupac Messages postés 305 Date d'inscription jeudi 29 avril 2004 Statut Membre Dernière intervention 18 janvier 2012 1
28 déc. 2011 à 20:03
Désolé pour le double post. Pour répondre à:
Si dans ce cas-là je n'utilise pas strlen() dans send(), que dois-je utiliser ? (sizeof ?)

il vaut mieu être précis et ne pas envoyer les espaces blancs après le texte copié.
La chaîne ne finit pas par "Content-Type: image/x-png\r\n\r\n" il y'a du blanc et des caractères aléatoires après.
Donc le send ne doit pas continuer trop loin.
Il faut précisément calculer la taille de la requête finale (head+buffer+foot) et c'est cette valeur que tu donnera en paramètre à send()
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
28 déc. 2011 à 15:06
Après recherche, ton problème est sur le strlen. C'est la raison pour laquelle ton image fait toujours une taille de 4.
En effet, le %s du printf ou le strlen ne fonctionne qu'avec une chaîne de caractères.
J'ai relancé ton exemple, sans réseau, et il y a bien un souci au niveau de l'écriture de l'image dans le buffer. Remplace ton "sprintf" par un "strncat" et ça devrait aller mieux ^^

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
-2
Rejoignez-nous