note 85345 added to function.stream-socket-client

From: Date: Tue, 26 Aug 2008 22:34:21 +0000
Subject: note 85345 added to function.stream-socket-client
Groups: php.notes 
Request: Send a blank email to php-notes+get-143849@lists.php.net to get a copy of this message
I came here since fsockopen() does not support any SSL certificate checking in PHP5. while curl is nice, I use stream_socket_client() to make XML-RPC POST requests via HTTPS and since I have not found any PHP code around that does this, I'll attach an example that also includes HTTP-Digest Auth (eg. trac's WikiRPCInterface2): <?php ################################################# # $host: hostname ; eg 'example.org' # $path: request' eg '/index.php?id=123' # $data_to_send : data to POST after the HTTP header. # # if $opts is an empty array() a standard HTTP to port 80 request is performed. # # set auth['type']='basic' to use plain-text auth, # digest-auth will be handled automatically if $auth['username'] is set and a 401 # status is encountered. - use auth['type']='nodigest' to override. # ## function httpPost($host, $path, $data_to_send, $opts=array('cert'=>"", 'headers'=>0, 'transport' =>'ssl', 'port'=>443), $auth=array('username'=>"", 'password'=>"", 'type'=>"") ) { $transport=''; $port=80; if (!empty($opts['transport'])) $transport=$opts['transport']; if (!empty($opts['port'])) $port=$opts['port']; $remote=$transport.'://'.$host.':'.$port; $context = stream_context_create(); $result = stream_context_set_option($context, 'ssl', 'verify_host', true); if (!empty($opts['cert'])) { $result = stream_context_set_option($context, 'ssl', 'cafile', $opts['cert']); $result = stream_context_set_option($context, 'ssl', 'verify_peer', true); } else { $result = stream_context_set_option($context, 'ssl', 'allow_self_signed', true); } $fp = stream_socket_client($remote, $err, $errstr, 60, STREAM_CLIENT_CONNECT, $context); if (!$fp) { trigger_error('httpPost error: '.$errstr); return NULL; } $req=''; $req.="POST $path HTTP/1.1\r\n"; $req.="Host: $host\r\n"; if ($auth['type']=='basic' && !empty($auth['username'])) { $req.="Authorization: Basic "; $req.=base64_encode($auth['username'].':'.$auth['password'])."\r\n"; } elseif ($auth['type']=='digest' && !empty($auth['username'])) { $req.='Authorization: Digest '; foreach ($auth as $k => $v) { if (empty($k) || empty($v)) continue; if ($k=='password') continue; $req.=$k.'="'.$v.'", '; } $req.="\r\n"; } $req.="Content-type: text/xml\r\n"; $req.='Content-length: '. strlen($data_to_send) ."\r\n"; $req.="Connection: close\r\n\r\n"; fputs($fp, $req); fputs($fp, $data_to_send); while(!feof($fp)) { $res .= fgets($fp, 128); } fclose($fp); if ($auth['type']!='nodigest' && !empty($auth['username']) && $auth['type']!='digest' # prev. digest AUTH failed. && preg_match("/^HTTP\/[0-9\.]* 401 /", $res)) { if (1 == preg_match("/WWW-Authenticate: Digest ([^\n\r]*)\r\n/Us", $res, $matches)) { foreach (split(",", $matches[1]) as $i) { $ii=split("=",trim($i),2); if (!empty($ii[1]) && !empty($ii[0])) { $auth[$ii[0]]=preg_replace("/^\"/",'', preg_replace("/\"$/",'', $ii[1])); } } $auth['type']='digest'; $auth['uri']='https://'.$host.$path; $auth['cnonce']=randomNonce(); $auth['nc']=1; $a1=md5($auth['username'].':'.$auth['realm'].':'.$auth['password']); $a2=md5('POST'.':'.$auth['uri']); $auth['response']=md5($a1.':' .$auth['nonce'].':'.$auth['nc'].':' .$auth['cnonce'].':'.$auth['qop'].':'.$a2); return httpPost($host, $path, $data_to_send, $opts, $auth); } } if (1 != preg_match("/^HTTP\/[0-9\.]* ([0-9]{3}) ([^\r\n]*)/", $res, $matches)) { trigger_error('httpPost: invalid HTTP reply.'); return NULL; } if ($matches[1] != '200') { trigger_error('httpPost: HTTP error: '.$matches[1].' '.$matches[2]); return NULL; } if (!$opts['headers']) { $res=preg_replace("/^.*\r\n\r\n/Us",'',$res); } return $res; } ?> ---- Server IP: 213.249.64.162 Probable Submitter: 86.80.7.231 ---- Manual Page -- http://www.php.net/manual/en/function.stream-socket-client.php Edit -- https://master.php.net/note/edit/85345 Del: integrated -- https://master.php.net/note/delete/85345/integrated Del: useless -- https://master.php.net/note/delete/85345/useless Del: bad code -- https://master.php.net/note/delete/85345/bad+code Del: spam -- https://master.php.net/note/delete/85345/spam Del: non-english -- https://master.php.net/note/delete/85345/non-english Del: in docs -- https://master.php.net/note/delete/85345/in+docs Del: other reasons-- https://master.php.net/note/delete/85345 Reject -- https://master.php.net/note/reject/85345 Search -- https://master.php.net/manage/user-notes.php

« previous php.notes (#143849) next »