Binding mod_curl [Descarga de ficheros de Internet]

Started by josebita, November 25, 2011, 12:32:52 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

peterpollito

#90
Funciona de lujo! Karma Josebita!

Pd: ¿Para descargar desde Iphone con 3G funcionara igual?

josebita

Quote from: peterpollito on January 13, 2012, 10:36:42 AM
Funciona de lujo! Karma Josebita!

Pd: ¿Para descargar desde Iphone con 3G funcionara igual?
Sip. Lo único que la versión para iphone (aún) tiene una versión un poquito anterior a esta y no os van a funcionar los imsmos programas... tengo previsto actualizarla a lo largo de este finde.

La momia que fuma

Como podría detectar el fallo si el archivo a descargar no esta?

josebita

Quote from: La momia que fuma on January 23, 2012, 08:08:52 PM
Como podría detectar el fallo si el archivo a descargar no esta?
¡Ups! Menudo FAIL. Lo dejé para más adelante y se me olvidó, al final.
He actualizado el link para win32 con un binario que devuelve el código de retorno de curl_easy_perform
Basicamente retval > 0 es error y retval == 0 es que todo ha ido bien. retval == -2 sigue siendo "que te esperes, niño".
Eso sí, un 404 no te va a devolver un error de esta forma, así que vas a tener que chequearlo a mano. La lista completa de errores que devuelve la librería la tienes aquí:
http://code.google.com/p/bennugd-monolithic/source/browse/trunk/3rdparty/curl/include/curl/curl.h#393

Otra cosa: he compilado el binario rapidito, así que puede que me haya pasado algo: si es así, avisa y lo miro pero yo diría que está bien.

Aprovecho desde aquí para mentar a la puñetera madre de todo el FBI por cerrar megaupload e inutilizar los enlaces a los binarios para OSX del módulo. ¡Un beso para ella!

La momia que fuma

hmm, he cambiado curl_perform(curl, &status); por curl_easy_perform(curl, &status); pero no me la reconoce...

josebita

#95
Quote from: La momia que fuma on January 24, 2012, 06:38:18 PM
hmm, he cambiado curl_perform(curl, &status); por curl_easy_perform(curl, &status); pero no me la reconoce...
No me he expresado bien, perdona.
La librería se usa de la misma forma que hasta ahora, sólo que ahora el valor de status se puede cambiar a un valor > 0 en caso de error.
curl_easy_perform() es el nombre de la función C que se ejecuta cuando tú llamas a la función curl_perform() de bennu y el valor de status se cambia a lo que devuelva.

Por eso te he enlazado a la lista de errores.


[Edito] Acabo de probar el siguiente código en OSX:import "mod_video"
import "mod_curl"
import "mod_say"
import "mod_mouse"
import "mod_text"
import "mod_map"
import "mod_file"

Global
int width = 1024;
int height = 768;
int quit=0;
end;

Process bouncer()
Private
    int vx=3, vy=3;

Begin
    graph = load_png("Icon.png");
    // Position the graphic onscreen
    x = 10+graphic_info(0, GRAPH, G_WIDTH);
    y = 10+graphic_info(0, GRAPH, G_HEIGHT);
    while(quit == 0)
        if(x + vx >= width || x+vx < 0)
            vx = -vx;
        end
        if(y+vy >= height || y+vy < 0)
            vy = -vy;
        end
        x += vx; y += vy;
        FRAME;
    End;
End;

Process main()
Private
    int i=0, status=0, curl=0;
    int tostring=0;     // Switch to 1 to download to a string
    string output;

Begin
    set_mode(width, height, 16);
   
    // Remove Google logo, if it exists already
    if(file_exists("classicplus.png"))
        fremove("classicplus.png");
        say("Removed existing logo");
    end;
   
    bouncer();
   
    say("Starting download");
   
    // Start libcurl, set options, perform transfer
    curl = curl_init();
    if(curl == -1)
        say("Curl initialisation failed, quitting");
        quit = 1;
        return;
    end;
   
    curl_setopt(curl, CURLOPT_NOPROGRESS,    1);
    if(tostring == 0)
        // Use this to write to a file
        curl_setopt(curl, CURLOPT_WRITEDATA, "classicplus.png");
        curl_setopt(curl, CURLOPT_URL, "http://www.google.es/logos/classicplus.png");
    else
        // Use this to download to a string
        curl_setopt(curl, CURLOPT_WRITEDATA, &output);
        curl_setopt(curl, CURLOPT_URL, "http://www.google.es/");
    end
   
    curl_perform(curl, &status);
   
    // Wait for the transfer to finish
    while(status < 0)
        FRAME;
    end;
   
    if(status > 0)
        say("Transfer failed with status "+status+", quitting");
        quit=1;
        return;
    end
   
    if(tostring == 0)
        // Replace the bouncer image by the google logo we just downloaded
        unload_map(0, son.graph);
        son.graph = load_png("classicplus.png");
    else
        write(0, 0, 0, 0, output);
    end
   
    curl_cleanup(curl);
   
    say("Download done!");

    while(! mouse.right)
        FRAME;
    end;
    quit=1;
End;

Y el resultado ha sido:imac:mod_curl joseba$ bgdi main
Removed existing logo
Starting download
Status: -2
[...]
Status: -2
Transfer failed with status 6, quitting
De forma que si me voy a la lista de errores que te he enlazado, el 6 es CURLE_COULDNT_RESOLVE_HOST. Entonces me acuerdo de que tengo el bittorrent dándolo todo y saturando mi conexión incluso para lo más básico :)

josebita

Actualizados binarios para OSX y reenlazados desde Google Code, a ver si el FBI no lo chapa.

La momia que fuma

#97
>_<


Yo sigo de pesao, jeje


He estado probando a ver si conseguía que saltase el error...como no lo conseguía probé con tu código a ver si era gambazo mio (Cambiando la dirección para que intente descargar algo que no existe)...pero tampoco me da resultado.


No da error y crea un classicplus.png vacío...


Cogí la dll (versión win) del link del 1er post, supongo que es ese, no? (Al menos pone que se actualizó ayer)

josebita

#98
Sí, el enlace es ese.
El tema es que el error que te está dando es un error 404 típico de esos de que no se encuentra el fichero.
Los errores que te va a dar la librería te saldrán en caso de que pongas un protocolo raro (prueba a poner httjhsgdjhsfajh://www.google.com) que no sea capaz de encontrar el host (desconecta el ordenador de internet para hacer la prueba) y cosas así.

Si la librería es capaz de conectarse al servidor y el servidor le devuelve una página de error, la librería ahora mismo no se entera.

De momento lo más sencillo para comprobar si la transferencia se ha completado correctamente o no es checkear los valores de retorno de las funciones de carga (load_png y similares).

==

La verdad es que no lo había probado, pero eso se haría leyendo las cabeceras que te mande de vuelta el servidor. Es una opción de configuración de libcurl pero hay que incluirla en la librería a mano así que voy a necesitar unos días para poder implementarla, pero no debería ser complicado.

Basicamente lo que harás será hacer otra llamada a curl_setopt() donde le indiques dónde quieres guardar las cabeceras que te mande el servidor -igual que se hace ahora con el fichero a descargar en sí- y luego leerla tú (desde código Bennu) para ver si ha fallado o no.


Por eso es bueno que useis la librería, así mejora :)

La momia que fuma

Aaah, vale, si, es lo que me explicabas hace un par de posts, que no me enteré bien jeje :P


Gracias!

SplinterGU

#100
joseba...

con estas lineas, si la curl_easy_perform da CURLE_OK, podes obtener el http response code con las siguientes lineas (si da diferente a CURL_OK, entonces es otro tipo de error no http, sino por ejemplo, no se puede resolver el nombre dns, error de conexion, etc)


        long theResponseCode;
        ...
    res = curl_easy_getinfo(curl, CURLINFO_HTTP_CODE, &theResponseCode);
    if (res == CURLE_OK) {
            printf( "HTTP_RESPONSE_CODE=%d\n", theResponseCode );
    }


con esto... 200 es ok... 404 not found, etc
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

josebita

Ok, thanks lo añadiré.

En todo caso también añadiré la funcionalidad de descarga de cabeceras, que imagino que será útil. En general, ahora mismo funciona bien pasar cualquier opción que se pase como entero o cadena, pero los punteros los tengo que "empalmar" a mano.


[Edito] ¡Bienvenido de vuelta del retiro espiritual! :)

SplinterGU

Download Lastest BennuGD Release: http://www.bennugd.org/node/2

Erkosone

Buenas, he estado "intentando" hacer algo con curl en bennu pero sinceramente soy un completo ignorante de esta librería, si alguno de vosotros la conoce lo suficiente como para traducir este Script que os dejo, se podrá postear en Facebook directamente desde los juegos programados en bennu.


De verdad que es muy interesante, mi problema.. la completa ignorancia sobre curl..


Alguien con conocimiento de la lib sabe traducir esto a código bennu??




#!/bin/bash
#cambia esto
email="tu_email_de_usuario_en_facebook"
pass="tu_contraseña_en_facebook"
#a partir de aquí no es necesario cambiar nada más
texto=$1
if [ -z "$texto" ]; then echo -e "Uso:\n$0 \"texto a publicar\"\n\n"; exit 1 ;fi
texto=${texto:0:140}
cokkies="~/.cookies.txt"
user_agent="Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0; es-ES)"
#nos logeamos y cogemos la url de la página redirigida
pagina=`curl -L --silent --keepalive-time 5 --user-agent "${user_agent}" --cookie "${cokkies}" --cookie-jar "${cokkies}" -d "email=$email" -d "pass=$pass" -d "login=Entrar" https://m.facebook.com/login.php`
pagina_redirige=`echo $pagina | sed -r 's/.*href="(http:.*;manual_redirect=1)".*/\1/g'`
#conectamos con la nueva página y leemos los datos que contiene su formulario para postear a facebook
pagina_con_formulario=`curl -L --silent --user-agent "${user_agent}" --cookie "${cokkies}" --cookie-jar "${cokkies}" "$pagina_redirige"`
url_action=`echo $pagina_con_formulario | sed -r 's/.*fbb=(.*&amp.*refid=.?)".*/\1/'`
post_form_id=`echo -n $pagina_con_formulario | sed -r 's/.*name="post_form_id" value="([^"]*)".*/\1/g'`
fb_dtsg=`echo -n $pagina_con_formulario | sed -r 's/.*name="fb_dtsg" value="([^"]*)".*/\1/g'`
url_action_completo="http://m.facebook.com/a/home.php?fbb=$direccionForm"
#ya tenemos los datos con los que componer el query final a Facebook, enviamos el mensaje
curl -X POST --user-agent "$user_agent" --cookie "$cokkies" --cookie-jar "$cokkies" --data-urlencode "status='$texto'" -d "update=Compartir" -d "post_form_id=$post_form_id" -d "fb_dtsg=$fb_dtsg" "$url_action_completo"
exit

SplinterGU

no pedis nada!

ahi no solo tenes requerimiento curl, sino tambien tenes manejo de regular expresion con submatches...
Download Lastest BennuGD Release: http://www.bennugd.org/node/2