2013-06-06 47 views
10

Môi trường của chúng tôi yêu cầu sử dụng proxy gửi đi cho các dịch vụ ngoại vi. Thông thường đây không phải là vấn đề. Trong trường hợp này với Twilio, tiêu đề phụ được trả về sẽ phá vỡ ứng dụng khách.Việc cần làm với tiêu đề HTTP bổ sung từ proxy là gì?

tiêu đề Outgoing:

POST /2010-04-01/Accounts/FOO/SMS/Messages.json HTTP/1.1 
Authorization: Basic FOO== 
User-Agent: twilio-php/3.10.0 
Host: api.twilio.com 
Accept: */* 
Accept-Charset: utf-8 
Content-Type: application/x-www-form-urlencoded 
Content-Length: 108 

Tiêu đề phản hồi:

HTTP/1.0 200 Connection established 

HTTP/1.1 201 Created 
Server: nginx 
Date: Thu, 06 Jun 2013 14:39:24 GMT 
Content-Type: application/json; charset=utf-8 
Content-Length: 551 
Connection: close 
X-Powered-By: PHP/5.3.11 

Tôi chỉ có thể giả định proxy sẽ bổ sung các tiêu đề HTTP thêm.

Các Twilio khách hàng không kiểm tra:

list($head, $body) = ($parts[0] == 'HTTP/1.1 100 Continue') 

Theo tôi được biết, có những thời điểm hoặc các phiên bản của curl đó sẽ tự động thêm một Expect header trong các yêu cầu, và HTTP 100 sẽ được trả lại trong phản ứng, nhưng trong trường hợp này nó không phải là, và phản ứng là 200 kết nối được thiết lập. Đối với những gì nó có giá trị thêm một mong đợi rỗng: hoặc một mong đợi: thịt xông khói đã không thay đổi kết quả.

Tôi thực sự không muốn tấn công khách hàng Twilio quá nhiều ở đây, và tôi đặc biệt muốn tránh chỉ thêm một || $ parts [0] == 'Kết nối HTTP/1.0 200 được thiết lập' vì có vẻ như nó lộn xộn.

Có thể gửi tiêu đề yêu cầu trong đó sẽ chặn/ẩn tiêu đề bổ sung không? Hoặc, một tùy chọn curl tôi không thấy bỏ qua nó?

Proxy gửi đi là Linux/Squid

+1

điều này thực sự khiến tôi giật mình. –

+0

@TheSurrican đó là gì? – somedev

+0

theo đặc điểm kỹ thuật chỉ có một "dòng trạng thái" duy nhất trong phản hồi http, theo sau là các định nghĩa tiêu đề. nghĩa là, nếu tôi đọc chính xác ... http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6 –

Trả lời

13

Sự cố proxy là thứ mà nhiều tập lệnh đang gặp phải. Các giải pháp ưa thích tôi có thể tìm thấy trên internet là chỉ cần thêm các dòng mã sau đây.

<?php 
// cURL automatically handles Proxy rewrites, remove the "HTTP/1.0 200 Connection established" string 
if (false !== stripos($response, "HTTP/1.0 200 Connection established\r\n\r\n")) { 
    $response = str_ireplace("HTTP/1.0 200 Connection established\r\n\r\n", '', $response); 
} 
?> 

Bây giờ, việc thêm vào ứng dụng khách Twilio sẽ hơi lộn xộn một chút. May mắn là bạn có thể sử dụng không gian tên để tạo lại các hàm gốc. Xem ví dụ sau.

<?php 
namespace FakeCurl; 

//create curl_exec function with same name, but its created in the FakeCurl namespace now. 
function curl_exec($ch) { 
    //execute the actual curl_exec function in the main namespace 
    $response = \curl_exec($ch); 

    // cURL automatically handles Proxy rewrites, remove the "HTTP/1.0 200 Connection established" string 
    if (false !== stripos($response, "HTTP/1.0 200 Connection established\r\n\r\n")) { 
    $response = str_ireplace("HTTP/1.0 200 Connection established\r\n\r\n", '', $response); 
    } 

    return "ADDED TO RESPONSE\r\n\r\n".$response; 
} 

//make a regular curl request, no alterations. 

$curl = curl_init(); 
curl_setopt_array($curl, array(
    CURLOPT_HEADER => true, 
    CURLOPT_NOBODY => true, 
    CURLOPT_RETURNTRANSFER => true, 
    CURLOPT_URL => 'http://stackoverflow.com')); 
$response = curl_exec($curl); 
curl_close($curl); 

echo '<pre>'.$response.'</pre>'; 

?> 

Output

ADDED TO RESPONSE 

HTTP/1.1 200 OK 
Cache-Control: public, max-age=11 
Content-Length: 191951 
Content-Type: text/html; charset=utf-8 
Expires: Wed, 12 Jun 2013 07:09:02 GMT 
Last-Modified: Wed, 12 Jun 2013 07:08:02 GMT 
Vary: * 
X-Frame-Options: SAMEORIGIN 
Date: Wed, 12 Jun 2013 07:08:49 GMT 

Vì vậy, để sử dụng với khách hàng twilio, bạn cần phải đặt ở đầu rất của kịch bản của bạn như sau:

<?php 
namespace FakeCurl; 
function curl_exec($ch) { 
    $response = \curl_exec($ch); 

    // cURL automatically handles Proxy rewrites, remove the "HTTP/1.0 200 Connection established" string 
    if (false !== stripos($response, "HTTP/1.0 200 Connection established\r\n\r\n")) { 
    $response = str_ireplace("HTTP/1.0 200 Connection established\r\n\r\n", '', $response); 
    } 

    return $response; 
} 

include("twilio.php"); 
?> 

tùy chọn namespace nên thất bại cho một số lý do, tôi sẽ thêm một chức năng đơn giản bên ngoài khách hàng twilio như thế nào.

<?php 
function fixProxyResponse($response) { 
    // cURL automatically handles Proxy rewrites, remove the "HTTP/1.0 200 Connection established" string 
    if (false !== stripos($response, "HTTP/1.0 200 Connection established\r\n\r\n")) { 
    $response = str_ireplace("HTTP/1.0 200 Connection established\r\n\r\n", '', $response); 
    } 

    return $response; 
} 

Và sau đó thay đổi kịch bản twilio TinyHttp.php và thay đổi chỉ dòng sau (~ linenr 63)

if ($response = curl_exec($curl)) { 
    $parts = explode("\r\n\r\n", $response, 3); 
    list($head, $body) = ($parts[0] == 'HTTP/1.1 100 Continue') 

để

if ($response = curl_exec($curl)) { 
    $parts = explode("\r\n\r\n", fixProxyResponse($response), 3); 
    list($head, $body) = ($parts[0] == 'HTTP/1.1 100 Continue') 
+0

Phải đợi một giờ để nhận giải thưởng, nhưng cảm ơn. Bạn đã xác nhận suy nghĩ của tôi rằng tôi không thể thoát khỏi việc sửa đổi mã TinyHttp từ Twilio, và tôi sẽ tiếp tục và làm như vậy. – somedev

+1

Nó luôn luôn tốt để chờ đợi cho đến khi kết thúc tiền thưởng. Đôi khi mọi người đưa ra các giải pháp tuyệt vời khi nó ở đầu danh sách. –

+0

Điểm tốt, cảm ơn lần nữa – somedev

3

Một số rất muộn làm rõ. Khi bạn kết nối với máy chủ SSL/TLS thông qua proxy, proxy sẽ thiết lập đường hầm, sử dụng HTTP CONNECT. Điều này được bao gồm trong RFC2817 và hết hạn tunneling spec và không phải là RFC2616.

Thông số kỹ thuật đường hầm ban đầu yêu cầu proxy trả lại '200 kết nối được thiết lập' cho khách hàng sau khi kết nối thành công với máy chủ, đó là những gì bạn đang thấy. Điều này có khả năng được theo sau bởi nhiều tiêu đề hơn và sau đó là một dòng trống, trước khi kết nối trở nên trong suốt và bạn nhận được phản hồi thực tế từ máy chủ. Vì vậy, bạn nhận được hai bộ tiêu đề. RFC 2817 giải phóng điều này và cho phép bất kỳ phản hồi 2xx nào đối với yêu cầu CONNECT.

Tức là, trong ngắn hạn, bạn không thể dựa vào việc phát hiện và tước bỏ một dòng tiêu đề bằng cách sử dụng mã php ở trên. Có thể có nhiều hơn một dòng và dòng đầu tiên có thể không có mã 200 và có thể không bao gồm chuỗi 'kết nối được thiết lập'. Bạn phải chuẩn bị để phát hiện hai bộ tiêu đề đầy đủ.

cURL đã loại bỏ phản hồi kết nối ban đầu cho đến 7.11.1 trong năm 2004, nhưng bây giờ gửi mọi thứ lại cho khách hàng. Xem here để biết chi tiết.