2015-02-05 82 views
0

我用下面的測試程序來獲取網站的內容:PHP了shell_exec插入CR字符curl命令,導致服務器錯誤500

<?php 

function getData($url, $output) { 
    // set the path for CURL 
    if (file_exists('/var/lib')) 
     $curl = 'curl'; 
    else 
     $curl = 'curl.exe'; 
    $curl .= ' --trace trace.txt --header "User-Agent: Some-Agent/1.0" '; 
    echo "\nreading $url...\n"; 
    $buffer = shell_exec("$curl -i \"$url\""); 
    // if this is a 301 redirection URL, follow it one step 
    if ((preg_match('~^HTTP.+? 301 ~', $buffer)) and preg_match('~Location: (.+)~', $buffer, $location)) { 
     $cmd = "$curl -i \"$location[1]\""; 
     echo "$cmd\n"; 
     $buffer = shell_exec($cmd); 
    } 
    file_put_contents($output, $buffer); 
} 

// test with a URL that will be redirected: 
getData("http://www.onvista.de/aktien/fundamental/EISEN-UND-HUETTENWERKE-AG-Aktie-DE0006055007", "DE0006055007-AG.html"); 

在我的Windows機器上,該代碼運行正常。在Linux機器上,它返回一個500內部服務器錯誤。 這是跟蹤文件trace.txt的開始:

== Info: About to connect() to www.onvista.de port 80 (#0)<br> 
== Info: Trying 217.11.205.10... == Info: connected<br> 
== Info: Connected to www.onvista.de (217.11.205.10) port 80 (#0)<br> 
=> Send header, 130 bytes (0x82)<br> 
0000: 47 45 54 20 2f 61 6b 74 69 65 6e 2f 66 75 6e 64 GET /aktien/fund<br> 
0010: 61 6d 65 6e 74 61 6c 2f 31 53 54 2d 52 45 44 2d amental/1ST-RED-<br> 
0020: 41 47 2d 41 6b 74 69 65 2d 44 45 30 30 30 36 30 AG-Aktie-DE00060<br> 
0030: 35 35 30 30 37 0d 20 48 54 54 50 2f 31 2e 31 0d 55007. HTTP/1.1.<br> 
0040: 0a 48 6f 73 74 3a 20 77 77 77 2e 6f 6e 76 69 73 .Host: www.onvis<br> 
0050: 74 61 2e 64 65 0d 0a 41 63 63 65 70 74 3a 20 2a ta.de..Accept: *<br> 
0060: 2f 2a 0d 0a 55 73 65 72 2d 41 67 65 6e 74 3a 20 /*..User-Agent: <br> 
0070: 53 6f 6d 65 2d 41 67 65 6e 74 2f 31 2e 30 0d 0a Some-Agent/1.0..<br> 
0080: 0d 0a           ..<br> 
<= Recv header, 36 bytes (0x24)<br> 
0000: 48 54 54 50 2f 31 2e 31 20 35 30 30 20 49 6e 74 HTTP/1.1 500 Int<br> 
0010: 65 72 6e 61 6c 20 53 65 72 76 65 72 20 45 72 72 ernal Server Err<br> 
0020: 6f 72 0d 0a <br> 

窗戶之間的唯一區別跟蹤和這個人是文件名(在DE0006055007結束後CR字符怎麼到達那裏,哪能抑制它?(不,我不想使用PHP cURL模塊導致其他問題。)

+0

你可以嘗試在'$ url'上調用[escapeshellarg](http://php.net/manual/en/function.escapeshellarg.php)嗎? – 2015-02-05 15:32:31

回答

0

你得到的http頭以\r\n結尾,在linux上看起來curl將它們轉換爲\n如果它檢測到輸出是tty,但嘗試重定向到一個文件,您將看到\r s。

.preg_match也匹配\r字符,所以它成爲$location[1]的一部分。簡單的解決辦法是trim吧。

這不會發生在Windows上,因爲您可以執行curl -i "http://google.com。報價由換行符後的shell自動結束。

而你應該真的使用escapeshellarg

+0

謝謝,Marek。我從未意識到這一點。匹配\ r - 我認爲它只匹配可打印的字符(在ord 31之上)。我替換了。與[^ \ s],現在它工作。 – user4532389 2015-02-05 16:52:23