Пример #1
0
 /**
  * Sign and post the given Atom entry as a Salmon message.
  *
  * Side effects: may generate a keypair on-demand for the given user,
  * which can be very slow on some systems.
  *
  * @param string $endpoint_uri
  * @param string $xml string representation of payload
  * @param Profile $actor local user profile whose keys to sign with
  * @return boolean success
  */
 public function post($endpoint_uri, $xml, $actor)
 {
     if (empty($endpoint_uri)) {
         return false;
     }
     foreach ($this->formatClasses() as $class) {
         try {
             $envelope = $this->createMagicEnv($xml, $actor, $class);
         } catch (Exception $e) {
             common_log(LOG_ERR, "Salmon unable to sign: " . $e->getMessage());
             return false;
         }
         $headers = array('Content-Type: application/magic-envelope+xml');
         try {
             $client = new HTTPClient();
             $client->setBody($envelope);
             $response = $client->post($endpoint_uri, $headers);
         } catch (HTTP_Request2_Exception $e) {
             common_log(LOG_ERR, "Salmon ({$class}) post to {$endpoint_uri} failed: " . $e->getMessage());
             continue;
         }
         if ($response->getStatus() != 200) {
             common_log(LOG_ERR, "Salmon ({$class}) at {$endpoint_uri} returned status " . $response->getStatus() . ': ' . $response->getBody());
             continue;
         }
         // Success!
         return true;
     }
     return false;
 }
Пример #2
0
 function onStartNoticeSave($notice)
 {
     $args = $this->testArgs($notice);
     common_debug("Blogspamnet args = " . print_r($args, TRUE));
     $requestBody = xmlrpc_encode_request('testComment', array($args));
     $request = new HTTPClient($this->baseUrl, HTTPClient::METHOD_POST);
     $request->setHeader('Content-Type', 'text/xml');
     $request->setBody($requestBody);
     $httpResponse = $request->send();
     $response = xmlrpc_decode($httpResponse->getBody());
     if (xmlrpc_is_fault($response)) {
         throw new ServerException("{$response['faultString']} ({$response['faultCode']})", 500);
     } else {
         common_debug("Blogspamnet results = " . $response);
         if (preg_match('/^ERROR(:(.*))?$/', $response, $match)) {
             throw new ServerException(sprintf(_("Error from %s: %s"), $this->baseUrl, $match[2]), 500);
         } else {
             if (preg_match('/^SPAM(:(.*))?$/', $response, $match)) {
                 throw new ClientException(sprintf(_("Spam checker results: %s"), $match[2]), 400);
             } else {
                 if (preg_match('/^OK$/', $response)) {
                     // don't do anything
                 } else {
                     throw new ServerException(sprintf(_("Unexpected response from %s: %s"), $this->baseUrl, $response), 500);
                 }
             }
         }
     }
     return true;
 }
Пример #3
0
 /**
  * Sign and post the given Atom entry as a Salmon message.
  *
  * Side effects: may generate a keypair on-demand for the given user,
  * which can be very slow on some systems (like those without php5-gmp).
  *
  * @param string $endpoint_uri
  * @param string $xml string representation of payload
  * @param User $user local user profile whose keys we sign with
  * @return boolean success
  */
 public static function post($endpoint_uri, $xml, User $user)
 {
     if (empty($endpoint_uri)) {
         common_debug('No endpoint URI for Salmon post to ' . $user->getUri());
         return false;
     }
     try {
         $magic_env = MagicEnvelope::signAsUser($xml, $user);
         $envxml = $magic_env->toXML();
     } catch (Exception $e) {
         common_log(LOG_ERR, "Salmon unable to sign: " . $e->getMessage());
         return false;
     }
     $headers = array('Content-Type: application/magic-envelope+xml');
     try {
         $client = new HTTPClient();
         $client->setBody($envxml);
         $response = $client->post($endpoint_uri, $headers);
     } catch (HTTP_Request2_Exception $e) {
         common_log(LOG_ERR, "Salmon post to {$endpoint_uri} failed: " . $e->getMessage());
         return false;
     }
     // Diaspora wants a slightly different formatting on the POST (other Content-type, so body needs "xml=")
     if ($response->getStatus() === 422) {
         common_debug(sprintf('Salmon (from profile %d) endpoint %s returned status %s. Diaspora? Will try again! Body: %s', $user->id, $endpoint_uri, $response->getStatus(), $response->getBody()));
         $headers = array('Content-Type: application/x-www-form-urlencoded');
         $client->setBody('xml=' . Magicsig::base64_url_encode($envxml));
         $response = $client->post($endpoint_uri, $headers);
     }
     // 200 OK is the best response
     // 202 Accepted is what we get from Diaspora for example
     if (!in_array($response->getStatus(), array(200, 202))) {
         common_log(LOG_ERR, sprintf('Salmon (from profile %d) endpoint %s returned status %s: %s', $user->id, $endpoint_uri, $response->getStatus(), $response->getBody()));
         return false;
     }
     // Success!
     return true;
 }
Пример #4
0
 function onStartNoticeSave($notice)
 {
     $args = $this->testArgs($notice);
     common_debug("Blogspamnet args = " . print_r($args, TRUE));
     $requestBody = xmlrpc_encode_request('testComment', array($args));
     $request = new HTTPClient($this->baseUrl, HTTPClient::METHOD_POST);
     $request->setHeader('Content-Type', 'text/xml');
     $request->setBody($requestBody);
     $httpResponse = $request->send();
     $response = xmlrpc_decode($httpResponse->getBody());
     if (xmlrpc_is_fault($response)) {
         throw new ServerException("{$response['faultString']} ({$response['faultCode']})", 500);
     } else {
         common_debug("Blogspamnet results = " . $response);
         if (preg_match('/^ERROR(:(.*))?$/', $response, $match)) {
             // TRANS: Server exception thrown when blogspam.net returns error status.
             // TRANS: %1$s is the base URL, %2$s is the error (unknown contents; no period).
             throw new ServerException(sprintf(_m('Error from %1$s: %2$s'), $this->baseUrl, $match[2]), 500);
         } else {
             if (preg_match('/^SPAM(:(.*))?$/', $response, $match)) {
                 // TRANS: Server exception thrown when blogspam.net returns spam status.
                 // TRANS: Does not end with period because of unknown contents for %s (spam match).
                 throw new ClientException(sprintf(_m('Spam checker results: %s'), $match[2]), 400);
             } else {
                 if (preg_match('/^OK$/', $response)) {
                     // don't do anything
                 } else {
                     // TRANS: Server exception thrown when blogspam.net returns an unexpected status.
                     // TRANS: %1$s is the base URL, %2$s is the response (unknown contents; no period).
                     throw new ServerException(sprintf(_m('Unexpected response from %1$s: %2$s'), $this->baseUrl, $response), 500);
                 }
             }
         }
     }
     return true;
 }
Пример #5
0
 /**
  * Send a 'fat ping' to the subscriber's callback endpoint
  * containing the given Atom feed chunk.
  *
  * Determination of which items to send should be done at
  * a higher level; don't just shove in a complete feed!
  *
  * @param string $atom well-formed Atom feed
  * @throws Exception (HTTP or general)
  */
 function push($atom)
 {
     $headers = array('Content-Type: application/atom+xml');
     if ($this->secret) {
         $hmac = hash_hmac('sha1', $atom, $this->secret);
         $headers[] = "X-Hub-Signature: sha1={$hmac}";
     } else {
         $hmac = '(none)';
     }
     common_log(LOG_INFO, "About to push feed to {$this->callback} for {$this->topic}, HMAC {$hmac}");
     $request = new HTTPClient();
     $request->setBody($atom);
     $response = $request->post($this->callback, $headers);
     if ($response->isOk()) {
         return true;
     } else {
         throw new Exception("Callback returned status: " . $response->getStatus() . "; body: " . trim($response->getBody()));
     }
 }
Пример #6
0
 /**
  * Make a HTTP request.
  *
  * @param string $url    Where to make the
  * @param array  $params post parameters
  *
  * @return mixed the request
  */
 function httpRequest($url, $params = null)
 {
     $request = new HTTPClient($url);
     $request->setConfig(array('connect_timeout' => 120, 'timeout' => 120, 'follow_redirects' => true, 'ssl_verify_peer' => false, 'ssl_verify_host' => false));
     // Twitter is strict about accepting invalid "Expect" headers
     $request->setHeader('Expect', '');
     if (isset($params)) {
         $request->setMethod(HTTP_Request2::METHOD_POST);
         $request->setBody($params);
     }
     try {
         $response = $request->send();
         $code = $response->getStatus();
         if ($code < 200 || $code >= 400) {
             throw new OAuthClientException($response->getBody(), $code);
         }
         return $response->getBody();
     } catch (Exception $e) {
         throw new OAuthClientException($e->getMessage(), $e->getCode());
     }
 }
Пример #7
0
 function postToCollection($url, $activity)
 {
     $client = new HTTPClient($url);
     $client->setMethod('POST');
     $client->setAuth($this->username, $this->password);
     $client->setHeader('Content-Type', 'application/atom+xml;type=entry');
     $client->setBody($activity->asString(true, true, true));
     $response = $client->send();
     $status = $response->getStatus();
     $reason = $response->getReasonPhrase();
     if ($status >= 200 && $status < 300) {
         return true;
     } else {
         if ($status >= 400 && $status < 500) {
             // TRANS: Client exception thrown when post to collection fails with a 400 status.
             // TRANS: %1$s is a URL, %2$s is the status, %s$s is the fail reason.
             throw new ClientException(sprintf(_m('URLSTATUSREASON', '%1$s %2$s %3$s'), $url, $status, $reason));
         } else {
             if ($status >= 500 && $status < 600) {
                 // TRANS: Server exception thrown when post to collection fails with a 500 status.
                 // TRANS: %1$s is a URL, %2$s is the status, %s$s is the fail reason.
                 throw new ServerException(sprintf(_m('URLSTATUSREASON', '%1$s %2$s %3$s'), $url, $status, $reason));
             } else {
                 // That's unexpected.
                 // TRANS: Exception thrown when post to collection fails with a status that is not handled.
                 // TRANS: %1$s is a URL, %2$s is the status, %s$s is the fail reason.
                 throw new Exception(sprintf(_m('URLSTATUSREASON', '%1$s %2$s %3$s'), $url, $status, $reason));
             }
         }
     }
 }
Пример #8
0
 /**
  * Send a 'fat ping' to the subscriber's callback endpoint
  * containing the given Atom feed chunk.
  *
  * Determination of which items to send should be done at
  * a higher level; don't just shove in a complete feed!
  *
  * @param string $atom well-formed Atom feed
  * @throws Exception (HTTP or general)
  */
 function push($atom)
 {
     $headers = array('Content-Type: application/atom+xml');
     if ($this->secret) {
         $hmac = hash_hmac('sha1', $atom, $this->secret);
         $headers[] = "X-Hub-Signature: sha1={$hmac}";
     } else {
         $hmac = '(none)';
     }
     common_log(LOG_INFO, "About to push feed to {$this->callback} for {$this->topic}, HMAC {$hmac}");
     $request = new HTTPClient();
     $request->setBody($atom);
     $response = $request->post($this->callback, $headers);
     if ($response->isOk()) {
         return true;
     } else {
         // TRANS: Exception. %1$s is a response status code, %2$s is the body of the response.
         throw new Exception(sprintf(_m('Callback returned status: %1$s. Body: %2$s'), $response->getStatus(), trim($response->getBody())));
     }
 }
Пример #9
0
 public function onSalmonSlap($endpoint_uri, MagicEnvelope $magic_env, Profile $target = null)
 {
     $envxml = $magic_env->toXML($target);
     $headers = array('Content-Type: application/magic-envelope+xml');
     try {
         $client = new HTTPClient();
         $client->setBody($envxml);
         $response = $client->post($endpoint_uri, $headers);
     } catch (HTTP_Request2_Exception $e) {
         common_log(LOG_ERR, "Salmon post to {$endpoint_uri} failed: " . $e->getMessage());
         return false;
     }
     if ($response->getStatus() === 422) {
         common_debug(sprintf('Salmon (from profile %d) endpoint %s returned status %s. We assume it is a Diaspora seed; will adapt and try again if that plugin is enabled!', $magic_env->getActor()->getID(), $endpoint_uri, $response->getStatus()));
         return true;
     }
     // 200 OK is the best response
     // 202 Accepted is what we get from Diaspora for example
     if (!in_array($response->getStatus(), array(200, 202))) {
         common_log(LOG_ERR, sprintf('Salmon (from profile %d) endpoint %s returned status %s: %s', $magic_env->getActor()->getID(), $endpoint_uri, $response->getStatus(), $response->getBody()));
         return true;
     }
     // Since we completed the salmon slap, we discontinue the event
     return false;
 }
Пример #10
0
 function postJSON($url, $body)
 {
     $request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, 'POST', $url);
     $request->sign_request($this->sha1_method, $this->consumer, $this->token);
     $hclient = new HTTPClient($url);
     $hclient->setConfig(array('connect_timeout' => 120, 'timeout' => 120, 'follow_redirects' => true, 'ssl_verify_peer' => false, 'ssl_verify_host' => false));
     $hclient->setMethod(HTTP_Request2::METHOD_POST);
     $hclient->setBody(json_encode($body));
     $hclient->setHeader('Content-Type', 'application/json');
     $hclient->setHeader($request->to_header());
     // Twitter is strict about accepting invalid "Expect" headers
     // No reason not to clear it still here -ESP
     $hclient->setHeader('Expect', '');
     try {
         $response = $hclient->send();
         $code = $response->getStatus();
         if (!$response->isOK()) {
             throw new OAuthClientException($response->getBody(), $code);
         }
         return $response;
     } catch (Exception $e) {
         throw new OAuthClientException($e->getMessage(), $e->getCode());
     }
 }
Пример #11
0
 public function onSalmonSlap($endpoint_uri, MagicEnvelope $magic_env, Profile $target = null)
 {
     $envxml = $magic_env->toXML($target, 'diaspora');
     // Diaspora wants another POST format (base64url-encoded POST variable 'xml')
     $headers = array('Content-Type: application/x-www-form-urlencoded');
     // Another way to distinguish Diaspora from GNU social is that a POST with
     // $headers=array('Content-Type: application/magic-envelope+xml') would return
     // HTTP status code 422 Unprocessable Entity, at least as of 2015-10-04.
     try {
         $client = new HTTPClient();
         $client->setBody('xml=' . Magicsig::base64_url_encode($envxml));
         $response = $client->post($endpoint_uri, $headers);
     } catch (HTTP_Request2_Exception $e) {
         common_log(LOG_ERR, "Diaspora-flavoured Salmon post to {$endpoint_uri} failed: " . $e->getMessage());
         return false;
     }
     // 200 OK is the best response
     // 202 Accepted is what we get from Diaspora for example
     if (!in_array($response->getStatus(), array(200, 202))) {
         common_log(LOG_ERR, sprintf('Salmon (from profile %d) endpoint %s returned status %s: %s', $magic_env->getActor()->getID(), $endpoint_uri, $response->getStatus(), $response->getBody()));
         return true;
     }
     // Success!
     return false;
 }