/** * Static function wrapping RSSParser to handle rendering of RSS elements * @param $input String: text inside the tags. * @param $args Array: value associative list of the element attributes and * their values. * @param $parser Parser * @param $frame PPFrame parser context */ static function renderRss($input, $args, $parser, $frame) { global $wgRSSCacheAge, $wgRSSCacheCompare, $wgRSSNamespaces, $wgRSSAllowedFeeds; if (is_array($wgRSSNamespaces) && count($wgRSSNamespaces)) { $ns = $parser->getTitle()->getNamespace(); $checkNS = array_flip($wgRSSNamespaces); if (!isset($checkNS[$ns])) { return wfMsg('rss-ns-permission'); } } if (count($wgRSSAllowedFeeds) && !in_array($input, $wgRSSAllowedFeeds)) { return wfMsg('rss-url-permission'); } if (!Http::isValidURI($input)) { return wfMsg('rss-invalid-url', htmlspecialchars($input)); } if ($wgRSSCacheCompare) { $timeout = $wgRSSCacheCompare; } else { $timeout = $wgRSSCacheAge; } $parser->getOutput()->updateCacheExpiry($timeout); $rss = new RSSParser($input, $args); $status = $rss->fetch(); # Check for errors. if (!$status->isGood()) { return wfMsg('rss-error', htmlspecialchars($input), $status->getWikiText()); } if (!is_object($rss->rss) || !is_array($rss->rss->items)) { return wfMsg('rss-empty', htmlspecialchars($input)); } return $rss->renderFeed($parser, $frame); }
public function execute($sub) { global $wgOut, $wgRequest; global $wgLandingPageBase, $wgChapterLandingPages, $wgLandingPageDefaultTarget; $lang = preg_match('/^[A-Za-z-]+$/', $wgRequest->getVal('lang')) ? $wgRequest->getVal('lang') : 'en'; $utm_source = $wgRequest->getVal('utm_source'); $utm_medium = $wgRequest->getVal('utm_medium'); $utm_campaign = $wgRequest->getVal('utm_campaign'); $referrer = $wgRequest->getHeader('referer'); $target = $wgRequest->getVal('target', null); if (!$target) { $target = $wgLandingPageDefaultTarget; } $tracking = '?' . wfArrayToCGI(array('utm_source' => "{$utm_source}", 'utm_medium' => "{$utm_medium}", 'utm_campaign' => "{$utm_campaign}", 'referrer' => "{$referrer}", 'target' => "{$target}")); $ip = $wgRequest->getVal('ip') ? $wgRequest->getVal('ip') : wfGetIP(); if (IP::isValid($ip)) { $country = geoip_country_code_by_name($ip); if (is_string($country) && array_key_exists($country, $wgChapterLandingPages)) { $wgOut->redirect($this->getDestination($utm_source) . '/' . $wgChapterLandingPages[$country] . $tracking); return; } } // No valid IP or chapter page - let's just go for the passed in url or our fallback if (Http::isValidURI($target)) { $wgOut->redirect($target . '/' . $lang . $tracking); return; } else { $wgOut->redirect($wgLandingPageBase . $target . '/' . $lang . $tracking); } }
public function fetchFile() { if (!Http::isValidURI($this->mUrl)) { return Status::newFatal('http-invalid-url'); } if (!$this->mAsync) { return $this->reallyFetchFile(); } return Status::newGood(); }
public function __construct(WebRequest $request) { parent::__construct($request); global $IP, $wgUser; $ac = new AssetsConfig(); $assets = $ac->resolve($this->mOid, true, !isset($this->mParams['minify']) || $this->mParams['minify'] == true, $this->mParams); $this->mContentType = $ac->getGroupType($this->mOid); foreach ($assets as $asset) { // reference to a file to be fetched by the browser from external server (BugId:9522) if (substr($asset, 0, 10) == '#external_') { // do nothing } else { if (Http::isValidURI($asset)) { $params = array(); $url = parse_url($asset); if (isset($url['query'])) { parse_str($url['query'], $params); } // Start checking the url to see if it is something we care about (BugId:30188) if (isset($params['action']) && $params['action'] == 'raw' && isset($params['gen']) && $params['gen'] == 'js') { //$this->mContent .= RequestContext::getMain()->getSkin()->generateUserJs(); // FIXME } else { if (isset($params['action']) && $params['action'] == 'raw' && isset($params['gen']) && $params['gen'] == 'css') { //$this->mContent .= RequestContext::getMain()->getSkin()->generateUserStylesheet(); // FIXME } else { //Debug added on May 4, 2012 to inquire external requests spikes $start = microtime(true); $this->mContent .= HTTP::get($asset); $totalTime = microtime(true) - $start; if ($totalTime >= 1) { Wikia::log(__METHOD__, false, "oid: {$this->mOid}, totalTime: {$totalTime}, asset: {$asset}, referrer: {$_SERVER['HTTP_REFERER']}, entrypoint: {$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}", true); } } } } else { $this->mContent .= file_get_contents($IP . '/' . $asset); } } if ($this->mContentType == AssetsManager::TYPE_JS) { // add semicolon to separate concatenated files (BugId:20272) // but only for JS (BugId:20824) $this->mContent .= ";\n"; } } // For RTE only // TODO: add "filters" definitions to config.php if ($this->mOid == 'rte' || $this->mOid == 'eplrte' || $this->mOid == 'mini_editor_rte_js') { $this->mContent = preg_replace('#^.*@Packager\\.RemoveLine.*$#m', '', $this->mContent); $this->mContent = str_replace("", '', $this->mContent); } }
/** Build $this->messages array */ private function initMessagesHref() { # List of default messages for the sidebar. The sidebar doesn't care at # all whether they are full URLs, interwiki links or local titles. $URL_messages = array('mainpage', 'portal-url', 'currentevents-url', 'recentchanges-url', 'randompage-url', 'helppage'); # We're assuming that isValidURI works as advertised: it's also # tested separately, in tests/phpunit/includes/HttpTest.php. foreach ($URL_messages as $m) { $titleName = MessageCache::singleton()->get($m); if (Http::isValidURI($titleName)) { $this->messages[$m]['href'] = $titleName; } else { $title = Title::newFromText($titleName); $this->messages[$m]['href'] = $title->getLocalURL(); } } }
/** * Test Http::isValidURI() * @bug 27854 : Http::isValidURI is too lax * @dataProvider provideURI * @covers Http::isValidURI */ public function testIsValidUri($expect, $URI, $message = '') { $this->assertEquals($expect, (bool) Http::isValidURI($URI), $message); }
public static function isValidURI($url) { return Http::isValidURI($url) || UploadFromUrl::isValidBase64($url); }
/** * @return Status */ public function fetchFile() { if (!Http::isValidURI($this->mUrl)) { return Status::newFatal('http-invalid-url'); } if (!self::isAllowedHost($this->mUrl)) { return Status::newFatal('upload-copy-upload-invalid-domain'); } if (!$this->mAsync) { return $this->reallyFetchFile(); } return Status::newGood(); }
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; }
/** * Download the file * * @param array $httpOptions Array of options for MWHttpRequest. * This could be used to override the timeout on the http request. * @return Status */ public function fetchFile($httpOptions = []) { if (!Http::isValidURI($this->mUrl)) { return Status::newFatal('http-invalid-url', $this->mUrl); } if (!self::isAllowedHost($this->mUrl)) { return Status::newFatal('upload-copy-upload-invalid-domain'); } if (!self::isAllowedUrl($this->mUrl)) { return Status::newFatal('upload-copy-upload-invalid-url'); } return $this->reallyFetchFile($httpOptions); }
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; }
/** * Based on the array of items resolves it into array of assets * Parameters $combine, $minify and $params are eventually passed to custom function (look at #function_) which may deliver different set of assets based on them * * @author Inez Korczyński <*****@*****.**> */ private function resolveItemsToAssets($items, $combine, $minify, $params) { $assets = array(); foreach ($items as $item) { if (substr($item, 0, 2) == '//') { // filepath - most typical case $assets[] = substr($item, 2); } elseif (substr($item, 0, 7) == '#group_') { // reference to another group $assets = array_merge($assets, $this->resolve(substr($item, 7), $combine, $minify, $params)); } elseif (substr($item, 0, 10) == '#function_') { // reference to a function that returns array of URIs $assets = array_merge($assets, call_user_func(substr($item, 10), $combine, $minify, $params)); } elseif (substr($item, 0, 10) == '#external_') { // reference to a file to be fetched by the browser from external server (BugId:9522) $assets[] = $item; } elseif (Http::isValidURI($item)) { // reference to remote file (http and https) $assets[] = $item; } } return $assets; }
/** * @author Inez Korczyński <*****@*****.**> * @return array Array of one or many URLs */ private function getGroupURL($groupName, $params, $prefix, $combine, $minify) { wfProfileIn(__METHOD__); //lazy loading of AssetsConfig $this->loadConfig(); // pass noexternals mode (BugId:28143) global $wgNoExternals; if (!empty($wgNoExternals)) { $params['noexternals'] = 1; } $assets = $this->mAssetsConfig->resolve($groupName, $this->mCombine, $this->mMinify, $params); $URLs = array(); if ($combine !== null ? $combine : $this->mCombine) { // "minify" is a special parameter that can be set only when initialising object and can not be overwritten per request if ($minify !== null ? !$minify : !$this->mMinify) { $params['minify'] = false; } else { unset($params['minify']); } // check for an #external_ URL being in the package (BugId:9522) $isEmpty = true; foreach ($assets as $asset) { if (substr($asset, 0, 10) == '#external_') { $URLs[] = substr($asset, 10); } else { $isEmpty = false; } } // add info about noexternals mode to AssetsManager URL (BugId:28143) global $wgNoExternals; if (!empty($wgNoExternals)) { $params['noexternals'] = 1; } // When AssetsManager works in "combine" mode return URL to the combined package if (!$isEmpty) { $url = $prefix . $this->getAMLocalURL('group', $groupName, $params); // apply domain sharding $url = wfReplaceAssetServer($url); $URLs[] = $url; } } else { foreach ($assets as $asset) { if (substr($asset, 0, 10) == '#external_') { $url = substr($asset, 10); } else { if (Http::isValidURI($asset)) { $url = $asset; } else { // We always need to use common host for static assets since it has // the information about the slot which is otherwise not available // in varnish (BugId: 33905) $url = $this->getOneCommonURL($asset, $minify); } } // apply domain sharding $url = wfReplaceAssetServer($url); $URLs[] = $url; } } $this->mGeneratedUrls += array_fill_keys($URLs, $groupName); wfProfileOut(__METHOD__); return $URLs; }
/** * @param $url String: url to use * @param $options Array: (optional) extra params to pass (see Http::request()) */ function __construct($url, $options = array()) { global $wgHTTPTimeout; $this->url = $url; $this->parsedUrl = parse_url($url); if (!Http::isValidURI($this->url)) { $this->status = Status::newFatal('http-invalid-url'); } else { $this->status = Status::newGood(100); // continue } if (isset($options['timeout']) && $options['timeout'] != 'default') { $this->timeout = $options['timeout']; } else { $this->timeout = $wgHTTPTimeout; } $members = array("postData", "proxy", "noProxy", "sslVerifyHost", "caInfo", "method", "followRedirects", "maxRedirects", "sslVerifyCert"); foreach ($members as $o) { if (isset($options[$o])) { $this->{$o} = $options[$o]; } } }
/** * @param string $url Url to use. If protocol-relative, will be expanded to an http:// URL * @param array $options (optional) extra params to pass (see Http::request()) * @param string $caller The method making this request, for profiling * @param Profiler $profiler An instance of the profiler for profiling, or null */ protected function __construct($url, $options = [], $caller = __METHOD__, $profiler = null) { global $wgHTTPTimeout, $wgHTTPConnectTimeout; $this->url = wfExpandUrl($url, PROTO_HTTP); $this->parsedUrl = wfParseUrl($this->url); if (isset($options['logger'])) { $this->logger = $options['logger']; } else { $this->logger = new NullLogger(); } if (!$this->parsedUrl || !Http::isValidURI($this->url)) { $this->status = Status::newFatal('http-invalid-url', $url); } else { $this->status = Status::newGood(100); // continue } if (isset($options['timeout']) && $options['timeout'] != 'default') { $this->timeout = $options['timeout']; } else { $this->timeout = $wgHTTPTimeout; } if (isset($options['connectTimeout']) && $options['connectTimeout'] != 'default') { $this->connectTimeout = $options['connectTimeout']; } else { $this->connectTimeout = $wgHTTPConnectTimeout; } if (isset($options['userAgent'])) { $this->setUserAgent($options['userAgent']); } $members = ["postData", "proxy", "noProxy", "sslVerifyHost", "caInfo", "method", "followRedirects", "maxRedirects", "sslVerifyCert", "callback"]; foreach ($members as $o) { if (isset($options[$o])) { // ensure that MWHttpRequest::method is always // uppercased. Bug 36137 if ($o == 'method') { $options[$o] = strtoupper($options[$o]); } $this->{$o} = $options[$o]; } } if ($this->noProxy) { $this->proxy = ''; // noProxy takes precedence } // Profile based on what's calling us $this->profiler = $profiler; $this->profileName = $caller; }
/** * Load quiz data (try to use cache layer) */ private function load($master = false) { global $wgMemc; wfProfileIn(__METHOD__); if (!$master) { $this->mData = $wgMemc->get($this->mMemcacheKey); } if (empty($this->mData)) { $article = Article::newFromID($this->mQuizId); // check quiz existence if (empty($article)) { wfDebug(__METHOD__ . ": quiz doesn't exist\n"); wfProfileOut(__METHOD__); return; } // get quiz's author and creation timestamp $title = $article->getTitle(); $firstRev = $title->getFirstRevision(); $titleText = $title->getText(); $titleScreenText = ''; $fbRecommendationText = ''; $images = array(); $imageShorts = array(); $moreInfoHeading = ''; $moreInfoLinks = array(); // parse wikitext containing quiz data $content = $article->getContent(); $lines = explode("\n", $content); foreach ($lines as $line) { if (startsWith($line, self::TITLESCREENTEXT_MARKER)) { $titleScreenText = trim(substr($line, strlen(self::TITLESCREENTEXT_MARKER))); } elseif (startsWith($line, self::FBRECOMMENDATIONTEXT_MARKER)) { $fbRecommendationText = trim(substr($line, strlen(self::FBRECOMMENDATIONTEXT_MARKER))); } elseif (startsWith($line, self::IMAGE_MARKER)) { $imageShort = trim(substr($line, strlen(self::IMAGE_MARKER))); $images[] = $this->getImageSrc($imageShort); $imageShorts[] = $imageShort; } elseif (startsWith($line, self::MOREINFOHEADING_MARKER)) { $moreInfoHeading = trim(substr($line, strlen(self::MOREINFOHEADING_MARKER))); } elseif (startsWith($line, self::MOREINFOLINK_MARKER)) { $moreInfo = substr($line, strlen(self::MOREINFOLINK_MARKER)); $moreInfoChunks = explode(self::MOREINFOLINK_TEXT_MARKER, $moreInfo); if (Http::isValidURI($moreInfoChunks[0])) { $moreInfoUrl = $moreInfoChunks[0]; } else { $title = Title::newFromText($moreInfoChunks[0]); $moreInfoUrl = $title->getFullUrl(); } $moreInfoLinks[] = array('article' => $moreInfoChunks[0], 'url' => $moreInfoUrl, 'text' => isset($moreInfoChunks[1]) ? $moreInfoChunks[1] : ''); } elseif (startsWith($line, self::REQUIRE_EMAIL_MARKER)) { $line = substr($line, strlen(self::REQUIRE_EMAIL_MARKER)); $requireEmail = $line == 'true'; } } // load quiz's elements if (empty($this->mCategory)) { $catName = self::QUIZ_CATEGORY_PREFIX . $titleText; $cat = Category::newFromName($catName); $this->mCategory = $cat; } $quizElements = array(); if (empty($this->mCategory) || !$this->mCategory->getID()) { wfDebug(__METHOD__ . ": quiz's category doesn't exist\n"); } else { // get quiz elements $quizIterator = $this->mCategory->getMembers(); while ($quizElementTitle = $quizIterator->current()) { $quizElement = WikiaQuizElement::newFromId($quizElementTitle->getArticleId()); $quizElements[] = $quizElement->getData(); $quizIterator->next(); } } $this->mData = array('id' => $this->mQuizId, 'name' => $titleText, 'requireEmail' => !empty($requireEmail), 'elements' => $quizElements, 'titlescreentext' => $titleScreenText, 'fbrecommendationtext' => $fbRecommendationText, 'images' => $images, 'imageShorts' => $imageShorts, 'moreinfoheading' => $moreInfoHeading, 'moreinfo' => $moreInfoLinks); wfDebug(__METHOD__ . ": loaded from scratch\n"); // store it in memcache $wgMemc->set($this->mMemcacheKey, $this->mData, self::CACHE_TTL); } else { wfDebug(__METHOD__ . ": loaded from memcache\n"); } $this->mExists = true; wfProfileOut(__METHOD__); return; }
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'] = "*/*"; $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 = array('http' => array('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' => array('verify_peer' => $this->sslVerifyCert, 'SNI_enabled' => 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) { $options['ssl']['CN_match'] = $this->parsedUrl['host']; } if (is_dir($this->caInfo)) { $options['ssl']['capath'] = $this->caInfo; } elseif (is_file($this->caInfo)) { $options['ssl']['cafile'] = $this->caInfo; } elseif ($this->caInfo) { throw new MWException("Invalid CA info passed: {$this->caInfo}"); } $context = stream_context_create($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; }
private static function parseCreateEditQuizRequest(WebRequest $request, $quiz, &$error) { $wgUser = F::app()->getGlobal('wgUser'); $wgLang = F::app()->getGlobal('wgContLang'); // parse quiz fields $quizContent = ''; // title if (!empty($quiz)) { $title = $quiz->getTitle(); } else { $title = trim($request->getVal('title')); } // title screen text $titleScreenText = trim($request->getVal('titlescreentext')); if ($titleScreenText) { $quizContent .= WikiaQuiz::TITLESCREENTEXT_MARKER . $titleScreenText . "\n"; } // facebook recommendation description $fbRecommendationText = trim($request->getVal('fbrecommendationtext')); if ($fbRecommendationText) { $quizContent .= WikiaQuiz::FBRECOMMENDATIONTEXT_MARKER . $fbRecommendationText . "\n"; } // title screen images $titleScreenImages = $request->getArray('titlescreenimage'); foreach ($titleScreenImages as $image) { if ($image) { if (!self::isValidImage($image)) { $error = wfMsg('wikiaquiz-error-invalid-image', $image); return; } $quizContent .= WikiaQuiz::IMAGE_MARKER . $image . "\n"; } } // More Info heading $moreInfoHeading = trim($request->getVal('moreinfoheading')); if ($moreInfoHeading) { $quizContent .= WikiaQuiz::MOREINFOHEADING_MARKER . $moreInfoHeading . "\n"; } // Are emails required? if ($request->getCheck('requireemail')) { $quizContent .= WikiaQuiz::REQUIRE_EMAIL_MARKER . "true\n"; } // More Info links $moreInfoArticles = $request->getArray('moreinfoarticle'); $moreInfoLinkTexts = $request->getArray('moreinfolinktext'); foreach ($moreInfoArticles as $index => $articleName) { if ($articleName) { $moreInfoLinkText = isset($moreInfoLinkTexts[$index]) ? $moreInfoLinkTexts[$index] : ''; if (Http::isValidURI($articleName)) { $quizContent .= WikiaQuiz::MOREINFOLINK_MARKER . $articleName . WikiaQuiz::MOREINFOLINK_TEXT_MARKER . $moreInfoLinkText . "\n"; } else { $title_object = F::build('Title', array($articleName), 'newFromText'); if (is_object($title_object) && $title_object->exists()) { $quizContent .= WikiaQuiz::MOREINFOLINK_MARKER . $articleName . WikiaQuiz::MOREINFOLINK_TEXT_MARKER . $moreInfoLinkText . "\n"; } else { $error = wfMsg('wikiaquiz-error-invalid-article-with-details', $articleName); return; } } } } $patternCategory = "/\\[\\[" . $wgLang->getNsText(NS_CATEGORY) . "\\:" . WikiaQuiz::QUIZ_CATEGORY_PREFIX . $title . "(\\|(.+))*\\]\\]/"; //process questions (quizelements) $questions = $request->getArray('question'); foreach ($questions as $index => $question) { $question = trim($question); if (!$question) { continue; } $title_object = F::build('Title', array($question, NS_WIKIA_QUIZARTICLE), 'newFromText'); if (is_object($title_object) && $title_object->exists()) { // update category tag $article = F::build('Article', array($title_object)); $content = $article->getContent(); $newContent = null; $matches = null; preg_match($patternCategory, $content, $matches); if (isset($matches[2])) { if ($matches[2] != $index) { $replace = "[[" . $wgLang->getNsText(NS_CATEGORY) . ":" . WikiaQuiz::QUIZ_CATEGORY_PREFIX . $title . "|" . $index . "]]"; $newContent = preg_replace($patternCategory, $replace, $content); } } else { // this category is new for this article. append to contents. $newContent .= self::getCategoryText($title, $index); } if ($newContent) { $status = $article->doEdit($newContent, 'Quiz Question and Answers Updated', EDIT_UPDATE, false, $wgUser); } } else { if ($title_object == null) { $error = wfMsg('wikiaquiz-error-invalid-question'); return; } else { // create question $content = self::getCategoryText($title, $index); $article = F::build('Article', array($title_object)); $status = $article->doEdit($content, 'Quiz Article Created', EDIT_NEW, false, $wgUser); //@todo check status } } } if (!empty($quiz)) { // remove old questions from quiz $questionKeys = array_flip($questions); $elements = $quiz->getElements(); if (is_array($elements)) { foreach ($elements as $element) { $question = trim($element['title']); if ($question) { if (!array_key_exists($question, $questionKeys)) { $title_object = F::build('Title', array($question, NS_WIKIA_QUIZARTICLE), 'newFromText'); $article = F::build('Article', array($title_object)); $content = $article->getContent(); $content = preg_replace($patternCategory, '', $content); $status = $article->doEdit($content, 'Quiz Question and Answers Updated', EDIT_UPDATE, false, $wgUser); } } } } } return $quizContent; }