/** * Get all URLs * * @param string $suffix * @param bool $doNotShuffle * @return string[] */ public function getAllURLs(string $suffix = '', bool $doNotShuffle = false) : array { $state = State::instance(); $candidates = []; if ($state->universal['tor-only']) { // Prioritize Tor Hidden Services $after = []; foreach ($this->urls as $url) { if (\Airship\isOnionUrl($url)) { $candidates[] = $url . $suffix; } else { $after[] = $url . $suffix; } } if (!$doNotShuffle) { \Airship\secure_shuffle($candidates); \Airship\secure_shuffle($after); } foreach ($after as $url) { $candidates[] = $url . $suffix; } } else { $candidates = $this->urls; if (!$doNotShuffle) { \Airship\secure_shuffle($candidates); } foreach (\array_keys($candidates) as $i) { $candidates[$i] .= $suffix; } } return $candidates; }
/** * Get all URLs * * @param bool $doNotShuffle * @return string[] */ protected function getChannelURLs(bool $doNotShuffle = false) : array { $state = State::instance(); $candidates = []; if ($state->universal['tor-only']) { // Prioritize Tor Hidden Services $after = []; foreach ($this->urls as $url) { if (\Airship\isOnionUrl($url)) { $candidates[] = $url; } else { $after[] = $url; } } // Shuffle each array separately, to maintain priority; if (!$doNotShuffle) { \Airship\secure_shuffle($candidates); \Airship\secure_shuffle($after); } foreach ($after as $url) { $candidates[] = $url; } } else { $candidates = $this->urls; if (!$doNotShuffle) { \Airship\secure_shuffle($candidates); } } return $candidates; }
/** * @covers \Airship\isOnionUrl() */ public function testOnionUrl() { $this->assertTrue(\Airship\isOnionUrl('http://duskgytldkxiuqc6.onion')); $this->assertTrue(\Airship\isOnionUrl('https://facebookcorewwwi.onion')); $this->assertTrue(\Airship\isOnionUrl('http://example.com.onion')); $this->assertFalse(\Airship\isOnionUrl('http://duskgytldkxiuqc6.onion.to')); $this->assertFalse(\Airship\isOnionUrl('https://duskgytldkxiuqc6.onion.to')); $this->assertFalse(\Airship\isOnionUrl('http://example.com?.onion')); }
/** * Make sure we include the default params * * @param array $params * @param string $url (used for decision-making) * * @return array */ public function params(array $params = [], string $url = '') : array { $config = State::instance(); $defaults = ['curl' => [CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_2]]; /** * If we have pre-configured some global parameters, let's add them to * our defaults before we check if we need Tor support. */ if (!empty($config->universal['guzzle'])) { $defaults = \array_merge($defaults, $config->universal['guzzle']); } /** * Support for Tor Hidden Services */ if (\Airship\isOnionUrl($url)) { // A .onion domain should be a Tor Hidden Service $defaults['curl'][CURLOPT_PROXY] = 'http://127.0.0.1:9050/'; $defaults['curl'][CURLOPT_PROXYTYPE] = CURLPROXY_SOCKS5; if (!\preg_match('#^https://', $url)) { // If it's a .onion site, HTTPS is not required. // If HTTPS is specified, still enforce it. unset($defaults['curl'][CURLOPT_SSLVERSION]); } } elseif (!empty($config->universal['tor-only'])) { // We were configured to use Tor for everything. $defaults['curl'][CURLOPT_PROXY] = 'http://127.0.0.1:9050/'; $defaults['curl'][CURLOPT_PROXYTYPE] = CURLPROXY_SOCKS5; } return \array_merge($defaults, ['form_params' => $params]); }
/** * Get a random URL * * @return string */ public function getURL() : string { $state = State::instance(); $candidates = []; if ($state->universal['tor-only']) { // Prioritize Tor Hidden Services foreach ($this->urls as $url) { if (\Airship\isOnionUrl($url)) { $candidates[] = $url; } } // If we had any .onions, we will only use those. // Otherwise, use non-Tor URLs over Tor. if (empty($candidates)) { $candidates = $this->urls; } } else { $candidates = $this->urls; } $max = \count($candidates) - 1; return $candidates[\random_int(0, $max)]; }