2010-08-07 10 views
11

Estoy usando la función cURL de PHP para leer perfiles de steampowered.com. Los datos recuperados son XML, y solo se necesitan los primeros aproximadamente 1000 bytes.Problemas para limitar el tamaño de descarga de la función cURL de PHP

El método que estoy usando es agregar un encabezado de rango, que leo en una respuesta de desbordamiento de pila (curl: How to limit size of GET?). Otro método que probé fue usar el curlopt_range, pero tampoco funcionó.

<? 
$curl_url = 'http://steamcommunity.com/id/edgen?xml=1'; 
$curl_handle = curl_init($curl_url); 

curl_setopt ($curl_handle, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt ($curl_handle, CURLOPT_CONNECTTIMEOUT, 2); 
curl_setopt ($curl_handle, CURLOPT_HTTPHEADER, array("Range: bytes=0-1000")); 

$data_string = curl_exec($curl_handle); 

echo $data_string; 

curl_close($curl_handle); 
?> 

Cuando se ejecuta este código, devuelve todo.

Estoy usando PHP Version 5.2.14.

+3

¿Está seguro de que el servidor que está consultando admite rango? Porque cuando intento desde la línea de comandos obtengo también el documento completo, lo que me lleva a pensar que steamcommunity.com no tiene esa función habilitada. – Doon

Respuesta

18

El servidor no respeta el encabezado del rango. Lo mejor que puede hacer es cancelar la conexión tan pronto como reciba más datos de los que desea. Ejemplo:

<?php 
$curl_url = 'http://steamcommunity.com/id/edgen?xml=1'; 
$curl_handle = curl_init($curl_url); 

$data_string = ""; 
function write_function($handle, $data) { 
    global $data_string; 
    $data_string .= $data; 
    if (strlen($data_string) > 1000) { 
     return 0; 
    } 
    else 
     return strlen($data); 
} 

curl_setopt ($curl_handle, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt ($curl_handle, CURLOPT_CONNECTTIMEOUT, 2); 
curl_setopt ($curl_handle, CURLOPT_WRITEFUNCTION, 'write_function'); 

curl_exec($curl_handle); 

echo $data_string; 

Tal vez de forma más limpia, se puede utilizar la envoltura http (esto también se usaría rizo si se compiló con --with-curlwrappers). Básicamente, debe llamar al fread en un bucle y luego al fclose en la transmisión cuando obtiene más datos de los que deseaba. También puede usar una secuencia de transporte (abra la secuencia con fsockopen, en lugar de fopen y envíe los encabezados manualmente) si allow_url_fopen está deshabilitado.

+0

¡Esto funcionó! Aunque, no entiendo completamente la mecánica de CURLOPT_WRITEFUNCTION. ¿Puedes explicar qué está pasando allí? Gracias de nuevo. – Curtis

+1

@Cur Es una devolución de llamada llamada por la extensión curl cada vez que se reciben datos nuevos. La devolución de llamada recibe el controlador de curl y los datos que se acaban de leer. Debería devolver el número de bytes leídos, si no lo hace, aborta la transferencia (aunque esta última parte no está documentada, parece ser el comportamiento). – Artefacto

+2

@Cur OK Encontré los documentos aquí: "Devuelve el número de bytes realmente atendidos. Si esa cantidad difiere de la cantidad transferida a su función, se enviará un mensaje de error a la biblioteca. Esto abortará la transferencia y se devolverá. CURLE_WRITE_ERROR ". http://curl.haxx.se/libcurl/c/curl_easy_setopt.html – Artefacto

Cuestiones relacionadas