the browser-facing portion of osu!
at master 133 lines 4.7 kB view raw
1<?php 2 3// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0. 4// See the LICENCE file in the repository root for full licence text. 5 6namespace App\Providers; 7 8use App\Hashing\OsuBcryptHasher; 9use App\Libraries\MorphMap; 10use App\Libraries\OsuCookieJar; 11use App\Libraries\OsuMessageSelector; 12use App\Libraries\RateLimiter; 13use App\Singletons; 14use Illuminate\Database\Eloquent\Relations\Relation; 15use Illuminate\Http\Request; 16use Illuminate\Queue\Events\JobProcessed; 17use Illuminate\Support\ServiceProvider; 18use Knuckles\Scribe\Scribe; 19use Laravel\Octane\Contracts\DispatchesTasks; 20use Laravel\Octane\SequentialTaskDispatcher; 21use Laravel\Octane\Swoole\SwooleTaskDispatcher; 22use Queue; 23use Swoole\Http\Server; 24 25class AppServiceProvider extends ServiceProvider 26{ 27 const LOCAL_CACHE_SINGLETONS = [ 28 'chat-filters' => Singletons\ChatFilters::class, 29 'countries' => Singletons\Countries::class, 30 'groups' => Singletons\Groups::class, 31 'layout-cache' => Singletons\LayoutCache::class, 32 'medals' => Singletons\Medals::class, 33 'smilies' => Singletons\Smilies::class, 34 'tags' => Singletons\Tags::class, 35 'user-cover-presets' => Singletons\UserCoverPresets::class, 36 ]; 37 38 const SINGLETONS = [ 39 'OsuAuthorize' => Singletons\OsuAuthorize::class, 40 'assets-manifest' => Singletons\AssetsManifest::class, 41 'clean-html' => Singletons\CleanHTML::class, 42 'ip2asn' => Singletons\Ip2Asn::class, 43 'local-cache-manager' => Singletons\LocalCacheManager::class, 44 'mods' => Singletons\Mods::class, 45 'route-section' => Singletons\RouteSection::class, 46 'score-pins' => Singletons\UserScorePins::class, 47 ]; 48 49 /** 50 * Bootstrap any application services. 51 * 52 * @return void 53 */ 54 public function boot() 55 { 56 Relation::morphMap(MorphMap::flippedMap()); 57 58 $GLOBALS['cfg'] = \Config::all(); 59 60 Queue::after(function (JobProcessed $event) { 61 app('OsuAuthorize')->resetCache(); 62 app('local-cache-manager')->incrementResetTicker(); 63 64 datadog_increment( 65 'queue.run', 66 [ 67 'job' => $event->job->payload()['data']['commandName'], 68 'queue' => $event->job->getQueue(), 69 ] 70 ); 71 }); 72 73 $this->app->make('translator')->setSelector(new OsuMessageSelector()); 74 75 app('url')->forceScheme(substr($GLOBALS['cfg']['app']['url'], 0, 5) === 'https' ? 'https' : 'http'); 76 77 Request::setTrustedProxies($GLOBALS['cfg']['trustedproxy']['proxies'], $GLOBALS['cfg']['trustedproxy']['headers']); 78 79 // newest scribe tries to rename {modelName} parameters to {id} 80 // but it kind of doesn't work with our route handlers. 81 Scribe::normalizeEndpointUrlUsing(fn ($url) => $url); 82 83 \Hash::extend('osubcrypt', fn () => new OsuBcryptHasher()); 84 } 85 86 /** 87 * Register any application services. 88 * 89 * This service provider is a great spot to register your various container 90 * bindings with the application. 91 * 92 * @return void 93 */ 94 public function register() 95 { 96 foreach (array_merge(static::SINGLETONS, static::LOCAL_CACHE_SINGLETONS) as $name => $class) { 97 $this->app->singleton($name, fn () => new $class()); 98 } 99 $localCacheManager = app('local-cache-manager'); 100 foreach (static::LOCAL_CACHE_SINGLETONS as $name => $_class) { 101 $localCacheManager->registerSingleton(app($name)); 102 } 103 104 $this->app->singleton('cookie', function ($app) { 105 $config = $GLOBALS['cfg']['session']; 106 107 return (new OsuCookieJar())->setDefaultPathAndDomain( 108 $config['path'], 109 $config['domain'], 110 $config['secure'], 111 $config['same_site'] ?? null 112 ); 113 }); 114 115 $this->app->singleton(RateLimiter::class, function ($app) { 116 return new RateLimiter($app->make('cache')->driver( 117 $app['config']->get('cache.limiter') 118 )); 119 }); 120 121 // pre-bind to avoid SwooleHttpTaskDispatcher and fallback when not running in a swoole context. 122 $this->app->bind( 123 DispatchesTasks::class, 124 fn ($app) => $app->bound(Server::class) ? new SwooleTaskDispatcher() : new SequentialTaskDispatcher() 125 ); 126 127 $env = $this->app->environment(); 128 if ($env === 'testing' || $env === 'dusk.local') { 129 // This is needed for testing with Dusk. 130 $this->app->register(AdditionalDuskServiceProvider::class); 131 } 132 } 133}