Linux anchor 4.4.0-210-generic #242-Ubuntu SMP Fri Apr 16 09:57:56 UTC 2021 x86_64
Apache/2.4.18 (Ubuntu)
Server IP : 10.10.100.4 & Your IP : 216.73.217.150
Domains :
Cant Read [ /etc/named.conf ]
User : www-data
Terminal
Auto Root
Create File
Create Folder
Localroot Suggester
Backdoor Destroyer
Readme
/
var /
www /
wiki.bernardino.org /
includes /
Delete
Unzip
Name
Size
Permission
Date
Action
actions
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
api
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
auth
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
cache
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
changes
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
changetags
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
clientpool
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
collation
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
compat
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
composer
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
config
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
content
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
context
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
dao
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
db
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
debug
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
deferred
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
diff
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
exception
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
export
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
extauth
[ DIR ]
drwxr-xr-x
2012-03-22 16:23
externalstore
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
filebackend
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
filerepo
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
gallery
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
htmlform
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
http
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
import
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
installer
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
interwiki
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
job
[ DIR ]
drwxr-xr-x
2012-03-22 16:23
jobqueue
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
json
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
libs
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
linker
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
logging
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
mail
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
media
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
normal
[ DIR ]
drwxr-xr-x
2012-03-22 16:23
objectcache
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
page
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
pager
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
parser
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
password
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
poolcounter
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
profiler
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
rcfeed
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
registration
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
resourceloader
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
revisiondelete
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
search
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
services
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
session
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
site
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
skins
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
specialpage
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
specials
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
templates
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
tidy
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
title
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
upload
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
user
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
utils
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
widget
[ DIR ]
drwxr-xr-x
2016-11-28 20:20
zhtable
[ DIR ]
drwxr-xr-x
2012-03-22 16:23
.htaccess
197
B
-r--r--r--
2026-08-22 08:29
Action.php
12.43
KB
-rw-r--r--
2011-09-16 17:01
AjaxDispatcher.php
4.03
KB
-rw-r--r--
2016-11-28 20:20
AjaxResponse.php
8.15
KB
-rw-r--r--
2016-11-28 20:20
Article.php
58.64
KB
-rw-r--r--
2011-11-15 20:46
AuthPlugin.php
9.2
KB
-rw-r--r--
2016-11-28 20:20
AutoLoader.php
3
KB
-rw-r--r--
2016-11-28 20:20
Autopromote.php
6.77
KB
-rw-r--r--
2016-11-28 20:20
BacklinkCache.php
9.03
KB
-rw-r--r--
2011-06-30 01:09
Block.php
41.97
KB
-rw-r--r--
2016-11-28 20:20
Category.php
10.34
KB
-rw-r--r--
2016-11-28 20:20
CategoryFinder.php
6.2
KB
-rw-r--r--
2016-11-28 20:20
CategoryPage.php
21.84
KB
-rw-r--r--
2011-10-28 23:20
CategoryViewer.php
22.5
KB
-rw-r--r--
2016-11-28 20:20
Categoryfinder.php
5.13
KB
-rw-r--r--
2011-05-19 02:03
Cdb.php
3.57
KB
-rw-r--r--
2011-05-28 20:58
Cdb_PHP.php
10.11
KB
-rw-r--r--
2011-05-28 19:51
ChangeTags.php
6.66
KB
-rw-r--r--
2011-07-09 11:01
ChangesFeed.php
5.82
KB
-rw-r--r--
2011-06-19 07:45
ChangesList.php
35.52
KB
-rw-r--r--
2011-10-25 23:51
Collation.php
9.86
KB
-rw-r--r--
2011-09-21 00:36
ConfEditor.php
29.16
KB
-rw-r--r--
2011-08-27 21:28
Cookie.php
6.17
KB
-rw-r--r--
2011-06-02 00:35
CryptRand.php
16.96
KB
-rw-r--r--
2012-03-21 11:43
DefaultSettings.php
265.47
KB
-rw-r--r--
2016-11-28 20:20
Defines.php
7.85
KB
-rw-r--r--
2016-11-28 20:20
DeprecatedGlobal.php
1.9
KB
-rw-r--r--
2016-11-28 20:20
DerivativeRequest.php
2.46
KB
-rw-r--r--
2016-11-28 20:20
DjVuImage.php
10.58
KB
-rw-r--r--
2011-05-18 00:03
DummyLinker.php
9.01
KB
-rw-r--r--
2016-11-28 20:20
EditPage.php
136.53
KB
-rw-r--r--
2016-11-28 20:20
EventRelayerGroup.php
1.27
KB
-rw-r--r--
2016-11-28 20:20
Exception.php
11.5
KB
-rw-r--r--
2011-10-22 04:34
Export.php
32.27
KB
-rw-r--r--
2011-11-24 02:29
ExternalEdit.php
2.45
KB
-rw-r--r--
2011-09-07 22:14
ExternalStore.php
4.29
KB
-rw-r--r--
2011-05-29 16:24
ExternalStoreDB.php
4.44
KB
-rw-r--r--
2011-10-17 00:24
ExternalStoreHttp.php
463
B
-rw-r--r--
2010-01-08 22:35
ExternalUser.php
8.96
KB
-rw-r--r--
2011-05-26 21:52
FakeTitle.php
6.6
KB
-rw-r--r--
2011-05-26 22:38
Fallback.php
5.49
KB
-rw-r--r--
2011-05-28 20:58
FauxRequest.php
5.66
KB
-rw-r--r--
2016-11-28 20:20
Feed.php
10.58
KB
-rw-r--r--
2016-11-28 20:20
FeedUtils.php
8.64
KB
-rw-r--r--
2016-11-28 20:20
FileDeleteForm.php
11.7
KB
-rw-r--r--
2016-11-28 20:20
ForkController.php
5.4
KB
-rw-r--r--
2016-11-28 20:20
FormOptions.php
11.08
KB
-rw-r--r--
2016-11-28 20:20
GenderCache.php
3.35
KB
-rw-r--r--
2011-09-19 14:58
GitInfo.php
10.74
KB
-rw-r--r--
2016-11-28 20:20
GlobalFunctions.php
106.76
KB
-rw-r--r--
2016-11-28 20:20
HTMLForm.php
49.55
KB
-rw-r--r--
2011-11-09 18:04
HistoryBlob.php
16.15
KB
-rw-r--r--
2016-11-28 20:20
HistoryPage.php
21.66
KB
-rw-r--r--
2011-09-16 16:12
Hooks.php
6.47
KB
-rw-r--r--
2016-11-28 20:20
Html.php
31.91
KB
-rw-r--r--
2016-11-28 20:20
HtmlFormatter.php
1015
B
-rw-r--r--
2016-11-28 20:20
HttpFunctions.old.php
319
B
-rw-r--r--
2011-05-28 17:59
HttpFunctions.php
21.28
KB
-rw-r--r--
2011-09-16 15:19
IP.php
21.58
KB
-rw-r--r--
2011-11-09 16:00
ImageFunctions.php
2.58
KB
-rw-r--r--
2011-05-29 16:24
ImageGallery.php
10.46
KB
-rw-r--r--
2011-07-16 01:18
ImagePage.php
36
KB
-rw-r--r--
2011-07-11 02:39
ImageQueryPage.php
1.5
KB
-rw-r--r--
2011-05-26 21:21
Import.php
33.63
KB
-rw-r--r--
2011-10-28 23:20
Init.php
4.67
KB
-rw-r--r--
2011-06-17 01:40
Licenses.php
4.89
KB
-rw-r--r--
2016-11-28 20:20
LinkFilter.php
6.08
KB
-rw-r--r--
2016-11-28 20:20
Linker.php
72.71
KB
-rw-r--r--
2016-11-28 20:20
LinksUpdate.php
23.7
KB
-rw-r--r--
2011-11-14 21:58
ListToggle.php
2.02
KB
-rw-r--r--
2016-11-28 20:20
LocalisationCache.php
29.31
KB
-rw-r--r--
2011-09-12 17:03
LogEventsList.php
32.56
KB
-rw-r--r--
2011-07-10 20:12
LogPage.php
16.09
KB
-rw-r--r--
2011-07-10 20:12
MWFunction.php
1.96
KB
-rw-r--r--
2011-03-22 21:23
MWGrants.php
5.85
KB
-rw-r--r--
2016-11-28 20:20
MWNamespace.php
13.76
KB
-rw-r--r--
2016-11-28 20:20
MWTimestamp.php
6.1
KB
-rw-r--r--
2016-11-28 20:20
MagicWord.php
15.1
KB
-rw-r--r--
2016-11-28 20:20
MagicWordArray.php
7.86
KB
-rw-r--r--
2016-11-28 20:20
MediaWiki.php
35.29
KB
-rw-r--r--
2016-11-28 20:20
MediaWikiServices.php
18.8
KB
-rw-r--r--
2016-11-28 20:20
MediaWikiVersionFetcher.php
746
B
-rw-r--r--
2016-11-28 20:20
MergeHistory.php
10.41
KB
-rw-r--r--
2016-11-28 20:20
Message.php
32.49
KB
-rw-r--r--
2016-11-28 20:20
MessageBlobStore.php
10.5
KB
-rw-r--r--
2011-05-28 00:42
Metadata.php
5.53
KB
-rw-r--r--
2011-06-30 00:09
MimeMagic.php
2.87
KB
-rw-r--r--
2016-11-28 20:20
MovePage.php
18.08
KB
-rw-r--r--
2016-11-28 20:20
Namespace.php
7.78
KB
-rw-r--r--
2011-05-21 21:07
NoLocalSettings.php
2.03
KB
-rw-r--r--
2016-11-28 20:20
OutputHandler.php
6.19
KB
-rw-r--r--
2016-11-28 20:20
OutputPage.php
113
KB
-rw-r--r--
2016-11-28 20:20
PHPVersionCheck.php
8.52
KB
-rw-r--r--
2016-11-28 20:20
PHPVersionError.php
2.96
KB
-rw-r--r--
2011-07-19 01:06
PageProps.php
8.52
KB
-rw-r--r--
2016-11-28 20:20
PageQueryPage.php
680
B
-rw-r--r--
2010-12-22 15:16
Pager.php
30.89
KB
-rw-r--r--
2011-07-06 04:26
PathRouter.php
12.43
KB
-rw-r--r--
2016-11-28 20:20
PatrolLog.php
2.53
KB
-rw-r--r--
2011-07-10 20:12
Pingback.php
7.31
KB
-rw-r--r--
2016-11-28 20:20
PoolCounter.php
5.65
KB
-rw-r--r--
2011-05-28 21:00
Preferences.php
51.21
KB
-rw-r--r--
2016-11-28 20:20
PrefixSearch.php
12.36
KB
-rw-r--r--
2016-11-28 20:20
ProtectionForm.php
19.56
KB
-rw-r--r--
2016-11-28 20:20
ProxyLookup.php
2.12
KB
-rw-r--r--
2016-11-28 20:20
ProxyTools.php
4.6
KB
-rw-r--r--
2011-09-07 22:14
QueryPage.php
22.76
KB
-rw-r--r--
2011-10-17 00:24
RawPage.php
6.2
KB
-rw-r--r--
2011-07-05 23:28
RecentChange.php
23.52
KB
-rw-r--r--
2011-08-27 21:28
RequestContext.php
7.85
KB
-rw-r--r--
2012-01-04 02:07
Revision.php
54.61
KB
-rw-r--r--
2016-11-28 20:20
RevisionList.php
9.25
KB
-rw-r--r--
2016-11-28 20:20
Sanitizer.php
58.04
KB
-rw-r--r--
2016-11-28 20:20
SeleniumWebSettings.php
6.3
KB
-rw-r--r--
2011-06-26 01:27
ServiceWiring.php
11.72
KB
-rw-r--r--
2016-11-28 20:20
Setup.php
27.89
KB
-rw-r--r--
2016-11-28 20:20
SiteConfiguration.php
18.34
KB
-rw-r--r--
2016-11-28 20:20
SiteStats.php
9.85
KB
-rw-r--r--
2016-11-28 20:20
Skin.php
42.13
KB
-rw-r--r--
2012-02-25 16:23
SkinLegacy.php
22.82
KB
-rw-r--r--
2011-10-20 22:50
SkinTemplate.php
64.93
KB
-rw-r--r--
2011-12-09 21:31
SpecialPage.php
31.23
KB
-rw-r--r--
2012-01-04 02:07
SpecialPageFactory.php
17.68
KB
-rw-r--r--
2011-10-28 23:20
SquidPurgeClient.php
10.02
KB
-rw-r--r--
2011-05-21 21:54
Status.php
12.63
KB
-rw-r--r--
2016-11-28 20:20
StreamFile.php
4.66
KB
-rw-r--r--
2016-11-28 20:20
StringUtils.php
11.32
KB
-rw-r--r--
2011-05-21 21:54
StubObject.php
6.4
KB
-rw-r--r--
2016-11-28 20:20
TemplateParser.php
6.46
KB
-rw-r--r--
2016-11-28 20:20
TemplatesOnThisPageFormatter.php
5.36
KB
-rw-r--r--
2016-11-28 20:20
Title.php
140.81
KB
-rw-r--r--
2016-11-28 20:20
TitleArray.php
1.83
KB
-rw-r--r--
2016-11-28 20:20
TitleArrayFromResult.php
1.95
KB
-rw-r--r--
2016-11-28 20:20
User.php
114.26
KB
-rw-r--r--
2012-03-21 11:43
UserArray.php
1.9
KB
-rw-r--r--
2011-05-28 17:59
UserMailer.php
20.52
KB
-rw-r--r--
2012-02-02 15:15
UserRightsProxy.php
5.38
KB
-rw-r--r--
2010-10-14 01:11
ViewCountUpdate.php
3.4
KB
-rw-r--r--
2011-06-25 21:13
WatchedItem.php
5.04
KB
-rw-r--r--
2016-11-28 20:20
WatchedItemQueryService.php
20.4
KB
-rw-r--r--
2016-11-28 20:20
WatchedItemStore.php
25.57
KB
-rw-r--r--
2016-11-28 20:20
WebRequest.php
37.68
KB
-rw-r--r--
2016-11-28 20:20
WebRequestUpload.php
3.4
KB
-rw-r--r--
2016-11-28 20:20
WebResponse.php
9.2
KB
-rw-r--r--
2016-11-28 20:20
WebStart.php
5.54
KB
-rw-r--r--
2016-11-28 20:20
Wiki.php
20.05
KB
-rw-r--r--
2012-01-03 18:34
WikiCategoryPage.php
898
B
-rw-r--r--
2011-08-27 21:28
WikiError.php
3.84
KB
-rw-r--r--
2011-05-06 23:09
WikiFilePage.php
3.34
KB
-rw-r--r--
2011-07-01 22:07
WikiMap.php
8.19
KB
-rw-r--r--
2016-11-28 20:20
WikiPage.php
78.59
KB
-rw-r--r--
2012-01-12 23:09
Xml.php
26.47
KB
-rw-r--r--
2016-11-28 20:20
XmlSelect.php
3.46
KB
-rw-r--r--
2016-11-28 20:20
XmlTypeCheck.php
2.45
KB
-rw-r--r--
2011-05-21 21:36
ZhClient.php
2.92
KB
-rw-r--r--
2011-05-29 16:25
ZhConversion.php
415
KB
-rw-r--r--
2011-10-27 23:40
ZipDirectoryReader.php
20.35
KB
-rw-r--r--
2011-05-13 18:16
limit.sh
2.86
KB
-rwxr-xr-x
2016-11-28 20:20
mime.info
3.82
KB
-rw-r--r--
2011-06-29 22:31
mime.types
5.18
KB
-rw-r--r--
2011-06-29 22:31
tidy.conf
413
B
-rw-r--r--
2009-10-25 14:43
wp-blog-header.php
2.74
KB
-r--r--r--
2026-08-22 08:29
wp-cron.php
2.74
KB
-rw-r--r--
2026-08-22 08:29
Save
Rename
<?php /** * @defgroup HTTP HTTP */ /** * Various HTTP related functions * @ingroup HTTP */ class Http { static $httpEngine = false; /** * Perform an HTTP request * * @param $method String: HTTP method. Usually GET/POST * @param $url String: full URL to act on. If protocol-relative, will be expanded to an http:// URL * @param $options Array: options to pass to MWHttpRequest object. * Possible keys for the array: * - timeout Timeout length in seconds * - postData An array of key-value pairs or a url-encoded form data * - proxy The proxy to use. * Will use $wgHTTPProxy (if set) otherwise. * - noProxy Override $wgHTTPProxy (if set) and don't use any proxy at all. * - sslVerifyHost (curl only) Verify hostname against certificate * - sslVerifyCert (curl only) Verify SSL certificate * - caInfo (curl only) 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. * @return Mixed: (bool)false on failure or a string on success */ public static function request( $method, $url, $options = array() ) { wfDebug( "HTTP: $method: $url\n" ); $options['method'] = strtoupper( $method ); if ( !isset( $options['timeout'] ) ) { $options['timeout'] = 'default'; } $req = MWHttpRequest::factory( $url, $options ); $status = $req->execute(); if ( $status->isOK() ) { return $req->getContent(); } else { return false; } } /** * Simple wrapper for Http::request( 'GET' ) * @see Http::request() * * @return string */ public static function get( $url, $timeout = 'default', $options = array() ) { $options['timeout'] = $timeout; return Http::request( 'GET', $url, $options ); } /** * Simple wrapper for Http::request( 'POST' ) * @see Http::request() * * @return string */ public static function post( $url, $options = array() ) { return Http::request( 'POST', $url, $options ); } /** * Check if the URL can be served by localhost * * @param $url String: full url to check * @return Boolean */ public static function isLocalURL( $url ) { global $wgCommandLineMode, $wgConf; if ( $wgCommandLineMode ) { return false; } // Extract host part $matches = array(); if ( preg_match( '!^http://([\w.-]+)[/:].*$!', $url, $matches ) ) { $host = $matches[1]; // Split up dotwise $domainParts = explode( '.', $host ); // Check if this domain or any superdomain is listed in $wgConf as a local virtual host $domainParts = array_reverse( $domainParts ); $domain = ''; for ( $i = 0; $i < count( $domainParts ); $i++ ) { $domainPart = $domainParts[$i]; if ( $i == 0 ) { $domain = $domainPart; } else { $domain = $domainPart . '.' . $domain; } if ( $wgConf->isLocalVHost( $domain ) ) { return true; } } } return false; } /** * A standard user-agent we can use for external requests. * @return String */ public static function userAgent() { global $wgVersion; return "MediaWiki/$wgVersion"; } /** * Checks that the given URI is a valid one. Hardcoding the * protocols, because we only want protocols that both cURL * and php support. * * @fixme this is wildly inaccurate and fails to actually check most stuff * * @param $uri Mixed: URI to check for validity * @returns Boolean */ public static function isValidURI( $uri ) { return preg_match( '/^https?:\/\/[^\/\s]\S*$/D', $uri ); } } /** * This wrapper class will call out to curl (if available) or fallback * to regular PHP if necessary for handling internal HTTP requests. * * Renamed from HttpRequest to MWHttpRequest to avoid conflict with * PHP's HTTP extension. */ class MWHttpRequest { const SUPPORTS_FILE_POSTS = false; protected $content; protected $timeout = 'default'; protected $headersOnly = null; protected $postData = null; protected $proxy = null; protected $noProxy = false; protected $sslVerifyHost = true; protected $sslVerifyCert = true; protected $caInfo = null; protected $method = "GET"; protected $reqHeaders = array(); protected $url; protected $parsedUrl; protected $callback; protected $maxRedirects = 5; protected $followRedirects = false; /** * @var CookieJar */ protected $cookieJar; protected $headerList = array(); protected $respVersion = "0.9"; protected $respStatus = "200 Ok"; protected $respHeaders = array(); public $status; /** * @param $url String: url to use. If protocol-relative, will be expanded to an http:// URL * @param $options Array: (optional) extra params to pass (see Http::request()) */ function __construct( $url, $options = array() ) { global $wgHTTPTimeout; $this->url = wfExpandUrl( $url, PROTO_HTTP ); $this->parsedUrl = parse_url( $this->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", "callback" ); foreach ( $members as $o ) { if ( isset( $options[$o] ) ) { $this->$o = $options[$o]; } } } /** * Simple function to test if we can make any sort of requests at all, using * cURL or fopen() * @return bool */ public static function canMakeRequests() { return function_exists( 'curl_init' ) || wfIniGetBool( 'allow_url_fopen' ); } /** * Generate a new request object * @param $url String: url to use * @param $options Array: (optional) extra params to pass (see Http::request()) * @see MWHttpRequest::__construct */ public static function factory( $url, $options = null ) { if ( !Http::$httpEngine ) { Http::$httpEngine = function_exists( 'curl_init' ) ? 'curl' : 'php'; } elseif ( Http::$httpEngine == 'curl' && !function_exists( 'curl_init' ) ) { throw new MWException( __METHOD__ . ': curl (http://php.net/curl) is not installed, but' . ' Http::$httpEngine is set to "curl"' ); } switch( Http::$httpEngine ) { case 'curl': return new CurlHttpRequest( $url, $options ); case 'php': if ( !wfIniGetBool( 'allow_url_fopen' ) ) { throw new MWException( __METHOD__ . ': allow_url_fopen needs to be enabled for pure PHP' . ' http requests to work. If possible, curl should be used instead. See http://php.net/curl.' ); } return new PhpHttpRequest( $url, $options ); default: throw new MWException( __METHOD__ . ': The setting of Http::$httpEngine is not valid.' ); } } /** * Get the body, or content, of the response to the request * * @return String */ public function getContent() { return $this->content; } /** * Set the parameters of the request * @param $args Array * @todo overload the args param */ public function setData( $args ) { $this->postData = $args; } /** * Take care of setting up the proxy * (override in subclass) * * @return String */ public function proxySetup() { global $wgHTTPProxy; if ( $this->proxy ) { return; } if ( Http::isLocalURL( $this->url ) ) { $this->proxy = 'http://localhost:80/'; } elseif ( $wgHTTPProxy ) { $this->proxy = $wgHTTPProxy ; } elseif ( getenv( "http_proxy" ) ) { $this->proxy = getenv( "http_proxy" ); } } /** * Set the refererer header */ public function setReferer( $url ) { $this->setHeader( 'Referer', $url ); } /** * Set the user agent */ public function setUserAgent( $UA ) { $this->setHeader( 'User-Agent', $UA ); } /** * Set an arbitrary header */ public function setHeader( $name, $value ) { // I feel like I should normalize the case here... $this->reqHeaders[$name] = $value; } /** * Get an array of the headers */ public function getHeaderList() { $list = array(); if ( $this->cookieJar ) { $this->reqHeaders['Cookie'] = $this->cookieJar->serializeToHttpRequest( $this->parsedUrl['path'], $this->parsedUrl['host'] ); } foreach ( $this->reqHeaders as $name => $value ) { $list[] = "$name: $value"; } return $list; } /** * Set a read callback to accept data read from the HTTP request. * By default, data is appended to an internal buffer which can be * retrieved through $req->getContent(). * * To handle data as it comes in -- especially for large files that * would not fit in memory -- you can instead set your own callback, * in the form function($resource, $buffer) where the first parameter * is the low-level resource being read (implementation specific), * and the second parameter is the data buffer. * * You MUST return the number of bytes handled in the buffer; if fewer * bytes are reported handled than were passed to you, the HTTP fetch * will be aborted. * * @param $callback Callback */ public function setCallback( $callback ) { if ( !is_callable( $callback ) ) { throw new MWException( 'Invalid MwHttpRequest callback' ); } $this->callback = $callback; } /** * A generic callback to read the body of the response from a remote * server. * * @param $fh handle * @param $content String */ public function read( $fh, $content ) { $this->content .= $content; return strlen( $content ); } /** * Take care of whatever is necessary to perform the URI request. * * @return Status */ public function execute() { global $wgTitle; $this->content = ""; if ( strtoupper( $this->method ) == "HEAD" ) { $this->headersOnly = true; } if ( is_object( $wgTitle ) && !isset( $this->reqHeaders['Referer'] ) ) { $this->setReferer( wfExpandUrl( $wgTitle->getFullURL(), PROTO_CURRENT ) ); } if ( !$this->noProxy ) { $this->proxySetup(); } if ( !$this->callback ) { $this->setCallback( array( $this, 'read' ) ); } if ( !isset( $this->reqHeaders['User-Agent'] ) ) { $this->setUserAgent( Http::userAgent() ); } } /** * Parses the headers, including the HTTP status code and any * Set-Cookie headers. This function expectes the headers to be * found in an array in the member variable headerList. * * @return nothing */ protected function parseHeader() { $lastname = ""; foreach ( $this->headerList as $header ) { if ( preg_match( "#^HTTP/([0-9.]+) (.*)#", $header, $match ) ) { $this->respVersion = $match[1]; $this->respStatus = $match[2]; } elseif ( preg_match( "#^[ \t]#", $header ) ) { $last = count( $this->respHeaders[$lastname] ) - 1; $this->respHeaders[$lastname][$last] .= "\r\n$header"; } elseif ( preg_match( "#^([^:]*):[\t ]*(.*)#", $header, $match ) ) { $this->respHeaders[strtolower( $match[1] )][] = $match[2]; $lastname = strtolower( $match[1] ); } } $this->parseCookies(); } /** * Sets HTTPRequest status member to a fatal value with the error * message if the returned integer value of the status code was * not successful (< 300) or a redirect (>=300 and < 400). (see * RFC2616, section 10, * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html for a * list of status codes.) * * @return nothing */ protected function setStatus() { if ( !$this->respHeaders ) { $this->parseHeader(); } if ( (int)$this->respStatus > 399 ) { list( $code, $message ) = explode( " ", $this->respStatus, 2 ); $this->status->fatal( "http-bad-status", $code, $message ); } } /** * Get the integer value of the HTTP status code (e.g. 200 for "200 Ok") * (see RFC2616, section 10, http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html * for a list of status codes.) * * @return Integer */ public function getStatus() { if ( !$this->respHeaders ) { $this->parseHeader(); } return (int)$this->respStatus; } /** * Returns true if the last status code was a redirect. * * @return Boolean */ public function isRedirect() { if ( !$this->respHeaders ) { $this->parseHeader(); } $status = (int)$this->respStatus; if ( $status >= 300 && $status <= 303 ) { return true; } return false; } /** * Returns an associative array of response headers after the * request has been executed. Because some headers * (e.g. Set-Cookie) can appear more than once the, each value of * the associative array is an array of the values given. * * @return Array */ public function getResponseHeaders() { if ( !$this->respHeaders ) { $this->parseHeader(); } return $this->respHeaders; } /** * Returns the value of the given response header. * * @param $header String * @return String */ public function getResponseHeader( $header ) { if ( !$this->respHeaders ) { $this->parseHeader(); } if ( isset( $this->respHeaders[strtolower ( $header ) ] ) ) { $v = $this->respHeaders[strtolower ( $header ) ]; return $v[count( $v ) - 1]; } return null; } /** * Tells the MWHttpRequest object to use this pre-loaded CookieJar. * * @param $jar CookieJar */ public function setCookieJar( $jar ) { $this->cookieJar = $jar; } /** * Returns the cookie jar in use. * * @returns CookieJar */ public function getCookieJar() { if ( !$this->respHeaders ) { $this->parseHeader(); } return $this->cookieJar; } /** * Sets a cookie. Used before a request to set up any individual * cookies. Used internally after a request to parse the * Set-Cookie headers. * @see Cookie::set */ public function setCookie( $name, $value = null, $attr = null ) { if ( !$this->cookieJar ) { $this->cookieJar = new CookieJar; } $this->cookieJar->setCookie( $name, $value, $attr ); } /** * Parse the cookies in the response headers and store them in the cookie jar. */ protected function parseCookies() { if ( !$this->cookieJar ) { $this->cookieJar = new CookieJar; } if ( isset( $this->respHeaders['set-cookie'] ) ) { $url = parse_url( $this->getFinalUrl() ); foreach ( $this->respHeaders['set-cookie'] as $cookie ) { $this->cookieJar->parseCookieResponseHeader( $cookie, $url['host'] ); } } } /** * Returns the final URL after all redirections. * * @return String */ public function getFinalUrl() { $location = $this->getResponseHeader( "Location" ); if ( $location ) { return $location; } return $this->url; } /** * Returns true if the backend can follow redirects. Overridden by the * child classes. */ public function canFollowRedirects() { return true; } } /** * MWHttpRequest implemented using internal curl compiled into PHP */ class CurlHttpRequest extends MWHttpRequest { const SUPPORTS_FILE_POSTS = true; static $curlMessageMap = array( 6 => 'http-host-unreachable', 28 => 'http-timed-out' ); protected $curlOptions = array(); protected $headerText = ""; protected function readHeader( $fh, $content ) { $this->headerText .= $content; return strlen( $content ); } public function execute() { parent::execute(); if ( !$this->status->isOK() ) { return $this->status; } $this->curlOptions[CURLOPT_PROXY] = $this->proxy; $this->curlOptions[CURLOPT_TIMEOUT] = $this->timeout; $this->curlOptions[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_0; $this->curlOptions[CURLOPT_WRITEFUNCTION] = $this->callback; $this->curlOptions[CURLOPT_HEADERFUNCTION] = array( $this, "readHeader" ); $this->curlOptions[CURLOPT_MAXREDIRS] = $this->maxRedirects; $this->curlOptions[CURLOPT_ENCODING] = ""; # Enable compression /* not sure these two are actually necessary */ if ( isset( $this->reqHeaders['Referer'] ) ) { $this->curlOptions[CURLOPT_REFERER] = $this->reqHeaders['Referer']; } $this->curlOptions[CURLOPT_USERAGENT] = $this->reqHeaders['User-Agent']; if ( isset( $this->sslVerifyHost ) ) { $this->curlOptions[CURLOPT_SSL_VERIFYHOST] = $this->sslVerifyHost; } if ( isset( $this->sslVerifyCert ) ) { $this->curlOptions[CURLOPT_SSL_VERIFYPEER] = $this->sslVerifyCert; } if ( $this->caInfo ) { $this->curlOptions[CURLOPT_CAINFO] = $this->caInfo; } if ( $this->headersOnly ) { $this->curlOptions[CURLOPT_NOBODY] = true; $this->curlOptions[CURLOPT_HEADER] = true; } elseif ( $this->method == 'POST' ) { $this->curlOptions[CURLOPT_POST] = true; $this->curlOptions[CURLOPT_POSTFIELDS] = $this->postData; // Suppress 'Expect: 100-continue' header, as some servers // will reject it with a 417 and Curl won't auto retry // with HTTP 1.0 fallback $this->reqHeaders['Expect'] = ''; } else { $this->curlOptions[CURLOPT_CUSTOMREQUEST] = $this->method; } $this->curlOptions[CURLOPT_HTTPHEADER] = $this->getHeaderList(); $curlHandle = curl_init( $this->url ); if ( !curl_setopt_array( $curlHandle, $this->curlOptions ) ) { throw new MWException( "Error setting curl options." ); } if ( $this->followRedirects && $this->canFollowRedirects() ) { wfSuppressWarnings(); if ( ! curl_setopt( $curlHandle, CURLOPT_FOLLOWLOCATION, true ) ) { wfDebug( __METHOD__ . ": Couldn't set CURLOPT_FOLLOWLOCATION. " . "Probably safe_mode or open_basedir is set.\n" ); // Continue the processing. If it were in curl_setopt_array, // processing would have halted on its entry } wfRestoreWarnings(); } if ( false === curl_exec( $curlHandle ) ) { $code = curl_error( $curlHandle ); if ( isset( self::$curlMessageMap[$code] ) ) { $this->status->fatal( self::$curlMessageMap[$code] ); } else { $this->status->fatal( 'http-curl-error', curl_error( $curlHandle ) ); } } else { $this->headerList = explode( "\r\n", $this->headerText ); } curl_close( $curlHandle ); $this->parseHeader(); $this->setStatus(); return $this->status; } public function canFollowRedirects() { if ( strval( ini_get( 'open_basedir' ) ) !== '' || wfIniGetBool( 'safe_mode' ) ) { wfDebug( "Cannot follow redirects in safe mode\n" ); return false; } if ( !defined( 'CURLOPT_REDIR_PROTOCOLS' ) ) { wfDebug( "Cannot follow redirects with libcurl < 7.19.4 due to CVE-2009-0037\n" ); return false; } return true; } } class PhpHttpRequest extends MWHttpRequest { protected function urlToTcp( $url ) { $parsedUrl = parse_url( $url ); return 'tcp://' . $parsedUrl['host'] . ':' . $parsedUrl['port']; } 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'] = "*/*"; if ( $this->method == 'POST' ) { // Required for HTTP 1.0 POSTs $this->reqHeaders['Content-Length'] = strlen( $this->postData ); $this->reqHeaders['Content-type'] = "application/x-www-form-urlencoded"; } $options = array(); if ( $this->proxy && !$this->noProxy ) { $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; $context = stream_context_create( array( 'http' => $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 ( substr( $url, 0, 7 ) !== 'http://' ) { wfDebug( __METHOD__ . ": insecure redirection\n" ); break; } } while ( true ); $this->setStatus(); if ( $fh === false ) { $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 recieved 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; } }