https://〜/へリクエストを投げる事。
サーバー側プログラムは通常通り標準出力すれば、apache等のwebサーバーが勝手にSSLで処理してくれます。
モジュール | バージョン |
cURL | 7.13.0(2005-02-18 (金) 16:18:09) |
PEAR Net_Curl | 0.2(stable) / 1.0.1(beta)2005-02-18 (金) 16:39:06 |
0.2と1.0.1betaがあるが、最新の1.0.1betaで実験してみる。
内部でcURLを呼んでいるようなので、cURLが必要。
pear install Net_Curl-beta
fsockopen()で行う場合。
PHPのBugがあるので注意。
<?php /** * @file * @brief HTTP関係クラス */ /** * HTTPリクエストの送信(GET, POST, SSL, NameVirtualHost, Basic認証対応) * * @param string $url URL ex: http://example.com:80/path/to, https://example.com:443/path/to, tls://example.com:443/path/to * @param array $options * 'content' => array('key'=>'value'), 送信データ * 'method' => 'GET' or 'POST' デフォルト:'GET' * 'header' => array( 'User-Agent:' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)' ), httpヘッダ * 'host' => 'IPアドレス', (省略可。ネームベースのバーチャルホストで特定のサーバにアクセスしたい場合は、IPアドレスを指定) * 'time_limit' => 10, (タイムアウト秒数。省略可。デフォルト10秒) * 'errno' => エラーがある場合はエラー番号, * 'errstr' => エラーがある場合はエラー文字列, * @return array list($head, $body) * * @note * - file_get_contents()では Location:ヘッダ + bodyがあった場合にリダイレクトされ、bodyを取得できない。この関数はリダイレクトしないため、bodyを取得できる。 * - 例 * - GET:list($head, $body) = httpRequest("http://example.com/path/to?key1=val1", $options); * - GET: @code $options = array('method'=>'get', 'content'=>array('key1' => 'val1') ); list($head, $body) = httpRequest("http://example.com/path/to", $options); @endcode * - GET(SSL): @code $options = array('method'=>'get', 'content'=>array('key1' => 'val1') ); list($head, $body) = httpRequest("https://example.com/path/to", $options); @endcode * - POST: @code $options = array('method'=>'post', 'content'=>array('key1' => 'val1') ); list($head, $body) = httpRequest("http://example.com/path/to", $options); @endcode * - エラーの判定 @code list($head, $body) = httpRequest("http://example.com/path/to", $options); if($options['errno'] != 0){ // エラー処理 echo $options['errstr'] . "\n"; } @endcode * - NameVirtualHostの特定ホストにリクエストを送る @code $options = array('host'=>'xxx.xxx.xxx.xxx'); list($head, $body) = httpRequest("http://example.com/path/to", $options); @endcode * - GET: 8080ポートを指定 @code $options = array('method'=>'get', 'content'=>array('key1' => 'val1') ); list($head, $body) = httpRequest("http://example.com:8080/path/to", $options); @endcode * - basic認証 @code list($head, $body) = httpRequest("http://username:password@example.com/path/to", $options); @endcode * - 任意のhttpヘッダを送信する @code $options = array( 'header'=>array('User-Agent:' => "PHP/".phpversion() ) ); list($head, $body) = httpRequest("http://username:password@example.com/path/to", $options); @endcode */ function httpRequest($url, &$options) { $_options = array( 'content' => '', // postデータ 'method' => 'GET', // 'post' or 'get' 'header' => array( 'Accept-Language:' => 'ja', 'User-Agent:' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)', // IE7 or "User-Agent: PHP/".phpversion()."\r\n"; ), 'host' => '', 'time_limit' => 10, ); $options['errno'] = -1; $options['errstr'] = ''; $_options = array_merge($_options, $options); $url = trim($url); $purl = parse_url($url); $purl['scheme'] = strtolower($purl['scheme']); switch($purl['scheme']){ case 'http': $purl['scheme'] = ''; $purl['port'] = ($purl['port'] != '') ? $purl['port'] : 80; break; case 'https': $purl['scheme'] = 'ssl://'; $purl['port'] = ($purl['port'] != '') ? $purl['port'] : 443; break; case 'tls': $purl['scheme'] = 'tls://'; $purl['port'] = ($purl['port'] != '') ? $purl['port'] : 443; break; default: break; } // Build the request string $request = ''; if($_options['content'] != ''){ if(is_array($_options['content'])){ $request = http_build_query($_options['content']); }else{ $request = $_options['content']; } } if (isset($purl["query"])) { $request .= ($request == '') ? $purl["query"] : '&'.$purl["query"]; } if($_options['host'] != ''){ // ホストが指定されている場合 $purl["host"] = $_options['host']; } $request_length = strlen($request); // Build the header $_options['method'] = strtoupper($_options['method']); $header = ''; $x_header = ''; if( is_array($_options['header']) ){ foreach($_options['header'] as $key => $val){ if(!preg_match("/\:$/",$key) ) $key .= ':'; $x_header .= sprintf("%s %s\r\n", $key, $val); } }else{ $x_header = $_options['header']; if(!preg_match("/\r\n$/",$x_header) ) $x_header .= "\r\n"; } switch($_options['method']){ case 'POST': $header .= "POST {$purl["path"]} HTTP/1.0\r\n"; $header .= "Host: {$purl["host"]}\r\n"; $header .= $x_header; $header .= "Content-type: application/x-www-form-urlencoded\r\n"; $header .= "Content-length: {$request_length}\r\n"; break; case 'GET': $header .= "GET {$purl["path"]}?$request HTTP/1.0\r\n"; $header .= "Host: {$purl["host"]}\r\n"; $header .= $x_header; $request = ''; break; default: $header .= "$method {$purl["path"]} HTTP/1.0\r\n"; $header .= "Host: {$purl["host"]}\r\n"; $header .= $x_header; break; } // Basic認証用ヘッダ if (isset($purl['user']) || isset($purl['pass'])) { $header .= "Authorization: Basic ".base64_encode($purl['user'].":".$purl['pass'])."\r\n"; } $header .= "\r\n"; // Open the connection $fp = @fsockopen($purl['scheme'] . $purl["host"], $purl["port"], $options['errno'], $options['errstr'], $_options['time_limit']); if (!$fp) { if ( $options['errno'] == 0 ){ $options['errno'] = 500; $options['errstr'] = 'fsockopen failed'; } return array(); } if(is_int($_options['time_limit'])) socket_set_timeout($fp, $_options['time_limit']); // Send everything fputs($fp, $header . $request); // Get the response $response = ''; while (!feof($fp)) { // PHP Bug #23220 「Warning: fgets(): SSL: fatal protocol error」の抑制 // file_get_contents()でも起こるようだ。 $response .= @fgets($fp, 4096); } fclose($fp); $fp = NULL; $DATA = split("\r\n\r\n", $response, 2); if(preg_match('#^HTTP/[\d\.]+\s+(\d+)[^\r\n]+#i', $DATA[0], $matches)){ $status_code = intval($matches[1]); if($status_code >= 200 && $status_code <= 299){ // 2xx Success }else if($status_code >= 300 && $status_code <= 399){ // 3xx Redirection }else{ $options['errno'] = $status_code; $options['errstr'] = $matches[0]; } } return $DATA; }