/**
  * Get the resulting notice ID from the reponse header of the API
  * request.
  *
  * @param  MWHttpRequest $response The response from the API request.
  * @return int|boolean             The ID of the resulting notice or
  *                                 false on failure.
  */
 public function getNoticeIdFromResponse(\MWHttpRequest $response)
 {
     $location = $response->getResponseHeader('Location');
     if (empty($location)) {
         return false;
     }
     $path = parse_url($location, PHP_URL_PATH);
     $matches = [];
     if (preg_match('/^\\/notices\\/(\\d+)$/', $path, $matches)) {
         return (int) $matches[1];
     }
     return false;
 }
Ejemplo n.º 2
0
 /**
  * The general method for handling the communication with the service.
  */
 public function request($resourceName, $getParams = [], $postData = [], $extraRequestOptions = [])
 {
     // Crash if we cannot make HTTP requests.
     \Wikia\Util\Assert::true(\MWHttpRequest::canMakeRequests());
     // Add client_id and client_secret to the GET data.
     $getParams['client_id'] = $this->clientId;
     $getParams['client_secret'] = $this->clientSecret;
     // Request URI pre-processing.
     $uri = "{$this->baseUri}{$resourceName}?" . http_build_query($getParams);
     // Request options pre-processing.
     $options = ['method' => 'GET', 'timeout' => 5, 'postData' => $postData, 'noProxy' => true, 'followRedirects' => false, 'returnInstance' => true, 'internalRequest' => true];
     $options = array_merge($options, $extraRequestOptions);
     /*
      * MediaWiki's MWHttpRequest class heavily relies on Messaging API
      * (wfMessage()) which happens to rely on the value of $wgLang.
      * $wgLang is set after $wgUser. On per-request authentication with
      * an access token we use MWHttpRequest before wgUser is created so
      * we need $wgLang to be present. With GlobalStateWrapper we can set
      * the global variable in the local, function's scope, so it is the
      * same as the already existing $wgContLang.
      */
     global $wgContLang;
     $wrapper = new GlobalStateWrapper(['wgLang' => $wgContLang]);
     // Request execution.
     /** @var \MWHttpRequest $request */
     $request = $wrapper->wrap(function () use($options, $uri) {
         return \Http::request($options['method'], $uri, $options);
     });
     $this->status = $request->status;
     $output = json_decode($request->getContent());
     if (!$output) {
         throw new ClientException('Invalid response.');
     }
     return $output;
 }
Ejemplo n.º 3
0
	public function getData () {

		// Crazy workaround for HttpRequest not accepting user options
		$req = MWHttpRequest::factory( $this->summaryDataURL, array ('method' => "GET", 'timeout' => 'default') );
		$req->setHeader("http-x-license-key", $this->licenceKey);
		$status = $req->execute();
		$response = $req->getContent();
		$data = array();

		if ($response) {
			// chop up xml
			$xml = simplexml_load_string($response);
			$data = array();
			foreach ($xml->threshold_value as $node) {
				$label = (string)$node['name'];

				// just grab the time from the first field since we are rounding to the nearest hour anyway
				if (empty($data['Time'])) {
					$time = (string)$node['end_time'];
					$date = strtotime($time);  // raw mysql date format should parse ok
					$data['Time'] = $date;
				}
				// we only want to use some of the fields returned from new relic
				if (in_array($label, array('Errors', 'Response Time', 'Throughput')))
					$data[$label] = (string)$node['metric_value'];
			}
		} else {
//			print_pre("null response from newrelic");
		}
		return $data;
	}
 /**
  * Check, if the user solved the captcha.
  *
  * Based on reference implementation:
  * https://github.com/google/recaptcha#php
  *
  * @return boolean
  */
 function passCaptcha()
 {
     global $wgRequest, $wgReCaptchaSecretKey, $wgReCaptchaSendRemoteIP;
     $url = 'https://www.google.com/recaptcha/api/siteverify';
     // Build data to append to request
     $data = array('secret' => $wgReCaptchaSecretKey, 'response' => $wgRequest->getVal('g-recaptcha-response'));
     if ($wgReCaptchaSendRemoteIP) {
         $data['remoteip'] = $wgRequest->getIP();
     }
     $url = wfAppendQuery($url, $data);
     $request = MWHttpRequest::factory($url, array('method' => 'GET'));
     $status = $request->execute();
     if (!$status->isOK()) {
         $this->error = 'http';
         $this->logStatusError($status);
         return false;
     }
     $response = FormatJson::decode($request->getContent(), true);
     if (!$response) {
         $this->error = 'json';
         $this->logStatusError($this->error);
         return false;
     }
     if (isset($response['error-codes'])) {
         $this->error = 'recaptcha-api';
         $this->logCheckError($response['error-codes']);
         return false;
     }
     return $response['success'];
 }
Ejemplo n.º 5
0
function streamAppleTouch()
{
    global $wgAppleTouchIcon;
    wfResetOutputBuffers();
    if ($wgAppleTouchIcon === false) {
        # That's not very helpful, that's where we are already
        header('HTTP/1.1 404 Not Found');
        faviconShowError('$wgAppleTouchIcon is configured incorrectly, ' . 'it must be set to something other than false \\n');
        return;
    }
    $req = RequestContext::getMain()->getRequest();
    if ($req->getHeader('X-Favicon-Loop') !== false) {
        header('HTTP/1.1 500 Internal Server Error');
        faviconShowError('Proxy forwarding loop detected');
        return;
    }
    $url = wfExpandUrl($wgAppleTouchIcon, PROTO_CANONICAL);
    $client = MWHttpRequest::factory($url);
    $client->setHeader('X-Favicon-Loop', '1');
    $status = $client->execute();
    if (!$status->isOK()) {
        header('HTTP/1.1 500 Internal Server Error');
        faviconShowError("Failed to fetch URL \"{$url}\"");
        return;
    }
    $content = $client->getContent();
    header('Content-Length: ' . strlen($content));
    header('Content-Type: ' . $client->getResponseHeader('Content-Type'));
    header('Cache-Control: public');
    header('Expires: ' . gmdate('r', time() + 86400));
    echo $content;
}
Ejemplo n.º 6
0
 protected function checkContactLink($name, $url, &$countOk)
 {
     global $wgVersion;
     $ok = false;
     if (Sanitizer::validateEmail($url)) {
         $ok = true;
         // assume OK
     } else {
         $bits = wfParseUrl($url);
         if ($bits && isset($bits['scheme'])) {
             if ($bits['scheme'] == 'mailto') {
                 $ok = true;
                 // assume OK
             } elseif (in_array($bits['scheme'], array('http', 'https'))) {
                 $req = MWHttpRequest::factory($url, array('method' => 'GET', 'timeout' => 8, 'sslVerifyHost' => false, 'sslVerifyCert' => false));
                 $req->setUserAgent("MediaWiki {$wgVersion}, CheckCongressLinks Checker");
                 $ok = $req->execute()->isOK();
             }
         }
     }
     if ($ok) {
         ++$countOk;
     } else {
         $this->output("Broken: [{$name}] [{$url}]\n");
     }
 }
Ejemplo n.º 7
0
 protected function getInterfaceObjectFromType($type)
 {
     wfProfileIn(__METHOD__);
     $apiUrl = $this->getApiUrl();
     if (empty($this->videoId)) {
         throw new EmptyResponseException($apiUrl);
     }
     $memcKey = wfMemcKey(static::$CACHE_KEY, $apiUrl, static::$CACHE_KEY_VERSION);
     $processedResponse = F::app()->wg->memc->get($memcKey);
     if (empty($processedResponse)) {
         $req = MWHttpRequest::factory($apiUrl, array('noProxy' => true));
         $req->setHeader('User-Agent', self::$REQUEST_USER_AGENT);
         $status = $req->execute();
         if ($status->isOK()) {
             $response = $req->getContent();
             $this->response = $response;
             // Only for migration purposes
             if (empty($response)) {
                 throw new EmptyResponseException($apiUrl);
             } else {
                 if ($req->getStatus() == 301) {
                     throw new VideoNotFoundException($req->getStatus(), $this->videoId . ' Moved Permanently.', $apiUrl);
                 }
             }
         } else {
             $this->checkForResponseErrors($req->status, $req->getContent(), $apiUrl);
         }
         $processedResponse = $this->processResponse($response, $type);
         F::app()->wg->memc->set($memcKey, $processedResponse, static::$CACHE_EXPIRY);
     }
     wfProfileOut(__METHOD__);
     return $processedResponse;
 }
Ejemplo n.º 8
0
 /**
  * @group Broken
  */
 public function testApiLoginGotCookie()
 {
     $this->markTestIncomplete("The server can't do external HTTP requests, " . "and the internal one won't give cookies");
     global $wgServer, $wgScriptPath;
     if (!isset($wgServer)) {
         $this->markTestIncomplete('This test needs $wgServer to be set in LocalSettings.php');
     }
     $user = self::$users['sysop'];
     $req = MWHttpRequest::factory(self::$apiUrl . "?action=login&format=xml", array("method" => "POST", "postData" => array("lgname" => $user->username, "lgpassword" => $user->password)), __METHOD__);
     $req->execute();
     libxml_use_internal_errors(true);
     $sxe = simplexml_load_string($req->getContent());
     $this->assertNotInternalType("bool", $sxe);
     $this->assertThat($sxe, $this->isInstanceOf("SimpleXMLElement"));
     $this->assertNotInternalType("null", $sxe->login[0]);
     $a = $sxe->login[0]->attributes()->result[0];
     $this->assertEquals(' result="NeedToken"', $a->asXML());
     $token = (string) $sxe->login[0]->attributes()->token;
     $req->setData(array("lgtoken" => $token, "lgname" => $user->username, "lgpassword" => $user->password));
     $req->execute();
     $cj = $req->getCookieJar();
     $serverName = parse_url($wgServer, PHP_URL_HOST);
     $this->assertNotEquals(false, $serverName);
     $serializedCookie = $cj->serializeToHttpRequest($wgScriptPath, $serverName);
     $this->assertNotEquals('', $serializedCookie);
     $this->assertRegexp('/_session=[^;]*; .*UserID=[0-9]*; .*UserName='******'; .*Token=/', $serializedCookie);
 }
 /**
  * getImage method
  *
  */
 public function getImage()
 {
     $this->wf->profileIn(__METHOD__);
     if ($this->wg->User->isLoggedIn()) {
         # make proper thumb path: c/central/images/thumb/....
         $path = sprintf("%s/%s/images", substr($this->wg->DBname, 0, 1), $this->wg->DBname);
         # take thumb request from request
         $img = $this->getVal('image');
         if (preg_match('/^(\\/?)thumb\\//', $img)) {
             # build proper thumb url for thumbnailer
             $thumb_url = sprintf("%s/%s/%s", $this->wg->ThumbnailerService, $path, $img);
             # call thumbnailer
             $options = array('method' => 'GET', 'timeout' => 'default', 'noProxy' => 1);
             $thumb_request = MWHttpRequest::factory($thumb_url, $options);
             $status = $thumb_request->execute();
             $headers = $thumb_request->getResponseHeaders();
             if ($status->isOK()) {
                 if (!empty($headers)) {
                     foreach ($headers as $header_name => $header_value) {
                         if (is_array($header_value)) {
                             list($value) = $header_value;
                         } else {
                             $value = $header_value;
                         }
                         header(sprintf("%s: %s", $header_name, $value));
                     }
                 }
                 echo $thumb_request->getContent();
             } else {
                 $this->wf->debug("Cannot generate auth thumb");
                 $this->_access_forbidden('img-auth-accessdenied', 'img-auth-nofile', $img);
             }
         } else {
             # serve original image
             $filename = realpath(sprintf("%s/%s", $this->wg->UploadDirectory, $img));
             $stat = @stat($filename);
             if ($stat) {
                 $this->wf->ResetOutputBuffers();
                 $fileinfo = finfo_open(FILEINFO_MIME_TYPE);
                 $imageType = finfo_file($fileinfo, $filename);
                 header(sprintf("Content-Disposition: inline;filename*=utf-8'%s'%s", $this->wg->ContLanguageCode, urlencode(basename($filename))));
                 header(sprintf("Content-Type: %s", $imageType));
                 header(sprintf("Content-Length: %d" . $stat['size']));
                 readfile($filename);
             } else {
                 $this->_access_forbidden('img-auth-accessdenied', 'img-auth-nopathinfo', $img);
             }
         }
     } else {
         $this->_access_forbidden('img-auth-accessdenied', 'img-auth-public', '');
     }
     $this->wf->profileOut(__METHOD__);
     exit;
 }
 public function makeRequest($url, $method = 'POST')
 {
     $options = array('method' => $method);
     if ($this->followRedirects) {
         $options['followRedirects'] = true;
         $this->followRedirects = false;
         # Reset the flag
     }
     $req = MWHttpRequest::factory($url, $options);
     $req->setUserAgent($this->userAgent);
     $req->setCookieJar($this->cookie_jar);
     return $req;
 }
 protected function importVideosForKeyphrase($keyword, $params = array())
 {
     wfProfileIn(__METHOD__);
     $addlCategories = !empty($params['addlCategories']) ? $params['addlCategories'] : array();
     $debug = !empty($params['debug']);
     $startDate = !empty($params['startDate']) ? $params['startDate'] : '';
     $endDate = !empty($params['endDate']) ? $params['endDate'] : '';
     $articlesCreated = 0;
     $page = 1;
     do {
         $numVideos = 0;
         // connect to provider API
         $url = $this->initFeedUrl($keyword, $startDate, $endDate, $page++);
         print "Connecting to {$url}...\n";
         $req = MWHttpRequest::factory($url);
         $status = $req->execute();
         if ($status->isOK()) {
             $response = $req->getContent();
         } else {
             print "ERROR: problem downloading content!\n";
             wfProfileOut(__METHOD__);
             return 0;
         }
         // parse response
         $videos = json_decode($response, true);
         $numVideos = sizeof($videos['videos']);
         print "Found {$numVideos} videos...\n";
         for ($i = 0; $i < $numVideos; $i++) {
             $clipData = array();
             $video = $videos['videos'][$i];
             $clipData['clipTitle'] = trim($video['title']);
             $clipData['videoId'] = $video['guid'];
             $clipData['thumbnail'] = $video['image'];
             $clipData['duration'] = $video['duration'];
             $clipData['published'] = $video['date'];
             $clipData['category'] = $video['category_name'];
             $clipData['keywords'] = trim($video['tags']);
             $clipData['description'] = trim($video['description']);
             $clipData['aspectRatio'] = $video['aspect_ratio'];
             $msg = '';
             $createParams = array('addlCategories' => $addlCategories, 'debug' => $debug);
             $articlesCreated += $this->createVideo($clipData, $msg, $createParams);
             if ($msg) {
                 print "ERROR: {$msg}\n";
             }
         }
     } while ($numVideos == self::API_PAGE_SIZE);
     wfProfileOut(__METHOD__);
     return $articlesCreated;
 }
Ejemplo n.º 12
0
 protected function requestParsoid($method, $title, $params)
 {
     global $wgVisualEditorParsoidURL, $wgVisualEditorParsoidTimeout, $wgVisualEditorParsoidForwardCookies;
     $url = $wgVisualEditorParsoidURL . '/' . urlencode($this->getApiSource()) . '/' . urlencode($title->getPrefixedDBkey());
     $data = array_merge($this->getProxyConf(), array('method' => $method, 'timeout' => $wgVisualEditorParsoidTimeout));
     if ($method === 'POST') {
         $data['postData'] = $params;
     } else {
         $url = wfAppendQuery($url, $params);
     }
     $req = MWHttpRequest::factory($url, $data);
     // Forward cookies, but only if configured to do so and if there are read restrictions
     if ($wgVisualEditorParsoidForwardCookies && !User::isEveryoneAllowed('read')) {
         $req->setHeader('Cookie', $this->getRequest()->getHeader('Cookie'));
     }
     $status = $req->execute();
     if ($status->isOK()) {
         // Pass thru performance data from Parsoid to the client, unless the response was
         // served directly from Varnish, in  which case discard the value of the XPP header
         // and use it to declare the cache hit instead.
         $xCache = $req->getResponseHeader('X-Cache');
         if (is_string($xCache) && strpos(strtolower($xCache), 'hit') !== false) {
             $xpp = 'cached-response=true';
             $hit = true;
         } else {
             $xpp = $req->getResponseHeader('X-Parsoid-Performance');
             $hit = false;
         }
         WikiaLogger::instance()->debug('ApiVisualEditor', array('hit' => $hit, 'method' => $method, 'url' => $url));
         if ($xpp !== null) {
             $resp = $this->getRequest()->response();
             $resp->header('X-Parsoid-Performance: ' . $xpp);
         }
     } elseif ($status->isGood()) {
         $this->dieUsage($req->getContent(), 'parsoidserver-http-' . $req->getStatus());
     } elseif ($errors = $status->getErrorsByType('error')) {
         $error = $errors[0];
         $code = $error['message'];
         if (count($error['params'])) {
             $message = $error['params'][0];
         } else {
             $message = 'MWHttpRequest error';
         }
         $this->dieUsage($message, 'parsoidserver-' . $code);
     }
     // TODO pass through X-Parsoid-Performance header, merge with getHTML above
     return $req->getContent();
 }
Ejemplo n.º 13
0
 public function hitUrl($zip, $attempt = 0)
 {
     $url = $this->makeUrl($zip);
     //$this->output( "*Trying to hit $url\n" );
     $req = MWHttpRequest::factory($url, array('method' => 'GET', 'timeout' => 2, 'sslVerifyHost' => false, 'sslVerifyCert' => false));
     if ($req->execute()->isOK()) {
         $this->isOK++;
     } else {
         sleep(2);
         $attempt++;
         if ($attempt < 3) {
             $this->hitUrl($zip, $attempt);
         } else {
             $this->isBad++;
         }
     }
 }
Ejemplo n.º 14
0
 public function get($url, $postData = false)
 {
     $this->log("Connect: {$url} ", 1);
     $options = array('followRedirects' => true, 'noProxy' => true, 'timeout' => 220);
     if ($postData !== false) {
         $options['postData'] = $postData;
         print_r($postData);
     }
     $req = MWHttpRequest::factory($url, $options);
     $status = $req->execute();
     $decodedResponse = null;
     if ($status->isOK()) {
         $response = $req->getContent();
         $response = iconv('UTF-8', 'UTF-8//IGNORE', utf8_encode($response));
         $responseCode = $req->getStatus();
         $decodedResponse = json_decode($response);
     }
     return array('code' => $responseCode, 'response' => $decodedResponse);
 }
 protected function hitThumbUrl($file, $transformParams)
 {
     global $wgUploadThumbnailRenderHttpCustomHost, $wgUploadThumbnailRenderHttpCustomDomain;
     $thumbName = $file->thumbName($transformParams);
     $thumbUrl = $file->getThumbUrl($thumbName);
     if ($wgUploadThumbnailRenderHttpCustomDomain) {
         $parsedUrl = wfParseUrl($thumbUrl);
         if (!$parsedUrl || !isset($parsedUrl['path']) || !strlen($parsedUrl['path'])) {
             return false;
         }
         $thumbUrl = '//' . $wgUploadThumbnailRenderHttpCustomDomain . $parsedUrl['path'];
     }
     wfDebug(__METHOD__ . ": hitting url {$thumbUrl}\n");
     $request = MWHttpRequest::factory($thumbUrl, array('method' => 'HEAD', 'followRedirects' => true), __METHOD__);
     if ($wgUploadThumbnailRenderHttpCustomHost) {
         $request->setHeader('Host', $wgUploadThumbnailRenderHttpCustomHost);
     }
     $status = $request->execute();
     return $request->getStatus();
 }
Ejemplo n.º 16
0
 /**
  * Perform an HTTP request
  *
  * @param string $method HTTP method. Usually GET/POST
  * @param string $url Full URL to act on. If protocol-relative, will be expanded to an http:// URL
  * @param array $options Options to pass to MWHttpRequest object.
  *	Possible keys for the array:
  *    - timeout             Timeout length in seconds
  *    - connectTimeout      Timeout for connection, in seconds (curl only)
  *    - postData            An array of key-value pairs or a url-encoded form data
  *    - proxy               The proxy to use.
  *                          Otherwise it will use $wgHTTPProxy (if set)
  *                          Otherwise it will use the environment variable "http_proxy" (if set)
  *    - noProxy             Don't use any proxy at all. Takes precedence over proxy value(s).
  *    - sslVerifyHost       Verify hostname against certificate
  *    - sslVerifyCert       Verify SSL certificate
  *    - caInfo              Provide CA information
  *    - maxRedirects        Maximum number of redirects to follow (defaults to 5)
  *    - followRedirects     Whether to follow redirects (defaults to false).
  *		                    Note: this should only be used when the target URL is trusted,
  *		                    to avoid attacks on intranet services accessible by HTTP.
  *    - userAgent           A user agent, if you want to override the default
  *                          MediaWiki/$wgVersion
  *    - logger              A \Psr\Logger\LoggerInterface instance for debug logging
  * @param string $caller The method making this request, for profiling
  * @return string|bool (bool)false on failure or a string on success
  */
 public static function request($method, $url, $options = [], $caller = __METHOD__)
 {
     wfDebug("HTTP: {$method}: {$url}\n");
     $options['method'] = strtoupper($method);
     if (!isset($options['timeout'])) {
         $options['timeout'] = 'default';
     }
     if (!isset($options['connectTimeout'])) {
         $options['connectTimeout'] = 'default';
     }
     $req = MWHttpRequest::factory($url, $options, $caller);
     $status = $req->execute();
     if ($status->isOK()) {
         return $req->getContent();
     } else {
         $errors = $status->getErrorsByType('error');
         $logger = LoggerFactory::getInstance('http');
         $logger->warning($status->getWikiText(false, false, 'en'), ['error' => $errors, 'caller' => $caller, 'content' => $req->getContent()]);
         return false;
     }
 }
Ejemplo n.º 17
0
	public function execute() {
		wfProfileIn( __METHOD__ );

		parent::execute();

		if ( is_array( $this->postData ) ) {
			$this->postData = wfArrayToCgi( $this->postData );
		}

		if ( $this->parsedUrl['scheme'] != 'http' &&
			 $this->parsedUrl['scheme'] != 'https' ) {
			$this->status->fatal( 'http-invalid-scheme', $this->parsedUrl['scheme'] );
		}

		$this->reqHeaders['Accept'] = "*/*";
		if ( $this->method == 'POST' ) {
			// Required for HTTP 1.0 POSTs
			$this->reqHeaders['Content-Length'] = strlen( $this->postData );
			if ( !isset( $this->reqHeaders['Content-Type'] ) ) {
				$this->reqHeaders['Content-Type'] = "application/x-www-form-urlencoded";
			}
		}

		$options = array();
		if ( $this->proxy ) {
			$options['proxy'] = $this->urlToTCP( $this->proxy );
			$options['request_fulluri'] = true;
		}

		if ( !$this->followRedirects ) {
			$options['max_redirects'] = 0;
		} else {
			$options['max_redirects'] = $this->maxRedirects;
		}

		$options['method'] = $this->method;
		$options['header'] = implode( "\r\n", $this->getHeaderList() );
		// Note that at some future point we may want to support
		// HTTP/1.1, but we'd have to write support for chunking
		// in version of PHP < 5.3.1
		$options['protocol_version'] = "1.0";

		// This is how we tell PHP we want to deal with 404s (for example) ourselves.
		// Only works on 5.2.10+
		$options['ignore_errors'] = true;

		if ( $this->postData ) {
			$options['content'] = $this->postData;
		}

		$options['timeout'] = $this->timeout;

		if ( $this->sslVerifyHost ) {
			$options['CN_match'] = $this->parsedUrl['host'];
		}
		if ( $this->sslVerifyCert ) {
			$options['verify_peer'] = true;
		}

		if ( is_dir( $this->caInfo ) ) {
			$options['capath'] = $this->caInfo;
		} elseif ( is_file( $this->caInfo ) ) {
			$options['cafile'] = $this->caInfo;
		} elseif ( $this->caInfo ) {
			throw new MWException( "Invalid CA info passed: {$this->caInfo}" );
		}

		$scheme = $this->parsedUrl['scheme'];
		$context = stream_context_create( array( "$scheme" => $options ) );

		$this->headerList = array();
		$reqCount = 0;
		$url = $this->url;

		$result = array();

		do {
			$reqCount++;
			wfSuppressWarnings();
			$fh = fopen( $url, "r", false, $context );
			wfRestoreWarnings();

			if ( !$fh ) {
				break;
			}

			$result = stream_get_meta_data( $fh );
			$this->headerList = $result['wrapper_data'];
			$this->parseHeader();

			if ( !$this->followRedirects ) {
				break;
			}

			# Handle manual redirection
			if ( !$this->isRedirect() || $reqCount > $this->maxRedirects ) {
				break;
			}
			# Check security of URL
			$url = $this->getResponseHeader( "Location" );

			if ( !Http::isValidURI( $url ) ) {
				wfDebug( __METHOD__ . ": insecure redirection\n" );
				break;
			}
		} while ( true );

		$this->setStatus();

		if ( $fh === false ) {
			$this->status->fatal( 'http-request-error' );
			wfProfileOut( __METHOD__ );
			return $this->status;
		}

		if ( $result['timed_out'] ) {
			$this->status->fatal( 'http-timed-out', $this->url );
			wfProfileOut( __METHOD__ );
			return $this->status;
		}

		// If everything went OK, or we received some error code
		// get the response body content.
		if ( $this->status->isOK() || (int)$this->respStatus >= 300 ) {
			while ( !feof( $fh ) ) {
				$buf = fread( $fh, 8192 );

				if ( $buf === false ) {
					$this->status->fatal( 'http-read-error' );
					break;
				}

				if ( strlen( $buf ) ) {
					call_user_func( $this->callback, $fh, $buf );
				}
			}
		}
		fclose( $fh );

		wfProfileOut( __METHOD__ );

		return $this->status;
	}
Ejemplo n.º 18
0
 /**
  * @param $xml
  * @throws GWTException
  */
 private function put_sitemap($xml)
 {
     $request = MWHttpRequest::factory($this->make_sitemaps_uri(), array('postData' => $xml, 'method' => 'POST'));
     $request->setHeader('Content-type', 'application/atom+xml');
     $request->setHeader('Content-length', strval(strlen($xml)));
     $request->setHeader('Authorization', 'GoogleLogin auth=' . $this->mAuth);
     $status = $request->execute();
     if ($status->isOK()) {
         $text = $request->getContent();
         GWTLogHelper::debug($text);
     } else {
         throw new GWTException("Non 200 response.\n" . "\n" . "message:" . $status->getMessage() . "\n" . $request->getContent());
     }
 }
Ejemplo n.º 19
0
 /**
  * Like a Http:get request, but with custom User-Agent.
  * @see Http::get
  * @param string $url
  * @param string $timeout
  * @param array $options
  * @param integer|bool &$mtime Resulting Last-Modified UNIX timestamp if received
  * @return bool|string
  */
 public static function httpGet($url, $timeout = 'default', $options = [], &$mtime = false)
 {
     $options['timeout'] = $timeout;
     /* Http::get */
     $url = wfExpandUrl($url, PROTO_HTTP);
     wfDebug("ForeignAPIRepo: HTTP GET: {$url}\n");
     $options['method'] = "GET";
     if (!isset($options['timeout'])) {
         $options['timeout'] = 'default';
     }
     $req = MWHttpRequest::factory($url, $options, __METHOD__);
     $req->setUserAgent(ForeignAPIRepo::getUserAgent());
     $status = $req->execute();
     if ($status->isOK()) {
         $lmod = $req->getResponseHeader('Last-Modified');
         $mtime = $lmod ? wfTimestamp(TS_UNIX, $lmod) : false;
         return $req->getContent();
     } else {
         $logger = LoggerFactory::getInstance('http');
         $logger->warning($status->getWikiText(false, false, 'en'), ['caller' => 'ForeignAPIRepo::httpGet']);
         return false;
     }
 }
Ejemplo n.º 20
0
 public function getThumbnail()
 {
     wfProfileIn(__METHOD__);
     $thumbnail = '';
     $url = 'http://www.gamestar.de/emb/getVideoData5.cfm?vid=' . $this->videoId;
     $req = MWHttpRequest::factory($url);
     $req->setHeader('User-Agent', self::$REQUEST_USER_AGENT);
     $status = $req->execute();
     if ($status->isOK()) {
         $response = trim($req->getContent());
         if (!empty($response)) {
             $xml = @simplexml_load_string($response);
             if (isset($xml->image)) {
                 $thumbnail = (string) $xml->image;
             }
         }
     }
     wfProfileOut(__METHOD__);
     return $thumbnail;
 }
Ejemplo n.º 21
0
 /**
  * Download the file, save it to the temporary file and update the file
  * size and set $mRemoveTempFile to true.
  * @return Status
  */
 protected function reallyFetchFile()
 {
     if ($this->mTempPath === false) {
         return Status::newFatal('tmp-create-error');
     }
     // Note the temporary file should already be created by makeTemporaryFile()
     $this->mTmpHandle = fopen($this->mTempPath, 'wb');
     if (!$this->mTmpHandle) {
         return Status::newFatal('tmp-create-error');
     }
     $this->mRemoveTempFile = true;
     $this->mFileSize = 0;
     $req = MWHttpRequest::factory($this->mUrl, array('followRedirects' => true));
     $req->setCallback(array($this, 'saveTempFileChunk'));
     $status = $req->execute();
     if ($this->mTmpHandle) {
         // File got written ok...
         fclose($this->mTmpHandle);
         $this->mTmpHandle = null;
     } else {
         // We encountered a write error during the download...
         return Status::newFatal('tmp-write-error');
     }
     if (!$status->isOk()) {
         return $status;
     }
     return $status;
 }
Ejemplo n.º 22
0
 /**
  * @param $s Status
  */
 private function subscribeToMediaWikiAnnounce(Status $s)
 {
     $params = array('email' => $this->getVar('_AdminEmail'), 'language' => 'en', 'digest' => 0);
     // Mailman doesn't support as many languages as we do, so check to make
     // sure their selected language is available
     $myLang = $this->getVar('_UserLang');
     if (in_array($myLang, $this->mediaWikiAnnounceLanguages)) {
         $myLang = $myLang == 'pt-br' ? 'pt_BR' : $myLang;
         // rewrite to Mailman's pt_BR
         $params['language'] = $myLang;
     }
     if (MWHttpRequest::canMakeRequests()) {
         $res = MWHttpRequest::factory($this->mediaWikiAnnounceUrl, array('method' => 'POST', 'postData' => $params))->execute();
         if (!$res->isOK()) {
             $s->warning('config-install-subscribe-fail', $res->getMessage());
         }
     } else {
         $s->warning('config-install-subscribe-notpossible');
     }
 }
Ejemplo n.º 23
0
 /**
  * Set read/write permissions for a Swift container.
  *
  * $readGrps is a list of the possible criteria for a request to have
  * access to read a container. Each item is one of the following formats:
  *   - account:user        : Grants access if the request is by the given user
  *   - ".r:<regex>"        : Grants access if the request is from a referrer host that
  *                           matches the expression and the request is not for a listing.
  *                           Setting this to '*' effectively makes a container public.
  *   -".rlistings:<regex>" : Grants access if the request is from a referrer host that
  *                           matches the expression and the request is for a listing.
  *
  * $writeGrps is a list of the possible criteria for a request to have
  * access to write to a container. Each item is of the following format:
  *   - account:user       : Grants access if the request is by the given user
  *
  * @see http://swift.openstack.org/misc.html#acls
  *
  * In general, we don't allow listings to end-users. It's not useful, isn't well-defined
  * (lists are truncated to 10000 item with no way to page), and is just a performance risk.
  *
  * @param $contObj CF_Container Swift container
  * @param array $readGrps List of read access routes
  * @param array $writeGrps List of write access routes
  * @return Status
  */
 protected function setContainerAccess(CF_Container $contObj, array $readGrps, array $writeGrps)
 {
     $creds = $contObj->cfs_auth->export_credentials();
     $url = $creds['storage_url'] . '/' . rawurlencode($contObj->name);
     // Note: 10 second timeout consistent with php-cloudfiles
     $req = MWHttpRequest::factory($url, array('method' => 'POST', 'timeout' => 10));
     $req->setHeader('X-Auth-Token', $creds['auth_token']);
     $req->setHeader('X-Container-Read', implode(',', $readGrps));
     $req->setHeader('X-Container-Write', implode(',', $writeGrps));
     return $req->execute();
     // should return 204
 }
Ejemplo n.º 24
0
 /**
  * @param $url string
  * @return Mixed|String
  */
 function fetchScaryTemplateMaybeFromCache($url)
 {
     global $wgTranscludeCacheExpiry;
     $dbr = wfGetDB(DB_SLAVE);
     $tsCond = $dbr->timestamp(time() - $wgTranscludeCacheExpiry);
     $obj = $dbr->selectRow('transcache', array('tc_time', 'tc_contents'), array('tc_url' => $url, "tc_time >= " . $dbr->addQuotes($tsCond)));
     if ($obj) {
         return $obj->tc_contents;
     }
     $req = MWHttpRequest::factory($url);
     $status = $req->execute();
     // Status object
     if ($status->isOK()) {
         $text = $req->getContent();
     } elseif ($req->getStatus() != 200) {
         // Though we failed to fetch the content, this status is useless.
         return wfMessage('scarytranscludefailed-httpstatus', $url, $req->getStatus())->inContentLanguage()->text();
     } else {
         return wfMessage('scarytranscludefailed', $url)->inContentLanguage()->text();
     }
     $dbw = wfGetDB(DB_MASTER);
     $dbw->replace('transcache', array('tc_url'), array('tc_url' => $url, 'tc_time' => $dbw->timestamp(time()), 'tc_contents' => $text));
     return $text;
 }
Ejemplo n.º 25
0
 /**
  * Set read/write permissions for a Swift container
  *
  * @param $contObj CF_Container Swift container
  * @param $readGrps Array Swift users who can read (account:user)
  * @param $writeGrps Array Swift users who can write (account:user)
  * @return Status
  */
 protected function setContainerAccess(CF_Container $contObj, array $readGrps, array $writeGrps)
 {
     // Wikia change - begin
     // don't send multiple ACL requests for the same container over and over again (BAC-872)
     static $reqSent = [];
     $key = $contObj->name;
     $entry = implode(',', $readGrps) . '::' . implode(',', $writeGrps);
     if (isset($reqSent[$key]) && $reqSent[$key] === $entry) {
         wfDebug(__METHOD__ . ": ACL already set\n");
         return Status::newGood();
     }
     $reqSent[$key] = $entry;
     // Wikia change - end
     $creds = $contObj->cfs_auth->export_credentials();
     $url = $creds['storage_url'] . '/' . rawurlencode($contObj->name);
     wfDebug(sprintf("%s: %s (ACL - read: '%s', write: '%s')\n", __METHOD__, $url, implode(',', $readGrps), implode(',', $writeGrps)));
     // Wikia change
     // Note: 10 second timeout consistent with php-cloudfiles
     /* @var CurlHttpRequest $req */
     $req = MWHttpRequest::factory($url, array('method' => 'POST', 'timeout' => $this->swiftTimeout, 'noProxy' => true));
     $req->setHeader('X-Auth-Token', $creds['auth_token']);
     $req->setHeader('X-Container-Read', implode(',', $readGrps));
     $req->setHeader('X-Container-Write', implode(',', $writeGrps));
     return $req->execute();
     // should return 204
 }
Ejemplo n.º 26
0
 protected function getMicrosoftSuggestion($serviceName, $config)
 {
     global $wgMemc;
     $this->mustHaveDefinition();
     self::checkTranslationServiceFailure($serviceName);
     $code = $this->handle->getCode();
     $definition = trim(strval($this->getDefinition()));
     $definition = self::wrapUntranslatable($definition);
     $memckey = wfMemckey('translate-tmsug-badcodes-' . $serviceName);
     $unsupported = $wgMemc->get($memckey);
     if (isset($unsupported[$code])) {
         return null;
     }
     $options = array();
     $options['timeout'] = $config['timeout'];
     $params = array('text' => $definition, 'to' => $code);
     if (isset($config['key'])) {
         $params['appId'] = $config['key'];
     } else {
         return null;
     }
     $url = $config['url'] . '?' . wfArrayToCgi($params);
     $url = wfExpandUrl($url);
     $options['method'] = 'GET';
     if (class_exists('MWHttpRequest')) {
         $req = MWHttpRequest::factory($url, $options);
     } else {
         $req = HttpRequest::factory($url, $options);
     }
     $status = $req->execute();
     if (!$status->isOK()) {
         $error = $req->getContent();
         if (strpos($error, 'must be a valid language') !== false) {
             $unsupported[$code] = true;
             $wgMemc->set($memckey, $unsupported, 60 * 60 * 8);
             return null;
         }
         if ($error) {
             error_log(__METHOD__ . ': Http::get failed:' . $error);
         } else {
             error_log(__METHOD__ . ': Unknown error, grr');
         }
         // Most likely a timeout or other general error
         self::reportTranslationServiceFailure($serviceName);
     }
     $ret = $req->getContent();
     $text = preg_replace('~<string.*>(.*)</string>~', '\\1', $ret);
     $text = Sanitizer::decodeCharReferences($text);
     $text = self::unwrapUntranslatable($text);
     $text = $this->suggestionField($text);
     return Html::rawElement('div', null, self::legend($serviceName) . $text . self::clear());
 }
Ejemplo n.º 27
0
 /**
  * Scale a file with a remote "scaler", as exists on the Wikimedia Foundation cluster, and output it to STDOUT.
  * Note: unlike the usual thumbnail process, the web client never sees the cluster URL; we do the whole HTTP transaction to the scaler ourselves
  *  and cat the results out.
  * Note: We rely on NFS to have propagated the file contents to the scaler. However, we do not rely on the thumbnail being created in NFS and then
  *   propagated back to our filesystem. Instead we take the results of the HTTP request instead.
  * Note: no caching is being done here, although we are instructing the client to cache it forever.
  * @param $file: File object
  * @param $params: scaling parameters ( e.g. array( width => '50' ) );
  * @param $flags: scaling flags ( see File:: constants )
  * @throws MWException
  * @return boolean success
  */
 private function outputRemoteScaledThumb($file, $params, $flags)
 {
     // this global probably looks something like 'http://upload.wikimedia.org/wikipedia/test/thumb/temp'
     // do not use trailing slash
     global $wgUploadStashScalerBaseUrl;
     // We need to use generateThumbName() instead of thumbName(), because
     // the suffix needs to match the file name for the remote thumbnailer
     // to work
     $scalerThumbName = $file->generateThumbName($file->getName(), $params);
     $scalerThumbUrl = $wgUploadStashScalerBaseUrl . '/' . $file->getUrlRel() . '/' . rawurlencode($scalerThumbName);
     // make a curl call to the scaler to create a thumbnail
     $httpOptions = array('method' => 'GET', 'timeout' => 'default');
     $req = MWHttpRequest::factory($scalerThumbUrl, $httpOptions);
     $status = $req->execute();
     if (!$status->isOK()) {
         $errors = $status->getErrorsArray();
         $errorStr = "Fetching thumbnail failed: " . print_r($errors, 1);
         $errorStr .= "\nurl = {$scalerThumbUrl}\n";
         throw new MWException($errorStr);
     }
     $contentType = $req->getResponseHeader("content-type");
     if (!$contentType) {
         throw new MWException("Missing content-type header");
     }
     return $this->outputContents($req->getContent(), $contentType);
 }
Ejemplo n.º 28
0
 public function execute()
 {
     parent::execute();
     if (is_array($this->postData)) {
         $this->postData = wfArrayToCgi($this->postData);
     }
     if ($this->parsedUrl['scheme'] != 'http' && $this->parsedUrl['scheme'] != 'https') {
         $this->status->fatal('http-invalid-scheme', $this->parsedUrl['scheme']);
     }
     $this->reqHeaders['Accept'] = "*/*";
     $this->reqHeaders['Connection'] = 'Close';
     if ($this->method == 'POST') {
         // Required for HTTP 1.0 POSTs
         $this->reqHeaders['Content-Length'] = strlen($this->postData);
         if (!isset($this->reqHeaders['Content-Type'])) {
             $this->reqHeaders['Content-Type'] = "application/x-www-form-urlencoded";
         }
     }
     // Set up PHP stream context
     $options = ['http' => ['method' => $this->method, 'header' => implode("\r\n", $this->getHeaderList()), 'protocol_version' => '1.1', 'max_redirects' => $this->followRedirects ? $this->maxRedirects : 0, 'ignore_errors' => true, 'timeout' => $this->timeout, 'curl_verify_ssl_host' => $this->sslVerifyHost ? 2 : 0, 'curl_verify_ssl_peer' => $this->sslVerifyCert], 'ssl' => ['verify_peer' => $this->sslVerifyCert, 'SNI_enabled' => true, 'ciphers' => 'HIGH:!SSLv2:!SSLv3:-ADH:-kDH:-kECDH:-DSS', 'disable_compression' => true]];
     if ($this->proxy) {
         $options['http']['proxy'] = $this->urlToTcp($this->proxy);
         $options['http']['request_fulluri'] = true;
     }
     if ($this->postData) {
         $options['http']['content'] = $this->postData;
     }
     if ($this->sslVerifyHost) {
         // PHP 5.6.0 deprecates CN_match, in favour of peer_name which
         // actually checks SubjectAltName properly.
         if (version_compare(PHP_VERSION, '5.6.0', '>=')) {
             $options['ssl']['peer_name'] = $this->parsedUrl['host'];
         } else {
             $options['ssl']['CN_match'] = $this->parsedUrl['host'];
         }
     }
     $options['ssl'] += $this->getCertOptions();
     $context = stream_context_create($options);
     $this->headerList = [];
     $reqCount = 0;
     $url = $this->url;
     $result = [];
     if ($this->profiler) {
         $profileSection = $this->profiler->scopedProfileIn(__METHOD__ . '-' . $this->profileName);
     }
     do {
         $reqCount++;
         $this->fopenErrors = [];
         set_error_handler([$this, 'errorHandler']);
         $fh = fopen($url, "r", false, $context);
         restore_error_handler();
         if (!$fh) {
             // HACK for instant commons.
             // If we are contacting (commons|upload).wikimedia.org
             // try again with CN_match for en.wikipedia.org
             // as php does not handle SubjectAltName properly
             // prior to "peer_name" option in php 5.6
             if (isset($options['ssl']['CN_match']) && ($options['ssl']['CN_match'] === 'commons.wikimedia.org' || $options['ssl']['CN_match'] === 'upload.wikimedia.org')) {
                 $options['ssl']['CN_match'] = 'en.wikipedia.org';
                 $context = stream_context_create($options);
                 continue;
             }
             break;
         }
         $result = stream_get_meta_data($fh);
         $this->headerList = $result['wrapper_data'];
         $this->parseHeader();
         if (!$this->followRedirects) {
             break;
         }
         # Handle manual redirection
         if (!$this->isRedirect() || $reqCount > $this->maxRedirects) {
             break;
         }
         # Check security of URL
         $url = $this->getResponseHeader("Location");
         if (!Http::isValidURI($url)) {
             $this->logger->debug(__METHOD__ . ": insecure redirection\n");
             break;
         }
     } while (true);
     if ($this->profiler) {
         $this->profiler->scopedProfileOut($profileSection);
     }
     $this->setStatus();
     if ($fh === false) {
         if ($this->fopenErrors) {
             $this->logger->warning(__CLASS__ . ': error opening connection: {errstr1}', $this->fopenErrors);
         }
         $this->status->fatal('http-request-error');
         return $this->status;
     }
     if ($result['timed_out']) {
         $this->status->fatal('http-timed-out', $this->url);
         return $this->status;
     }
     // If everything went OK, or we received some error code
     // get the response body content.
     if ($this->status->isOK() || (int) $this->respStatus >= 300) {
         while (!feof($fh)) {
             $buf = fread($fh, 8192);
             if ($buf === false) {
                 $this->status->fatal('http-read-error');
                 break;
             }
             if (strlen($buf)) {
                 call_user_func($this->callback, $fh, $buf);
             }
         }
     }
     fclose($fh);
     return $this->status;
 }
Ejemplo n.º 29
0
 /**
  * Like a Http:get request, but with custom User-Agent.
  * @see Http:get
  */
 public static function httpGet($url, $timeout = 'default', $options = array())
 {
     $options['timeout'] = $timeout;
     /* Http::get */
     $url = wfExpandUrl($url, PROTO_HTTP);
     wfDebug("ForeignAPIRepo: HTTP GET: {$url}\n");
     $options['method'] = "GET";
     if (!isset($options['timeout'])) {
         $options['timeout'] = 'default';
     }
     $req = MWHttpRequest::factory($url, $options);
     $req->setUserAgent(ForeignAPIRepo::getUserAgent());
     $status = $req->execute();
     if ($status->isOK()) {
         return $req->getContent();
     } else {
         return false;
     }
 }
 /**
  * Convert from/to wikitext/html via Parsoid.
  *
  * This will assume Parsoid is installed.
  *
  * @param string $from Format of content to convert: html|wikitext
  * @param string $to Format to convert to: html|wikitext
  * @param string $content
  * @param Title $title
  * @return string
  * @throws NoParsoidException When parsoid configuration is not available
  * @throws WikitextException When conversion is unsupported
  */
 protected static function parsoid($from, $to, $content, Title $title)
 {
     list($parsoidURL, $parsoidPrefix, $parsoidTimeout, $parsoidForwardCookies) = self::parsoidConfig();
     if ($from == 'html') {
         $from = 'html';
     } elseif (in_array($from, array('wt', 'wikitext'))) {
         $from = 'wt';
     } else {
         throw new WikitextException('Unknown source format: ' . $from, 'process-wikitext');
     }
     $params = array($from => $content, 'body' => true);
     if ($from === 'html') {
         $params['scrubWikitext'] = 'true';
     }
     $prefixedDbTitle = $title->getPrefixedDBkey();
     $request = \MWHttpRequest::factory($parsoidURL . '/' . $parsoidPrefix . '/' . urlencode($prefixedDbTitle), array('method' => 'POST', 'postData' => wfArrayToCgi($params), 'timeout' => $parsoidTimeout, 'connectTimeout' => 'default'));
     if ($parsoidForwardCookies && !User::isEveryoneAllowed('read')) {
         if (PHP_SAPI === 'cli') {
             // From the command line we need to generate a cookie
             $cookies = self::generateForwardedCookieForCli();
         } else {
             $cookies = RequestContext::getMain()->getRequest()->getHeader('Cookie');
         }
         $request->setHeader('Cookie', $cookies);
     }
     $status = $request->execute();
     if (!$status->isOK()) {
         $statusMsg = $status->getMessage()->text();
         $msg = "Failed contacting Parsoid for title \"{$prefixedDbTitle}\": {$statusMsg}";
         wfDebugLog('Flow', __METHOD__ . ": {$msg}");
         throw new NoParsoidException("{$msg}", 'process-wikitext');
     }
     return $request->getContent();
 }