/** * 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; }
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; }
/** * 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; }
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; }
/** * 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())); } }
/** * 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()); } }
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)); } } } }
/** * 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()))); } }
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; }
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()); } }
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; }