Recentemente mi sono trovato a dovere simulare il comportamendo di un browser interagendo con un web server in PHP. L’obiettivo dello script PHP che si stava facendo era quello di simulare il caricamento in POST di un documento. L’obiettivo è facilmente raggiungibile in PHP tramite le librerie CURL. Cercando su internet si trovano numerosi esempi da cui se ne deduce che l’uso-tipo è il seguente:
/* L'url a cui inviare il POST */ $request_url = "http://www.ciccio.com/upload.php"; /* Indico a CURL quale sia il file da inviare: * nel form c'è un <input type="file" name="FileUP" /> */ $post_params['FileUP'] = "@/home/io/TestPdf2.pdf"; /* Nel Form ho un qualsivoglia altro parametro da passare * in post */ $post_params['AltroParametro'] = "Ezekiel"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $request_url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $post_params); curl_setopt($ch, CURLOPT_VERBOSE, TRUE); $result = curl_exec($ch); curl_close($ch);
Il trucco sta nello specificare con la @ davanti il nome del file da inviare: in questo modo CURL capisce che parliamo di un file e si regola di conseguenza. Tutto ha funzionato bene fino a che non ho provato ad eseguire lo stesso codice da dietro SQUID in modalità trasparente, che ha iniziato a rispondermi “Invalid request”. Dopo ore ed ore di tentativi (inutili), ho scoperto che il punto è molto semplice: CURL utilizza un’intestazione HTTP non supportata da Squid, la “Expect: 100-continue”. Per impedire questo comportamento è sufficiente aggiungere un’opzione:
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
E tutto magicamente funzionerà.