Commande curl pour upload à  partir d'une application ?

fregonesfregones Membre
octobre 2013 modifié dans API AppKit #1

Bonjour à  toutes et à  tous,


 


Après la présentation, voici mon premier problème de débutant sur lequel je coince par manque de connaissance ! J'espère être dans la bonne rubrique ?


 


Je débugge  une application (Photo Nav) pour que celle-ci envoie par FTP des images vers un serveur et qu'elle entre des informations dans une base de données. Je teste en local pour le moment.


 


La commande générer par l'application est la suivante et est un exemple :



/usr/bin/curl –u login:password –T /Users/moncompte/48.png ftp://192.168.1.5/ftp/63.png

Commande récupérée dans la console de Xcode. Curl renvoi l'erreur 26, soit ouverture ou lecture impossible du fichier 48.png. Mais si je reprends cette commande tel quelle dans le terminal d'OSX, cela fonctionne ! Le transfert se fait bien, parfait avec le terminal mais pas avec l'application. J'ai bien essayé de changer les droits d'accès au fichier à  uploader mais rien n'y fait !


 


Ma question est la suivante : pourquoi cette commande ne fonctionne pas avec l'application et que cela fonctionne avec le terminal !? Quelque chose m'échappe !


 


Une idée ? une piste à  suivre ?


 


Merci par avance pour votre aide et votre patience !


 


Bonne journée à  vous.


 


François.


 


P. -S. : les fichiers sources avec de nombreux bugs sont là  :


 


http://www.editions-eyrolles.com/Livre/9782212111927/mac-os-x-creer-un-gestionnaire-de-photos-avec-cocoa-realbasic-et-webobjects


Mots clés:

Réponses

  • CéroceCéroce Membre, Modérateur
    octobre 2013 modifié #2

    Dans quel répertoire es-tu quand tu lances la commande dans le terminal ?


    Essaie de te mettre dans le répertoire de ton exécutable; je ne suis pas sûr de moi, mais c'est peut-être une piste.


  • Tu peux copier/coller l'erreur exacte ?


    Ton application n'aurait pas essayé d'ouvrir le fichier 48.png par ailleurs pendant que tu lances cette commande ?


  • LeChatNoirLeChatNoir Membre, Modérateur

    Bon, je vais peut être répondre un peu à  côté, mais pour faire ce que tu veux faire, je choisirai plutot des requêtes HTTP en mode POST et le framework AFNetworking te permet de faire ça assez facilement...


  • AliGatorAliGator Membre, Modérateur
    Hello !

    Tu la lances comment ta comment ta commande curl dans ton application ? Avec une NSTask ? Tu peux citer le code ?
  • RE. à  tous,


     


    Merci pour votre aide !


     



    Céroce : Dans quel répertoire es-tu quand tu lances la commande dans le terminal ?


    Essaie de te mettre dans le répertoire de ton exécutable; je ne suis pas sûr de moi, mais c'est peut-être une piste.


     



     


    Alors si je me mets dans le répertoire de l'exécutable avec le Terminal : ça fonctionne !


     



    FKDEV : Tu peux copier/coller l'erreur exacte ?


    Ton application n'aurait pas essayé d'ouvrir le fichier 48.png par ailleurs pendant que tu lances cette commande ?


     



     


    Effectivement, l'application ouvre le fichier ou les fichiers afin de sélectionner celui à  importer sur le serveur et de transmettre les infos à  la base de données. Voici l'erreur qui sort sur la console de X-Code :



    [Session started at 2013-10-01 11:09:10 +0200.]
    2013-10-01 11:09:11.385 Photo Nav[962] Dans awakeFromNib
    2013-10-01 11:09:11.385 Photo Nav[962] Dans awakeFromNib
    2013-10-01 11:09:13.218 Photo Nav[962] Nous sommes dans openAction
    2013-10-01 11:09:21.135 Photo Nav[962] path == /Upload
    2013-10-01 11:09:21.137 Photo Nav[962] NB Pictures in a row: 5.104167
    2013-10-01 11:09:32.838 Photo Nav[962] Traitement de l'image : Photo.png
    2013-10-01 11:09:32.885 Photo Nav[962] Commande : /usr/bin/curl -u webobjects_man:webobjects_man -T /Upload/Photo.png ftp://192.168.1.5/ftp/66.png 
    2013-10-01 11:09:32.954 Photo Nav[962] Photo Nav [curl] :curl: 
    2013-10-01 11:09:32.956 Photo Nav[962] Photo Nav [curl] :C
    2013-10-01 11:09:32.957 Photo Nav[962] Photo Nav [curl] :a
    2013-10-01 11:09:32.958 Photo Nav[962] Photo Nav [curl] :n
    2013-10-01 11:09:32.959 Photo Nav[962] Photo Nav [curl] :'
    2013-10-01 11:09:32.959 Photo Nav[962] Photo Nav [curl] :t
    2013-10-01 11:09:32.960 Photo Nav[962] Photo Nav [curl] : 
    2013-10-01 11:09:32.961 Photo Nav[962] Photo Nav [curl] :o
    2013-10-01 11:09:32.962 Photo Nav[962] Photo Nav [curl] :p
    2013-10-01 11:09:32.963 Photo Nav[962] Photo Nav [curl] :e
    2013-10-01 11:09:32.964 Photo Nav[962] Photo Nav [curl] :n
    2013-10-01 11:09:32.965 Photo Nav[962] Photo Nav [curl] : 
    2013-10-01 11:09:32.966 Photo Nav[962] Photo Nav [curl] :'
    2013-10-01 11:09:32.967 Photo Nav[962] Photo Nav [curl] : 
    2013-10-01 11:09:32.968 Photo Nav[962] Photo Nav [curl] :/
    2013-10-01 11:09:32.969 Photo Nav[962] Photo Nav [curl] :U
    2013-10-01 11:09:32.971 Photo Nav[962] Photo Nav [curl] :p
    2013-10-01 11:09:32.972 Photo Nav[962] Photo Nav [curl] :l
    2013-10-01 11:09:32.973 Photo Nav[962] Photo Nav [curl] :o
    2013-10-01 11:09:32.974 Photo Nav[962] Photo Nav [curl] :a
    2013-10-01 11:09:32.975 Photo Nav[962] Photo Nav [curl] :d
    2013-10-01 11:09:32.976 Photo Nav[962] Photo Nav [curl] :/
    2013-10-01 11:09:32.977 Photo Nav[962] Photo Nav [curl] :P
    2013-10-01 11:09:32.977 Photo Nav[962] Photo Nav [curl] :h
    2013-10-01 11:09:32.978 Photo Nav[962] Photo Nav [curl] :o
    2013-10-01 11:09:32.979 Photo Nav[962] Photo Nav [curl] :t
    2013-10-01 11:09:32.980 Photo Nav[962] Photo Nav [curl] :o
    2013-10-01 11:09:32.981 Photo Nav[962] Photo Nav [curl] :.
    2013-10-01 11:09:32.982 Photo Nav[962] Photo Nav [curl] :p
    2013-10-01 11:09:32.983 Photo Nav[962] Photo Nav [curl] :n
    2013-10-01 11:09:32.984 Photo Nav[962] Photo Nav [curl] :g
    2013-10-01 11:09:32.985 Photo Nav[962] Photo Nav [curl] :'
    2013-10-01 11:09:32.985 Photo Nav[962] Photo Nav [curl] :!
    2013-10-01 11:09:32.986 Photo Nav[962] Photo Nav [curl] :
    2013-10-01 11:09:32.987 Photo Nav[962] Photo Nav [curl] :c
    2013-10-01 11:09:32.988 Photo Nav[962] Photo Nav [curl] :u
    2013-10-01 11:09:32.989 Photo Nav[962] Photo Nav [curl] :r
    2013-10-01 11:09:32.990 Photo Nav[962] Photo Nav [curl] :l
    2013-10-01 11:09:32.991 Photo Nav[962] Photo Nav [curl] ::
    2013-10-01 11:09:32.992 Photo Nav[962] Photo Nav [curl] : 
    2013-10-01 11:09:32.993 Photo Nav[962] Photo Nav [curl] :t
    2013-10-01 11:09:32.994 Photo Nav[962] Photo Nav [curl] :r
    2013-10-01 11:09:32.995 Photo Nav[962] Photo Nav [curl] :y
    2013-10-01 11:09:32.996 Photo Nav[962] Photo Nav [curl] : 
    2013-10-01 11:09:32.997 Photo Nav[962] Photo Nav [curl] :'
    2013-10-01 11:09:32.998 Photo Nav[962] Photo Nav [curl] :c
    2013-10-01 11:09:32.999 Photo Nav[962] Photo Nav [curl] :u
    2013-10-01 11:09:33.000 Photo Nav[962] Photo Nav [curl] :r
    2013-10-01 11:09:33.001 Photo Nav[962] Photo Nav [curl] :l
    2013-10-01 11:09:33.001 Photo Nav[962] Photo Nav [curl] : 
    2013-10-01 11:09:33.002 Photo Nav[962] Photo Nav [curl] :-
    2013-10-01 11:09:33.003 Photo Nav[962] Photo Nav [curl] :-
    2013-10-01 11:09:33.004 Photo Nav[962] Photo Nav [curl] :h
    2013-10-01 11:09:33.005 Photo Nav[962] Photo Nav [curl] :e
    2013-10-01 11:09:33.006 Photo Nav[962] Photo Nav [curl] :l
    2013-10-01 11:09:33.007 Photo Nav[962] Photo Nav [curl] :p
    2013-10-01 11:09:33.008 Photo Nav[962] Photo Nav [curl] :'
    2013-10-01 11:09:33.009 Photo Nav[962] Photo Nav [curl] : 
    2013-10-01 11:09:33.010 Photo Nav[962] Photo Nav [curl] :o
    2013-10-01 11:09:33.010 Photo Nav[962] Photo Nav [curl] :r
    2013-10-01 11:09:33.011 Photo Nav[962] Photo Nav [curl] : 
    2013-10-01 11:09:33.012 Photo Nav[962] Photo Nav [curl] :'
    2013-10-01 11:09:33.013 Photo Nav[962] Photo Nav [curl] :c
    2013-10-01 11:09:33.014 Photo Nav[962] Photo Nav [curl] :u
    2013-10-01 11:09:33.015 Photo Nav[962] Photo Nav [curl] :r
    2013-10-01 11:09:33.016 Photo Nav[962] Photo Nav [curl] :l
    2013-10-01 11:09:33.017 Photo Nav[962] Photo Nav [curl] : 
    2013-10-01 11:09:33.018 Photo Nav[962] Photo Nav [curl] :-
    2013-10-01 11:09:33.019 Photo Nav[962] Photo Nav [curl] :-
    2013-10-01 11:09:33.019 Photo Nav[962] Photo Nav [curl] :m
    2013-10-01 11:09:33.022 Photo Nav[962] Photo Nav [curl] :a
    2013-10-01 11:09:33.023 Photo Nav[962] Photo Nav [curl] :n
    2013-10-01 11:09:33.024 Photo Nav[962] Photo Nav [curl] :u
    2013-10-01 11:09:33.025 Photo Nav[962] Photo Nav [curl] :a
    2013-10-01 11:09:33.026 Photo Nav[962] Photo Nav [curl] :l
    2013-10-01 11:09:33.027 Photo Nav[962] Photo Nav [curl] :'
    2013-10-01 11:09:33.028 Photo Nav[962] Photo Nav [curl] : 
    2013-10-01 11:09:33.029 Photo Nav[962] Photo Nav [curl] :f
    2013-10-01 11:09:33.029 Photo Nav[962] Photo Nav [curl] :o
    2013-10-01 11:09:33.030 Photo Nav[962] Photo Nav [curl] :r
    2013-10-01 11:09:33.031 Photo Nav[962] Photo Nav [curl] : 
    2013-10-01 11:09:33.032 Photo Nav[962] Photo Nav [curl] :m
    2013-10-01 11:09:33.033 Photo Nav[962] Photo Nav [curl] :o
    2013-10-01 11:09:33.034 Photo Nav[962] Photo Nav [curl] :r
    2013-10-01 11:09:33.035 Photo Nav[962] Photo Nav [curl] :e
    2013-10-01 11:09:33.036 Photo Nav[962] Photo Nav [curl] : 
    2013-10-01 11:09:33.037 Photo Nav[962] Photo Nav [curl] :i
    2013-10-01 11:09:33.037 Photo Nav[962] Photo Nav [curl] :n
    2013-10-01 11:09:33.038 Photo Nav[962] Photo Nav [curl] :f
    2013-10-01 11:09:33.039 Photo Nav[962] Photo Nav [curl] :o
    2013-10-01 11:09:33.040 Photo Nav[962] Photo Nav [curl] :r
    2013-10-01 11:09:33.041 Photo Nav[962] Photo Nav [curl] :m
    2013-10-01 11:09:33.042 Photo Nav[962] Photo Nav [curl] :a
    2013-10-01 11:09:33.043 Photo Nav[962] Photo Nav [curl] :t
    2013-10-01 11:09:33.044 Photo Nav[962] Photo Nav [curl] :i
    2013-10-01 11:09:33.045 Photo Nav[962] Photo Nav [curl] :o
    2013-10-01 11:09:33.046 Photo Nav[962] Photo Nav [curl] :n
    2013-10-01 11:09:33.046 Photo Nav[962] Photo Nav [curl] :
    2013-10-01 11:09:33.052 Photo Nav[962] theResult == 26


    AliGator : Hello !

    Tu la lances comment ta comment ta commande curl dans ton application ? Avec une NSTask ? Tu peux citer le code ?

     




     


    La commande curl se lance avec la classe Apple TaskWrapper. Ci-après le code de cette section du lancement de la commande.


     


     




    #import "ConnectController.h"
    #import "PNImageCell.h"


    @implementation ConnectController


    /*
     * initWithImportCtrl: :
     * on crée le ConnectController en spécifiant le ImportController
     * qui est lié.
     * ==> renvoie le ConnectController créé
     */
    - (ConnectController *) initWithImportCtrl:parentCtrl
    {
        importCtrl = parentCtrl;
        isConnected = NO;
        connectTask = nil;
        return self;
    }


    /*
     * closePassWindow:
     * ferme la fenêtre d'authentification
     */
    - (IBAction)closePassWindow:(id)sender
    {
        // On repasse en mode non-modal
        [NSApp stopModal];
        if (sender == cancelButton)
            // si l'utilisateur a annulé, on doit annuler tout
            // le traitement d'import dans la base.
    [importCtrl setCanceled];
        else {
            // si l'utilisateur a dit OK, on récupère le login
            // et le password. On fait des retain pour s'assurer
            // qu'ils ne seront pas libérés trop tôt.
            if (login != nil)
                [login release];
    login = [loginField stringValue];
            [login retain];
            if (pass != nil)
                [pass release];
    pass = [passField stringValue];
            [pass retain];
        }
    }


    /*
     * setLoginAndPass
     * si le login et le password sont définis dans les préférences,
     * on les récupère, sinon, on demande à  s'authentifier.
     */
    - (void) setLoginAndPass
    {
        NSUserDefaults* defaults;
        defaults = [NSUserDefaults standardUserDefaults];
        login = [defaults stringForKey:@login];
        [login retain];
        pass = [defaults stringForKey:@passwd];
        [pass retain];
        if (([login length] == 0) || ([pass length] == 0)) {
    [self askLoginAndPass];
        }
    }


    /*
     * loadNibFile
     * chargement du fichier d'interface ConnectView.nib
     * qui contient les éléments d'interface liés à  la connexion
     * (la fenêtre d'authentification)
     */
    - (void) loadNibFile
    {
        // Chargement du fichier
        if (![NSBundle loadNibNamed:@ConnectView owner:self])  {
    NSLog(@Failed to load ConnectView.nib);
    NSBeep();
    return;
        }
        // les fenêtres décrites dans ce fichier n'ont pas à  apparaà®tre
        // dans le menu des fenêtres de l'application
        [passWindow setExcludedFromWindowsMenu:YES];
    }


    /*
     * askLoginAndPass
     * affiche la fenêtre d'authentification
     */
    - (void) askLoginAndPass
    {
        // Si la fenêtre n'est pas chargée, on charge le fichier d'interface
        if (passWindow==nil) {
    [self loadNibFile];
        }
        // Si le login est spécifié dans les préférences, on pré-rempli le champ
        // et on se positionne sur le champ de saisie du mot de passe
        if ([login length] > 0) {
    [loginField setStringValue:login];
    [passWindow setInitialFirstResponder:passField];
        }
        if (passWindow!=nil) {
            // Création du dialogue modal en forme de feuille
    [NSApp beginSheet:passWindow
               modalForWindow:[NSApp mainWindow]
       modalDelegate:nil
      didEndSelector:nil
                  contextInfo:nil];
            // lancement du mode modal pour notre dialogue
    [NSApp runModalForWindow:passWindow];
            // arrêt du mode modal à  la fermeture du dialogue
    [NSApp endSheet:passWindow];
            // affichage du dialogue
    [passWindow orderOut:self];
        }
    }


    /*
     * processStarted
     * le tâche est en cours d'exécution
     */
    - (void)processStarted
    {
        isConnected=YES;
    }


    /*
     * processStarted
     * le tâche est en cours d'exécution
     */
    - (void)processFinished
    {
        isConnected=NO;
    }


    /*
     * appendOutput:
     * gestion de l'affichage de la commande lancée
     * actuellement, on affiche sur la console
     */
    - (void)appendOutput:(NSString *)output
    {
        NSLog(@Photo Nav [curl] :%@",output);
    }


    /*
     * sendImage:withId:
     * envoi d'une image sur le serveur
     * ==> renvoie YES si le code retour de la commande est 0
     */
    - (BOOL) sendImage:(id)anImage withId:(int)idImage
    {
        // Création des chaines représentant les paramètres de curl


        // paramètre pour l'authentification de la forme  -u<login>:<password>
        NSString *authStr = [NSString stringWithFormat:@-u %@:%@",login,pass];


        // paramètre pour l'URL, doit contenir le nom du fichier destination
        NSString *destURL = [NSString stringWithFormat:@ftp:;//%@/ftp/%d.%@",
            [[NSUserDefaults standardUserDefaults] stringForKey:@serverHostname],
            idImage,
            [[anImage fullImageName] pathExtension]];


        // paramètre pour spécifier l'envoi du fichier local <filepath>
        // de la forme    -T <filepath>
        NSString *fileOpt = [NSString stringWithFormat:@-T %@",
            [anImage fullImageName]];


        // La commande à  lancer :
        // NSString *command = @/essai.sh;
        NSString *command = @/usr/bin/curl;


        // création d'un tableau contenant la commande en premier élément et
        // les arguments en éléments suivant
        NSArray *curlcmd = [NSArray arrayWithObjects:command,
            authStr,
            fileOpt,
            destURL,
            nil];




        if (isConnected)
        {
            // si une connexion est déjà  en cours, on stoppe tout traitement
            [connectTask stopProcess];
            [connectTask release];
            connectTask=nil;
            return NO;
        }
        else
        {
            if (connectTask!=nil)
                [connectTask release];
            NSLog(@Commande : %@ ",[curlcmd componentsJoinedByString:@ ]);
            // création du TaskWrapper avec la command et ses arguments.
            connectTask=[[TaskWrapper alloc] initWithController:self arguments:curlcmd];
            // lancement de la connexion
            [connectTask startProcess];
            // on attend la fin de la connexion et on récupère le code retour
            int theResult = [connectTask waitForResult];


            NSLog(@theResult == %d\n,theResult);
            [self processFinished];
            // on renvoie YES si le code retour vaut 0
            return (theResult == 0);
        }
    }


    /*
     * dealloc
     * destructeur de ConnectController.
     * fait le ménage dans les objets créés par ConnectController
     */
    - (void) dealloc
    {
        if (connectTask!=nil)
            [connectTask release];
        if (login != nil)
            [login release];
        if (pass != nil)
            [pass release];
        // après le traitement spécifique, on appelle le destructeur standard
        [super dealloc];
    }


    /*
    - (ConnectController *) init
    {
        isConnected = NO;
        connectTask = nil;
        return self;
    }
    */


    /*
     * login
     * accesseur pour le paramètre login
     * utile pour récupérer le login depuis d'autres classes (DBController par exemple)
     */
    - (NSString *) login
    {
        return login;
    }


    @end

    Les requêtes en HTTP : je ne sais pas !? (sourire)


     


    Quel patience vous avez : merci infiniment !


     


    Bien cordialement


     


    François.


  • NSArray *curlcmd doit contenir un objet par paramètre.


    /usr/bin/curl -u webobjects_man:webobjects_man -T /Upload/Photo.png ftp://192.168.1.5/ftp/66.png 


     


    donne


     


    NSArray *curlcmd = [NSArray arrayWithObjects:@-u, @webobjects_man:webobjects_man, @-T, @/Upload/Photo.png, @"ftp://192.168.1.5/ftp/66.png "];

  • AliGatorAliGator Membre, Modérateur
    J'ai pas tout lu encore, mais vite fait avant de partir manger je vois déjà  :
    1) que c'est bizarre ton message d'erreur qui s'affiche avec un caractère par ligne (et très chiant à  lire ^^)
    2) que l'erreur semble dire "Can't open '/Upload/Photo.png'" (et non "/Users/tonnom/40.png" comme tu le mettais dans ton message d'origine). As-tu vraiment un dossier "Upload" à  la racine même de ton disque dur ?
  • RE.


     



    NSArray *curlcmd doit contenir un objet par paramètre.


    /usr/bin/curl -u webobjects_man:webobjects_man -T /Upload/Photo.png ftp://192.168.1.5/ftp/66.png 


     


    donne


     


    NSArray *curlcmd = [NSArray arrayWithObjects:@-u, @webobjects_man:webobjects_man, @-T, @/Upload/Photo.png, @"ftp://192.168.1.5/ftp/66.png "];


     



     


    Je vais voir de se côté là ...


     


    J'ai pas tout lu encore, mais vite fait avant de partir manger je vois déjà  :
    1) que c'est bizarre ton message d'erreur qui s'affiche avec un caractère par ligne (et très chiant à  lire ^^)
    2) que l'erreur semble dire "Can't open '/Upload/Photo.png'" (et non "/Users/tonnom/40.png" comme tu le mettais dans ton message d'origine). As-tu vraiment un dossier "Upload" à  la racine même de ton disque dur ?

     



     


    Oui, c'est un peu le bazar à  lire ce message d'erreur dans la console ! Je vais essayez d'arranger çà  ! (sourire)


    Oui, pour test et seulement pour test, j'ai un dossier Upload à  la racine. Et, le fichier test à  uploader est Photo.png puis renommer en "numéro".png par l'application. Dans cette configuration comme dans l'autre cela fonctionne avec le terminal.


     


    Bien cordialement


     


    François.

  • Bonjour,


     


    Pourquoi ne pas utilise les classes Apple faite pour ça, pour toute communication http/https/ftp/file ( url loading system). Ou bien y a un truc que je ne comprends pas. 


  • CéroceCéroce Membre, Modérateur


    Pourquoi ne pas utilise les classes Apple faite pour ça, pour toute communication http/https/ftp/file ( url loading system). Ou bien y a un truc que je ne comprends pas. 




     


    Sous OS X, on peut tout à  fait utiliser les outils en ligne de commande. Utiliser curl est probablement plus simple dans un premier temps, que de tout coder avec NSURLConnection et compagnie.

Connectez-vous ou Inscrivez-vous pour répondre.