Commit graph

713 commits

Author SHA1 Message Date
Umherirrender
8de3b7d324 Use static closures where safe to use
This is micro-optimization of closure code to avoid binding the closure
to $this where it is not needed.

Created by I25a17fb22b6b669e817317a0f45051ae9c608208

Change-Id: I0ffc6200f6c6693d78a3151cb8cea7dce7c21653
2021-02-11 00:13:52 +00:00
Tim Starling
2697837fd8 RequestTimeout library integration
* Add $wgRequestTimeLimit. If it is non-null, it starts a time limit,
  using Excimer with a fallback to set_time_limit().
* Add pretty formatting of timeout exceptions thrown by the library.
  Related refactoring.
* Expose the library's critical section feature in MediaWikiServices
* In Setup.php, call warnIfHeadersSent() before sending session headers.
  This helped to debug a related issue I had.
* In wfTransactionalTimeLimit() use the new library, and respect the
  existing library time limit if it is larger than
  $wgTransactionalTimeLimit.

Bug: T269326
Depends-On: I6409ad8a5cba775c27b0d5a79d3300c4dac4c91a
Change-Id: I2e6f6351c451407c06cc7e20932548f7b62e36b6
2021-02-08 11:58:45 +11:00
daniel
47bb958f03 Deprecate premature instantiation of services.
This deprecates access to the global service container before
initialization is complete. For now, such premature access will
trigger a deprecation warning. In 1.37 we can prevent it entirely.

Bug: T153256
Change-Id: Ibd3ab32d92c9c3d3783082ab574739467c1c2ff9
2021-01-19 22:33:13 +01:00
Umherirrender
f46ca9a63c build: Updating mediawiki/mediawiki-phan-config to 0.10.5
Change-Id: I343d2bae626a3903eb1e67c05bf5caef4314b7dd
2020-12-12 14:42:25 +01:00
Umherirrender
6a2c2548a4 Document HttpError to help taint-check
This does not help to avoid the suppression inside the class,
but it avoids the suppression for all callers

Remove unneeded local vars while looking at the code

Bug: T269895
Bug: T216348
Change-Id: I5ce9a2dddca2b3bb556eb7adb5305178db09a71a
2020-12-12 00:06:00 +01:00
Umherirrender
1bc05f5242 Use UserNameUtils in Setup
Change-Id: Id374aa1d460ee2b1ecb362bd3cce50fb8ed11149
2020-11-29 08:43:52 +00:00
Ammar Abdulhamid
e217793aeb Improve variable doc in Setup
Change-Id: I395a76b607431f2a2f93ac253031d92ff997a027
2020-11-14 08:30:29 +01:00
DannyS712
4c19a01569 Setup.php: Avoid global pollution from internal variables
Change-Id: If7d8836e4e3c3481249b1107b658fbd0a63391a7
2020-10-27 01:06:32 +00:00
Gergő Tisza
d5d3c90152
Log IP/device changes within the same session
Store IP and device information in the session and log when
it changes. The goal is to detect session leakage when the
session is accidentally sent to another user, which is a
hypothetical cause of T264370. The log will be noisy since
users do change IP addresses for a number of reasons,
but we are mainly interested in the ability of correlating
user-reported incidents where we have a username to filter
by, so that's OK.

Based on I27468a3f6d58.

Bug: T264799
Change-Id: Ifa14fa637c1b199159ea11e983a25212ae005565
2020-10-08 13:13:25 -07:00
Timo Tijhof
10bdad0d35 Remove $wgMemc
Deprecated since 1.35, and no longer used in core, bundled, or
wmf-deployed projects.

Bug: T160813
Change-Id: Idd3166ef90d1795a0b22dc29d52de76048d0703e
2020-07-27 23:45:22 +00:00
jenkins-bot
8b2f44b6e7 Merge "phan: Enable redundant_condition_detection" 2020-07-02 00:28:10 +00:00
Umherirrender
bc5cb7ae64 phan: Enable redundant_condition_detection
Remove duplicate casts
Suppress false positives

Bug: T248438
Change-Id: I2f89664a4bcd3b39b15e7cf850adda2f0c90ae6f
2020-07-01 20:13:07 +00:00
Tim Starling
c75eef91bf Introduce $wgForceHTTPS
Add $wgForceHTTPS. When set to true:

* It makes the HTTP to HTTPS redirect unconditional and suppresses the
  forceHTTPS cookie.
* It makes session cookies be secure.
* In the Action API, it triggers the existing deprecation warning and
  avoids more expensive user/session checks.
* In login and signup, it suppresses the old hidden form fields for
  protocol switching.
* It hides the prefershttps user preference.

Other changes:

* Factor out the HTTPS redirect in MediaWiki::main() into
  maybeDoHttpsRedirect() and shouldDoHttpRedirect(). Improve
  documentation.
* User::requiresHTTPS() reflects $wgForceHTTPS whereas the Session
  concept of "force HTTPS" does not. The documentation of
  User::requiresHTTPS() says that it includes configuration, and
  retaining this definition was beneficial for some callers. Whereas
  Session::shouldForceHTTPS() was used fairly narrowly as the value
  of the forceHTTPS cookie, and injecting configuration into it is not
  so easy or beneficial, so I left it as it was, except for clarifying
  the documentation.
* Deprecate the following hooks: BeforeHttpsRedirect, UserRequiresHTTPS,
  CanIPUseHTTPS. No known extension uses them, and they're not compatible
  with the long-term goal of ending support for mixed-protocol wikis.
  BeforeHttpsRedirect was documented as unstable from its inception.
  CanIPUseHTTPS was a WMF config hack now superseded by GFOC's SNI
  sniffing.
* For tests which failed with $wgForceHTTPS=true, I mostly split the
  tests, testing each configuration value separately.
* Add ArrayUtils::cartesianProduct() as a helper for generating
  combinations of boolean options in the session tests.

Bug: T256095

Change-Id: Iefb5ba55af35350dfc7c050f9fb8f4e8a79751cb
2020-06-30 15:38:11 +10:00
daniel
f59bf8a22f Use @internal instead of @private per policy
https://www.mediawiki.org/wiki/Stable_interface_policy mandates the use
of @internal. The semantics of @private was never properly defined.

Bug: T247862
Change-Id: I4c7c6e7b5a80e86456965521f88d1dfa7d698f84
2020-06-26 14:14:23 +02:00
Umherirrender
fd666afbb0 Use MediaWikiServices::getAuthManager instead of AuthManager::singleton
Change-Id: I92c31b963095eab751df9f8c1715e8e23b7e8485
2020-06-22 00:57:08 +00:00
Tim Starling
47a1619027 Remove terminating line breaks from debug messages
A terminating line break has not been required in wfDebug() since 2014,
however no migration was done. Some of these line breaks found their way
into LoggerInterface::debug() calls, where they mess up the formatting
of the debug log.

So, remove terminating line breaks from wfDebug() and
LoggerInterface::debug() calls.

Also:
* Fix the stripping of leading line breaks from the log header emitted
  by Setup.php. This feature, accidentally broken in 2014, allows
  requests to be distinguished in the log file.
* Avoid using the global variable $self.
* Move the logging of the client IP back to Setup.php. It was moved to
  WebRequest in the hopes that it would not always be needed, however
  $wgRequest->getIP() is now called unconditionally a few lines up in
  Setup.php. This means that it is put in its proper place after the
  "start request" message.
* Wrap the log header code in a closure so that variables like $name do
  not leak into global scope.
* In Linker.php, remove a few instances of an unnecessary second
  parameter to wfDebug().

Change-Id: I96651d3044a95b9d210b51cb8368edc76bebbb9e
2020-06-03 12:01:16 +10:00
Tim Starling
68c433bd23 Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.

General principles:
* Use DI if it is already used. We're not changing the way state is
  managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
  is a service, it's a more generic interface, it is the only
  thing that provides isRegistered() which is needed in some cases,
  and a HookRunner can be efficiently constructed from it
  (confirmed by benchmark). Because HookContainer is needed
  for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
  SpecialPage and ApiBase have getHookContainer() and getHookRunner()
  methods in the base class, and classes that extend that base class
  are not expected to know or care where the base class gets its
  HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
  getHookRunner() methods, getting them from the global service
  container. The point of this is to ease migration to DI by ensuring
  that call sites ask their local friendly base class rather than
  getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
  methods did not seem warranted, there is a private HookRunner property
  which is accessed directly. Very rarely (two cases), there is a
  protected property, for consistency with code that conventionally
  assumes protected=private, but in cases where the class might actually
  be overridden, a protected accessor is preferred over a protected
  property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
  global code. In a few cases it was used for objects with broken
  construction schemes, out of horror or laziness.

Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore

Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router

setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine

Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-05-30 14:23:28 +00:00
Timo Tijhof
a339338ec3 upload: Move MinUploadChunkSize logic from Setup.php to ApiUpload
This was previously making calls to various methods during the
Setup.php, which apart from being deferrable logic that isn't
needed on most requests, is also risky/complicated because MW
isn't initialised yet at this point.

Bug: T189966
Change-Id: Iaee3f2af8d18bc5095e9297cbe1b6efc627f3977
2020-05-05 01:58:15 +00:00
TheSandDoctor
705e7e7c21 Hard deprecate $wgParser
$wgParser, originally soft deprecated in 1.32, has been hard deprecated.

Code search in WMF deployed code:
https://codesearch.wmflabs.org/deployed/?q=%5B%24%5DwgParser%5B%5EA-Z%5D&i=nope&files=&repos=

Everything search:
https://codesearch.wmflabs.org/search/?q=%5B%24%5DwgParser%5B%5EA-Z%5D&i=nope&files=&repos=

Bug: T160811
Change-Id: I6830126d4dedab25b6ae6a2fcbfacdf429f71021
2020-04-30 03:41:04 -04:00
Holger Knust
471d2371ab doxygen: Changed Doxygen tags causing warnings during documentation generation
Updated Doxygen markup in several .php files triggering warnings when mwdocgen.php is executed. Removed
obsolete settings MSCGEN_PATH and TCL_SUBST from Doxyfile. The former would generate a warning in 1.8.16
while TCL support was removed in 1.8.18. Since TCL_SUBST was blank anyway, it was removed prior to getting
to .18 in production. Increased DOT_GRAPH_MAX_NODES from 50 to 200 since Doxygen complained about it being
too low for API and Maintenance.

Bug: T248706
Change-Id: I9c67f0807d1b43089d351263d4f591dee5501f36
2020-04-14 03:25:19 +00:00
Timo Tijhof
4eb1e679d5 Setup: Document the responsibilities of entry points
Bug: T189966
Change-Id: If282c21a882094a7d8a601a64de8c6fcc18b659f
2020-04-12 21:22:41 +01:00
Timo Tijhof
c7330ebabc objectcache: Improve wgMainWANCache docs
* Document how wgWANObjectCaches and wgMainWANCache are
  used / should be used.
  Remove outdated mention of event relayers.

* The easiest way I could document the 'other' options that
  wgWANObjectCaches entries can have was by saying which keys
  can't be set and that aside from these and class/cacheId
  they are all passed on.

  However, that wasn't (yet) technically right given we do pass
  class/cacheId on blindly, which might be unexpected for
  subclasses in theory. Explicitly unset those in ServiceWiring
  to avoid any chance of confusion. Also simplify that code
  slightly overall in terms of var names and var re-use,
  and improve error messages a litle bit.

* Test plan for the wanobjectcache-deployment doc ref:

  $ php maintenance/mwdocgen.php \
   --file includes/DefaultSettings.php,includes/libs/objectcache/

  Then open path/to/mediawiki/docs/html/, click on the docs for
  DefaultSettings, and find-in-page to "wgMainWANCache".

Change-Id: I1cfc65c2cc4dbceed6b9777c2b808527a58daeb9
2020-04-02 20:11:20 +00:00
DannyS712
ce800afdd2 Declare $wgUser to be deprecated in version 1.35
Only soft deprecated, removal is in process, see task and subtasks
Still used within core, but thats okay, since its not hard deprecated

Bug: T159299
Change-Id: I0e7e9857a0f6b83c4fd3df6316591c4b01e85106
2020-03-25 06:58:52 +00:00
Timo Tijhof
59f67dafb8 Setup.php: Remove internal $messageMemc variable
Was originally for use by the MessageCache class, which no longer
uses it.

Bug: T243175
Change-Id: I1c62c6bba08fadf52bda4993a4e99df81b02a97f
2020-03-18 17:44:35 +00:00
Timo Tijhof
9a9ae83419 Remove $wgContLanguageCode
Prior to 2004, the site language was configured via $wgContLanguageCode,
derived from that were $wgContLang (object). $wgLanguageCode was just a
cached copy of $wgUser->getOption('language').

In 2004 (r5492, 5537c5b85e, MW 1.3), $wgContLanguageCode ceased to be
supported as a configuration variable. Instead, the site language would
now be configured via $wgLanguageCode instead and the confusion started.
Its value was copied to $wgContLanguageCode for back-compat, and also
because $wgLanguageCode was still also used to store
User::getOption('language') right after initialising $wgContLang.

Sometime between 2004 and 2006, $wgLanguageCode was relieved of this
secondary purpose, as documented in r5492 (5537c5b85, MW 1.8), leaving it
as just a configuration variable for the site language.

Use of $wgContLanguageCode has been removed from Codesearch-indexed repos,
including third-party repos on GitHub.

Bug: T247674
Bug: T189966
Change-Id: Ic91f500d48d772360bf10323a2ed0733c0ea890d
2020-03-17 18:29:20 +00:00
Timo Tijhof
9463b0105b Setup: Move simple shortcuts together in Setup.php and improve docs
I've moved the simple config expansions that don't depend on anything
else in Setup.php together, more compactly.

Change-Id: Iefb7f8ffdca70bcfbf7cbf49f7939747c5ab0d76
2020-03-14 23:10:07 +00:00
Timo Tijhof
81a31e162b Setup: Remove compat for $wgDisableCounters
Deprecated since 2014 in MediaWiki 1.25, and the feature it
controlled was removed from core in 1.26.

The feature is still available via the HitCounters extension,
<https://gerrit.wikimedia.org/g/mediawiki/extensions/HitCounters/>

Bug: T189966
Change-Id: I5e46d1aef1b44b8828bdd1bba644136391cc1c4c
2020-03-14 19:28:00 +00:00
Timo Tijhof
75ccdc6147 languages: Move default $wgNamespaceAliases to MessagesEn.php
These are not configuration but business logic, similar to the
canonical names that are in NamespaceInfo.php, these must always
exist and cannot be altered or unset.

They were previously unconditionally assigned during all requests
in Setup.php and passed down as "site configuration".

Changes:

* Move them to MessagesEn.php where they can be cached and
  processed the same way as other core-provided aliases.

  Document and confirm with tests that this is a mergeable
  attribute that follows the language chain.

* Remove the duplicated code in a few places that was reading
  this variable + Language::getNamespaceAliases(), to instead
  just call the latter and move the logic there, centralised,
  and tested.

  In doing so I noticed that these were applied in an
  inconsistent order. Sometimes the config won, sometimes not.
  There's no obvious right or wrong way here, but I've chosen
  to standardise on the way that Language::getNamespaceIds() did
  it, which is that config wins. This because that method seems
  to be most widely used of the three (it decides how URLs and
  titles are parsed), and thus the one I least want to change
  the behaviour of.

* Document that $wgNamespaceAliases may only be used to
  define (extra) aliases, it is and never was a way to access
  the complete list of aliases.

Bug: T189966
Change-Id: Ibb14181aba8c1b509264ed40523e9ab4000fd71a
2020-03-14 19:27:40 +00:00
Timo Tijhof
e8d9d68b86 Setup: Remove compat for $wgUseSquid and friends
Follows-up f9f8dff40 (MediaWiki 1.34).

Bug: T189966
Change-Id: Ifc0022783e6b5e739d754f5a5060742d5ab42500
2020-03-14 16:59:26 +00:00
Timo Tijhof
50c3a47140 Setup: Move wgSkipSkins appendix to Skin::getAllowedSkins
This isn't a default setting or fallback, it's unconditional
business logic that can't be overidden. This doesn't need to
run on every web request in Setup.php.

Bug: T189966
Change-Id: I708131b111cd2ff0e34c3cc8a4b933eff260b3da
2020-03-13 23:45:12 +00:00
Timo Tijhof
9e44459031 Setup: Improve section docs to better explain the pre-config setup
Also remove some comments that didn't help understand the line
below (e.g. "install header callback" above "HeaderCallback::install")

Bug: T189966
Change-Id: Ib0b413c557f83f8f58683515fcdbf1817fe1f661
2020-03-13 16:27:25 +00:00
Reedy
c030dacfbe Kill off $wgLocalInterwiki
Change-Id: I07e44d1384138704eea979263e45a9853a0ae621
2020-03-07 21:44:46 +00:00
mainframe98
53da96af08 Remove wfGetMessageCacheStorage
There were no callers to this method, outside the $messageMemc
global, which is to be deprecated with T243175. Pending its
eventual removal, its usage has been inlined as the function
was trivial anyways.

Any previous callers were migrated with the convertion of the
MessageCache to a service in 752e7dd707.

Bug: T243176
Change-Id: I79846442512f023dcdf2f1f8c425156589c0421d
2020-02-14 20:09:14 +01:00
James D. Forrester
ec60dbbaea Follow-up 8cd2e13: Setup: Check that 1x key has been set in wgLogos before using
Bug: T232140
Bug: T244370
Change-Id: If1e0a384db6584d8854d7f39313ee62ae8423a7f
2020-02-05 07:44:16 -08:00
jdlrobson
8cd2e13363 Deprecate access of logos directly from config, introduce wgLogos
Add getAvailableLogos static method and wgLogos config variable

Longterm we'll phase out wgLogo and wgLogoHD for this more extendable
config.

wgLogoHD is marked as deprecated. wgLogo continues to function as before
when wgLogos doesn't exist to cause minimum disruption.

From now on all logos should be accessed via getAvailableLogos. Patches
in Minerva and Vector follow. See I00899c16c0325f36b671baf17e88c2b5187b3526,
I569e0d800e147eabc7852567acd140108613f074 and
I013bd0904fe8c55efa49d14e84cf06ec1412896f.

Bug: T232140
Change-Id: I66a971631c623cc94b58eb0e5e5bad804789bf1c
2020-02-04 01:56:20 +00:00
mainframe98
82b56e50e8 Deprecate $wgMemc
Callers should use the LocalServerObjectCache service instead.

Bug: T160813
Change-Id: I0f9725a56413b85929f920542bf89928e719baac
2020-01-20 11:44:21 +01:00
James D. Forrester
0958a0bce4 Coding style: Auto-fix MediaWiki.Usage.IsNull.IsNull
Change-Id: I90cfe8366c0245c9c67e598d17800684897a4e27
2020-01-10 14:17:13 -08:00
James D. Forrester
4f2d1efdda Coding style: Auto-fix MediaWiki.Classes.UnsortedUseStatements.UnsortedUse
Change-Id: I94a0ae83c65e8ee419bbd1ae1e86ab21ed4d8210
2020-01-10 09:32:25 -08:00
DannyS712
d50b9592e2 Drop wgSkipSkin, deprecated and unused
Bug: T241342
Change-Id: I38708089a48979dc9816a16050e48ed0c8a7b572
2020-01-02 00:37:48 +01:00
DannyS712
049dd15d4c Drop wgProfileOnly, deprecated and unused
Bug: T241343
Change-Id: I16eed6807bdcae657153221d06c4448da4566371
2019-12-23 00:48:53 +00:00
DannyS712
ce99c5f3aa Remove $wgSysopEmailBans, deprecated in 1.34
Bug: T233116
Change-Id: I72e257454692b29bfcbf4796f457858fc61b93d8
2019-11-01 02:46:45 +00:00
DannyS712
42566fce93 Hard deprecate $wgSysopEmailBans
Bug: T232169
Change-Id: Icfe02595fc92738c279fa6764f955aa00818088d
2019-11-01 01:59:44 +00:00
Kunal Mehta
03078991c4 Disable $wgServer autodetection to prevent cache poisoning attacks
Since MediaWiki 1.18, $wgServer has been automatically set by the web installer
when it generates LocalSettings.php, so this shouldn't be an issue for most
wikis. The CLI installer now supports a --server optional parameter to
specify $wgServer, otherwise it'll be set to 'http://localhost' by default.

Users will see a fatal error pointing them to the on-wiki $wgServer
documentation that I've updated as well.

Originally this functionality was slated for removal in 1.20, but now is
just a good time as any. It also calls into other parts of MediaWiki before
most things are initialized, making it difficult to librarize some code.

Bug: T30798
Bug: T232931
Change-Id: Ia5d616e7fafbab01655067c24c5a3a073b254f21
2019-10-30 15:49:41 +11:00
Daimona Eaytoy
ae424ce5da build: Upgrade mediawiki-phan-config to 0.8.0
This is to ensure that the CI job is working with the new version.

Note: redundant_condition_detection should have worked as expected by
this version, but unfortunately it still has false positives.

Bug: T235049
Bug: T231636
Change-Id: Idaba6584cb5b2ff19b6455c7bbec6b89619ddbff
2019-10-22 09:16:45 +00:00
jenkins-bot
42f58ae012 Merge "Setup: Move wgArticlePath validation to its main consumer (PathRouter)" 2019-10-07 21:58:16 +00:00
Max Semenik
2f749f7cb3 NamespaceInfo: use array constants now that we can
Change-Id: I676a68fdc42ff2f37c7e4a2700b7c0c448155d47
2019-10-05 00:26:56 -07:00
Max Semenik
a647c37843 Setup.php: remove HHVM support
Change-Id: I2fd43887ae996a0e0752032c6f3e8a25a6dd6d20
2019-10-02 21:03:51 -07:00
Timo Tijhof
480b7341f8 Setup: Move wgArticlePath validation to its main consumer (PathRouter)
The variable is also read in a few other places, such as to
export the value from api.php (siteinfo) and load.php (mw.config)
but those requests don't need to be held back by this extra
logic.

Alternatively, if we really want to require this for all consumption,
we should probably let PathRouter provide the value and require
consumers to use it. E.g. services->getPathRouter->getArticlePath,
or something like that.

As easy first step, I'm moving it to PathRouter, called from
WebRequest::getPathInfo which is still called on all index.php
requests for any wiki page action in any namespace (incl Special)
when the wiki uses anything other than the default 'index.php?title='
article path.

Test Plan:
* Set '$wgArticlePath = 'bla';`
* View /mediawiki/index.php/Main_Page, and observe the fatal
  error message (same as before this change).

Bug: T189966
Change-Id: Id06c2557e2addb58faeef0b6f7767a65b8de55a5
2019-09-25 23:06:52 +00:00
Daimona Eaytoy
e5444ea55a docs: Avoid some scalar juggling
Phan can treat scalar types as non-interchangeable with
`scalar_implicit_cast` set to false. This patch fixes some of those
issues (which are in total >1000), namely the ones with alphabetic order
< includes/actions.

Change-Id: Ib1c6573ab899088bc319b9da9ceaffc850da3dbe
2019-09-19 17:21:24 +00:00
DannyS712
3a2c7d1b5d Deprecate $wgSysopEmailBans
Bug: T232169
Change-Id: Iba2493eb2f49d32c5aa1b4da53c9c221847fb125
2019-09-17 08:23:04 +00:00