0) foreach ($urlsockets as $k => $v) if ($v['lastused'] < (time()-8)) close_url_socket($k); if (isset($urlsockets[$hostport])) { $streaminfo = stream_get_meta_data($urlsockets[$hostport]['handle']); if (($urlsockets[$hostport]['lastused'] < (time()-9)) || ($streaminfo['timed_out']) || ($urlsockets[$hostport]['hits'] >= 100)) { if ($dodebug) echo "\n".Date('H:i:s')." Socket to $hostport expired, closing first"; close_url_socket($hostport); } else { if ($dodebug) echo "\n".Date('H:i:s')." Reusing socket to $hostport"; $handle = $urlsockets[$hostport]['handle']; if (fputs($handle, ($topost==''?'GET ':'POST ').$path." HTTP/1.1\r\n") === false) { if ($dodebug) echo "\n".Date('H:i:s')." Write failed to reused socket"; close_url_socket($hostport); unset($handle); } } } if (!isset($handle)) { if ($dodebug) echo "\n".Date('H:i:s')." Opening socket to $hostport"; if (!isset($opencounts[$hostport])) $opencounts[$hostport] = 0; $opencounts[$hostport]++; if ($opencounts[$hostport] > 4) sleep(1.5); if (($handle = fsockopen(($https?'ssl://':'').$host, $port, $errno, $errstr,6)) === false) { if ($dodebug) echo "\n".Date('H:i:s').' Socket open failed: '.$errstr; $header = ''; unset($handle); } else { if ($dodebug) echo "\n".Date('H:i:s').' Socket open successful.'; fputs($handle, ($topost==''?'GET ':'POST ').$path." HTTP/1.1\r\n"); } } if (isset($handle)) { $sendheaders = 'Host: '.$host."\r\n"; $sendheaders .= $addlheaders; if (stripos($addlheaders,'User-Agent: ') === false) $sendheaders .= "User-Agent: Mozilla/5.0 Gecko Firefox/2.0.0.3\r\n"; if ($topost != '') { if (stripos($addlheaders,'Content-Type: ') === false) $sendheaders .= "Content-Type: application/x-www-form-urlencoded\r\n"; $sendheaders .= "Content-Length: ".strlen($topost)."\r\n"; } if (!$nogzip) { if ($dodebug) echo "\n".Date("H:i:s")." Allowing gzip on this ".($topost==''?'GET ':'POST '); $sendheaders .= "Accept-Encoding: gzip\r\n"; } $cookieset = ''; foreach ($cookies as $cookie) { if ((strtolower(substr($host, -1 * strlen($cookie['domain']))) == strtolower($cookie['domain'])) && (substr($path, 0, strlen($cookie['path'])) == $cookie['path'])) { //if ($dodebug) echo "\n".Date("H:i:s")." Cookie: ".$cookie['VALUE']; $cookieset .= (($cookieset=='')?'':'; ').$cookie['VALUE']; } } if ($cookieset != '') { if ($dodebug) echo "\n".Date("H:i:s")." Cookie: ".$cookieset; $sendheaders .= "Cookie: ".$cookieset."\r\n"; } //else if ($host == 'eu.wowarmory.com') fputs($handle, "Cookie: loginChecked=1\r\n"); if ($etag != '') $sendheaders .= "If-None-Match: $etag\r\n"; $sendheaders .= "Connection: Keep-Alive\r\n"; if ($dodebug) echo "\n".Date("H:i:s")." Outgoing headers:\n".str_replace("\r",'',$sendheaders); fputs($handle, $sendheaders."\r\n"); if ($topost != '') fputs($handle, $topost); if ($dodebug) echo "\n".Date("H:i:s")." Starting reads, path: $path"; $gotheaders = false; $inchunks = false; $isgzipped = false; $header = ''; $filedata = ''; $chunksize = 8192; $datalength = 0; $speedtime = microtime(true); $readstarttime = time(); //$debugfile = tempnam('/tmp','geturlold.output.'); do { stream_set_timeout($handle, 10); stream_set_blocking($handle, false); if (!$gotheaders) { $_data = fgets($handle); //file_put_contents($debugfile, $_data, FILE_APPEND); $_data = trim($_data); if ($_data != '') { $header .= $_data."\r\n"; $readstarttime = time(); } else usleep(10000); if (($header != '') && ($_data == '')) { $gotheaders = true; $prevheader = $header; $inchunks = (strpos(strtolower($header), 'transfer-encoding: chunked') !== FALSE); $isgzipped = (strpos(strtolower($header), 'content-encoding: gzip') !== FALSE); $cnt = preg_match('/Content-Length: *([0-9]+)/i',$header,$mc); $datalength=($cnt>0)?intval($mc[1]):0; if ($dodebug) echo "\n".Date("H:i:s")." Got header:\n$header"; } } else { if ($inchunks) { do { $_data = fgets($handle); //file_put_contents($debugfile, $_data, FILE_APPEND); $curline = trim($_data); if (strpos($curline, ';') !== FALSE) $curline = trim(substr($curline, 0, strpos($curline, ';'))); if ($curline != '') $readstarttime = time(); else usleep(10000); if ((time() - $readstarttime) >= 8) $curline = '0'; } while ($curline == ''); // && isset($_data{0})); if ((strlen($curline) > 8) || (preg_match('/[^a-f0-9]/i',$curline) > 0)) { $header = ''; $isgzipped = false; $filedata = ''; if ($dodebug) echo "\n".Date("H:i:s")." Bad chunk size! Length: ".strlen($curline); break; } $chunksize = hexdec($curline); // if ($dodebug) echo "\n".Date("H:i:s")." Chunk size: $chunksize"; } else if ($datalength > 0) $chunksize = min(8192, $datalength - strlen($filedata)); else $chunksize = 8192; if ($chunksize > 0) { $_data = ''; $readsuccess = false; // if ($dodebug) echo "\n".Date("H:i:s")." Read ".strlen($_data)." of $chunksize"; do { $readsuccess = ($_data .= fread($handle, $chunksize-strlen($_data))); if ($_data != '') { // if ($dodebug) echo "\n".Date("H:i:s")." Read ".strlen($_data)." of $chunksize"; $readstarttime = time(); } else usleep(10000); if ((time() - $readstarttime) >= 8) break; } while ($inchunks && (($chunksize-strlen($_data)) > 0) && (!feof($handle)) && ($readsuccess !== false)); //file_put_contents($debugfile, $_data, FILE_APPEND); $filedata .= $_data; } } if ((time() - $readstarttime) >= 8) { $header = ''; $isgzipped = false; if ($dodebug) echo "\n".Date("H:i:s")." Read timeout"; break; } } while ((!$gotheaders) || ($inchunks && ($chunksize > 0)) || (strlen($filedata) < $datalength)); if ($dodebug) echo "\n".Date("H:i:s")." Reads complete. ".strlen($filedata).' bytes'; if ($dodebug && (microtime(true) > $speedtime)) echo ' at '.round(strlen($filedata)/(microtime(true)-$speedtime)/1024,2).'kBps'; if ($dodebug) echo "\n".Date("H:i:s")." Saving handle to $hostport"; $urlsockets[$hostport]['handle'] = $handle; $urlsockets[$hostport]['lastused'] = time(); if (isset($urlsockets[$hostport]['hits'])) { $urlsockets[$hostport]['hits']++; } else $urlsockets[$hostport]['hits'] = 1; if (strpos(strtolower($header), 'connection: close') !== FALSE) { if ($dodebug) echo "\n".Date("H:i:s")." Closing connection as requested"; close_url_socket($hostport); } $cc = preg_match_all('/\n\s*Set-Cookie: ([^\n\r]+)/i', $header, $cres); if ($cc > 0) { if ($dodebug) echo "\n".Date("H:i:s")." Parsing $cc cookies"; for ($x = 0; $x < $cc; $x++) { $cook = array(); $cparts = explode(';',$cres[1][$x]); $cook['VALUE'] = $cparts[0]; $cook['domain'] = $host; $cook['path'] = substr($path, 0, strrpos($path,'/')); for ($y = 1; $y < count($cparts); $y++) { $cparts[$y] = trim($cparts[$y]); if (strpos($cparts[$y],'=')===false) { $cook[strtolower($cparts[$y])] = true; continue; } $cparts[$y] = explode('=',$cparts[$y],2); $cook[strtolower($cparts[$y][0])] = $cparts[$y][1]; } for ($y = 0; $y < count($cookies); $y++) if ((substr($cookies[$y]['VALUE'], 0, strpos($cookies[$y]['VALUE'],'='))==substr($cook['VALUE'], 0, strpos($cook['VALUE'],'='))) && ($cook['domain'] == $cookies[$y]['domain']) && ($cook['path'] == $cookies[$y]['path'])) { if (strpos($cook['VALUE'],'=') == (strlen($cook['VALUE'])-1)) { if ($dodebug) echo "\n".Date("H:i:s")." Removing cookie: ".serialize($cook); array_splice($cookies, $y, 1); } else { if ($dodebug) echo "\n".Date("H:i:s")." Updating cookie: ".serialize($cook); array_splice($cookies, $y, 1, array($cook)); } unset($cook); break; } if (isset($cook)) { if ($dodebug) echo "\n".Date("H:i:s")." Adding cookie: ".serialize($cook); $cookies[] = $cook; unset($cook); } } //if ($dodebug) print_r($cookies); } } $etag = (preg_match('/[\r\n]ETag: ?([^\r\n]+)[\r\n]/',$header,$res) > 0)?$res[1]:$etag; switch ((preg_match('/\b\d\d\d\b/',$header,$res) > 0)?$res[0]:'500') { case '301': //moved permanently case '302': //found case '303': //see other case '307': //temporary redirect $newloc = (preg_match('/Location: ([^\n\r]+)[\n\r]/',$header,$res) > 0)?$res[1]:''; if ($newloc == '') { if ($dodebug) echo "\n".Date("H:i:s")." Bad header, 302 without Location"; array_pop($urlstack); return ''; } if (preg_match('/^http(s)?:\/\//',$newloc) == 0) $newloc = 'http'.($https?'s':'').'://'.$hostport.$newloc; if ($dodebug) echo "\n".Date("H:i:s")." Redirect to $newloc"; $ret = get_url_old($newloc); array_pop($urlstack); return $ret; case '304': //not modified //array_pop($urlstack); if ($dodebug) echo "\n".Date("H:i:s")." Good header, 304 not modified"; //return $filedata; case '200': //ok case '201': //created case '202': //accepted case '203': //non-authoritative case '204': //no content case '205': //reset content' array_pop($urlstack); if ($dodebug) echo "\n".Date("H:i:s")." Good header"; if ($isgzipped && (strlen($filedata) > 0)) { if ($dodebug) echo "\n".Date("H:i:s")." Was gzipped, extracting"; $filedata2 = mygzuncompress($filedata); if ($filedata2 == '') { $filedata = ''; if ($dodebug) echo "\n".Date("H:i:s")." Couldn't ungzip"; if ((!$nogzip) && ($topost == '')) { if ($dodebug) echo ", retrying w/o gzip"; array_pop($urlstack); $nogzip = true; $filedata2 = get_url_old($url); $nogzip = false; array_push($urlstack,$url); $header = $prevheader; if ($filedata2 != '') if ($dodebug) echo "\n".Date("H:i:s")." Data returned without gzip"; } } else if ($dodebug) echo "\n".Date("H:i:s")." Ungzip successful. ".strlen($filedata)." -> ".strlen($filedata2).", ".round(strlen($filedata)/strlen($filedata2)*100,1).'%'; $filedata = $filedata2; } return $filedata; default: array_pop($urlstack); if ($dodebug) echo "\n".Date("H:i:s")." Bad header"; if ($dodebug && (strlen($filedata) < 1025)) { if ($isgzipped) { //if ($dodebug) echo "\n".Date("H:i:s")." Was gzipped, extracting"; $filedata2 = mygzuncompress($filedata); if ($filedata2 == '') { $filedata = ''; if ($dodebug) echo "\n".Date("H:i:s")." Couldn't ungzip"; if ((!$nogzip) && ($topost == '')) { if ($dodebug) echo ", retrying w/o gzip"; array_pop($urlstack); $nogzip = true; $filedata2 = get_url_old($url); $nogzip = false; array_push($urlstack,$url); $header = $prevheader; if ($filedata2 != '') if ($dodebug) echo "\n".Date("H:i:s")." Data returned without gzip"; } } //else if ($dodebug) echo "\n".Date("H:i:s")." Ungzip successful"; $filedata = $filedata2; } if (strlen($filedata) < 1025) echo "\n$filedata\n"; } if (isset($urlsockets[$hostport])) close_url_socket($hostport); return ''; } } function close_url_socket($host) { global $urlsockets,$dodebug; if (isset($urlsockets[$host])) { if ($dodebug) echo "\n".Date("H:i:s")." Closing socket to $host"; @fclose($urlsockets[$host]['handle']); unset($urlsockets[$host]); } } function getItem($itm) { $fs = get_url_old('http://us.battle.net/api/wow/item/'.$itm); if (($fs != '') && (preg_match('/"id":'.$itm.'\b/',$fs) > 0)) { $json = json_decode($fs, true, 10); return $json; } return $fs; } function mygzuncompress($d) { if (substr($d,0,3) != (chr(31).chr(139).chr(8))) return ''; $flags = ord(substr($d,3,1)); $fhcrc = ($flags & 2 > 0); $fextra = ($flags & 4 > 0); $fname = ($flags & 8 > 0); $fcomment = ($flags & 16 > 0); $datastart = 10; if ($fextra) $datastart += ord(substr($d,$datastart,1)) + (256 * ord(substr($d,$datastart,2))) + 2; if ($fname) while (substr($d,$datastart++,1) != "\0"); if ($fcomment) while (substr($d,$datastart++,1) != "\0"); if ($fhcrc) $datastart += 2; $cb = substr($d, $datastart, -8); return gzinflate($cb); } ini_set('memory_limit','192M'); $dodebug=true; error_reporting(E_ALL); function filejssortcmp($a,$b) { if ($a->lastModified == $b->lastModified) return 0; return (floatval($a->lastModified) <= floatval($b->lastModified)) ? -1 : 1; } function client1() { // this function isn't complete because it has lots of other magic // however, this is all the code that touches the battle.net API global $dodebug; // hey look: $realmrow is a database row with some basic realm information. the array keys should be clues. $curlm = floatval($realmrow['lastmodified']); if ($dodebug) echo "\n".Date('H:i:s')." Getting URL for ".$realmrow['slug']; $etagret = ''; $filejs = get_url_old('https://'.strtolower($realmrow['realmset']).'.battle.net/api/wow/auction/data/'.urlencode($realmrow['slug']), '', $etagret, getauthheader('/api/wow/auction/data/'.urlencode($realmrow['slug']))); if ($filejs != '') { $bytes += strlen($filejs); $json = json_decode($filejs); if (isset($json->files) && (count($json->files) > 0)) { uasort($json->files,'filejssortcmp'); $fil = array_pop($json->files); if ($fil->lastModified <= $curlm) { return; } } else return; } else return; unset($filejs); unset($json); $fil->url = preg_replace('/^http:/','https:',$fil->url); if ($dodebug) echo "\n".Date('H:i:s')." Pulling ".$fil->url; $authheader = getauthheader(parse_url($fil->url,PHP_URL_PATH)); $jsonstr = get_url_old($fil->url, '', $etagret, $authheader); if ($jsonstr != '') { $bytes += strlen($jsonstr); if (substr($jsonstr,0,3) == (chr(31).chr(139).chr(8))) $jsonstr = mygzuncompress($jsonstr); $json = json_decode($jsonstr,true,12); if ($dodebug) switch (json_last_error()) { case JSON_ERROR_DEPTH: echo "\n".Date('H:i:s')." JSON Error: Max stack depth exceeded"; break; case JSON_ERROR_STATE_MISMATCH: echo "\n".Date('H:i:s')." JSON Error: Underflow or the modes mismatch"; break; case JSON_ERROR_CTRL_CHAR: echo "\n".Date('H:i:s')." JSON Error: Unexpected control character found"; break; case JSON_ERROR_SYNTAX: echo "\n".Date('H:i:s')." JSON Error: Syntax error, malformed JSON"; break; case JSON_ERROR_UTF8: echo "\n".Date('H:i:s')." JSON Error: Malformed UTF-8 characters"; break; case JSON_ERROR_NONE: break; default: echo "\n".Date('H:i:s')." JSON Error: Unknown error"; break; } unset($jsonstr); // $json is now a multi-dimensional array with the auction data in the source json's format } } function hmacsha1($key,$data) { $blocksize=64; $hashfunc='sha1'; if (strlen($key)>$blocksize) $key=pack('H*', $hashfunc($key)); $key=str_pad($key,$blocksize,chr(0x00)); $ipad=str_repeat(chr(0x36),$blocksize); $opad=str_repeat(chr(0x5c),$blocksize); $hmac = pack( 'H*',$hashfunc( ($key^$opad).pack( 'H*',$hashfunc( ($key^$ipad).$data ) ) ) ); return $hmac; } function getauthheader($urlpath) { global $dodebug; $pubkey = 'STUFF FROM BLIZZARD HERE'; $privkey = 'MORE STUFF FROM BLIZZARD HERE'; $dt = date_format(date_create('now',timezone_open('GMT')),'D, d M Y H:i:s').' GMT'; $tosign = "GET\n$dt\n$urlpath\n"; $sig = base64_encode(hmacsha1($privkey,$tosign)); $headrs = "Date: $dt\r\nAuthorization: BNET $pubkey:$sig\r\n"; if ($dodebug) echo "\n".Date('H:i:s')." Auth headers for $urlpath are\n".str_replace("\r",'',$headrs); return $headrs; } ?>