function gda_worker_main() { global $init_shared; global $cmdfile; global $replyfile; $reply = new SimpleXMLElement("<reply></reply>"); $reply->addChild('session', htmlspecialchars(SID)); $reply->addChild('status', "OK"); $reply->addChild("counter", $_SESSION["counter"]); echo gda_add_hash($init_shared, $reply->asXml()); flush(); ob_flush(); /* set max execution time to 10s */ set_time_limit(10); while (1) { $doquit = false; try { if (!file_exists($cmdfile)) { throw new GdaException("Bad setup", true); } //echo "Reading from fifo...\n"; flush (); ob_flush(); $file = fopen($cmdfile, "r+"); stream_set_blocking($file, false); while (1) { $readers = array($file); if (stream_select($readers, $writers = null, $except = null, 5, 0) < 1) { /* More waiting... */ echo chr(0); flush(); ob_flush(); // send something to the client to test connection if (connection_status() != 0) { fclose($file); exit(0); break; } continue; } else { /* data available to read */ break; } } $datafile = fread($file, 8192); fclose($file); $text = file_get_contents($datafile); @unlink($datafile); if ($text == false) { throw new GdaException('Could not read command', false); } //echo "COMMAND [$datafile]\n"; flush (); ob_flush(); $array = split("\n", $text, 2); if (sizeof($array) != 2) { throw new GdaException('Missing message hash', true); } if ($array[0][0] == "<") { throw new GdaException('Bad message hash', true); } if ($array[0] != "NOHASH" || isset($_SESSION['key'])) { $hash = hmac($_SESSION['key'], $array[1]); if ($array[0] != $hash) { throw new GdaException('Bad message hash', true); } } if ($array[1][0] != "<") { throw new GdaException('Bad message format', true); } $xml = simplexml_load_string($array[1]); $retval = gda_handle_xml($xml, $doquit); /* send reply */ try { send_reply($retval); } catch (Exception $e) { /* will be caught by the listening thread */ echo $retval; } } catch (GdaException $e) { $reply = new SimpleXMLElement("<reply></reply>"); if (!$e->cnc_closed) { $chal = rand_str(); $_SESSION['challenge'] = $chal; $reply->addChild('challenge', $chal); if (isset($debug) && $debug) { $reply->addChild('session', htmlspecialchars(SID)); } $node = $reply->addChild('status', "ERROR"); } else { $_SESSION["cncclosed"] = true; $doquit = true; $node = $reply->addChild('status', "CLOSED"); } $node->addAttribute("error", $e->getMessage()); $reply->addChild("counter", $_SESSION["counter"]); if (isset($_SESSION['key'])) { $retval = gda_add_hash($_SESSION['key'], $reply->asXml()); } else { $retval = gda_add_hash("", $reply->asXml()); } try { send_reply($retval); } catch (Exception $e) { /* will be caught by the listening thread */ echo $retval; } } //echo "REPLY [$retval]\n"; flush(); ob_flush(); if ($doquit) { break; } } }
} // read $len bytes for the actual payload and assume it's a JSON object. $msg = fread($in, $len); $rq = json_decode($msg); // TODO validation - was it valid json? $pis = get_matches($rq); // don't reply with anything if there were no matches: if (count($pis) == 0) { continue; } $res = new stdclass(); $res->_msgtype = "results"; $res->qid = $rq->qid; $res->results = array(); $res->results = $pis; send_reply($res); } // put a 4-byte big-endian int first, denoting length of message function send_reply($obj) { // i think json_spirit rejects \/ even tho it's valid json. doh. $str = str_replace('\\/', '/', json_encode($obj)); print pack('N', strlen($str)); print $str; } // this might return multiple objects if it did a proper search: // for now it only matches one song because it's just a demo. function get_matches($rq) { global $magnatune; $tracks = @$magnatune[metaphone($rq->artist)][metaphone($rq->track)];