/** * Send request to remote server * * @param string $method Either REGISTER, NOTIFY * @param mixed $data Data block to send * @param bool $callback (optional) Socket callback request * * @return Net_Growl_Response | TRUE * @throws Net_Growl_Exception if remote server communication failure */ protected function sendRequest($method, $data, $callback = false) { // @codeCoverageIgnoreStart $protocol = $this->options['protocol'] == 'udp' ? 'udp' : 'tcp'; $addr = $protocol . '://' . $this->options['host']; $this->debug($addr . ':' . $this->options['port'] . ' ' . $this->options['timeout']); // open connection if (is_array($this->options['context']) && function_exists('stream_context_create')) { $context = stream_context_create($this->options['context']); if (function_exists('stream_socket_client')) { $flags = STREAM_CLIENT_CONNECT; $addr = $addr . ':' . $this->options['port']; $sh = @stream_socket_client($addr, $errno, $errstr, $this->options['timeout'], $flags, $context); } else { $sh = @fsockopen($addr, $this->options['port'], $errno, $errstr, ${$this}->options['timeout'], $context); } } else { $sh = @fsockopen($addr, $this->options['port'], $errno, $errstr, ${$this}->options['timeout']); } if ($sh === false) { $this->debug($errstr, 'error'); $error = 'Could not connect to Growl Server.'; throw new Net_Growl_Exception($error); } stream_set_timeout($sh, $this->options['timeout'], 0); $this->debug($data); /** @noinspection PhpParamsInspection */ $res = fwrite($sh, $data, $this->strByteLen($data)); if ($res === false) { $error = 'Could not send data to Growl Server.'; throw new Net_Growl_Exception($error); } switch ($protocol) { case 'tcp': // read GNTP response $line = $this->_readLine($sh); $this->debug($line); $response = new Net_Growl_Response($line); $statusOK = $response->getStatus() == 'OK'; while ($this->strByteLen($line) > 0) { $line = $this->_readLine($sh); $response->appendBody($line . "\r\n"); if (is_resource($this->_fp)) { $this->debug($line); } } if ($statusOK && $callback === true && $method == 'NOTIFY') { // read GNTP socket Callback response $line = $this->_readLine($sh); $this->debug($line); if (preg_match('/^GNTP\\/1.0 -(\\w+).*$/', $line, $resp)) { $res = $resp[1] == 'CALLBACK'; if ($res) { while ($this->strByteLen($line) > 0) { $line = $this->_readLine($sh); $this->debug($line); $eon = true; $nid = preg_match('/^Notification-ID: (.*)$/', $line, $resp); if ($nid) { $eon = false; } $ncr = preg_match('/^Notification-Callback-Result: (.*)$/', $line, $resp); if ($ncr) { $this->growlNotificationCallback[] = $resp[1]; $eon = false; } $ncc = preg_match('/^Notification-Callback-Context: (.*)$/', $line, $resp); if ($ncc) { $this->growlNotificationCallback[] = $resp[1]; $eon = false; } $ncct = preg_match('/^Notification-Callback-Context-Type: (.*)$/', $line, $resp); if ($ncct) { $this->growlNotificationCallback[] = $resp[1]; $eon = false; } $nct = preg_match('/^Notification-Callback-Timestamp: (.*)$/', $line, $resp); if ($nct) { $this->growlNotificationCallback[] = $resp[1]; $eon = false; } if ($eon) { break; } } } } if (is_resource($this->_fp)) { while ($this->strByteLen($line) > 0) { $line = $this->_readLine($sh); $this->debug($line); } } } break; case 'udp': $statusOK = $response = true; break; } switch (strtoupper($method)) { case 'REGISTER': if ($statusOK) { $this->isRegistered = true; } break; case 'NOTIFY': if ($statusOK) { $this->growlNotificationCount++; } break; } // close connection fclose($sh); return $response; // @codeCoverageIgnoreEnd }
/** * Creates a new Net_Growl_Response object from a file * * @param resource $fp File pointer returned by fopen() * * @return Net_Growl_Response */ protected function createResponseFromFile($fp) { $response = new Net_Growl_Response(fgets($fp)); while (!feof($fp)) { $response->appendBody(fread($fp, 8192)); } return $response; }