Skip to content

Commit d72f824

Browse files
authored
Merge pull request #62 from Decicus/at/remove-at-characters
[Twitch] Remove `@` characters from the beginning of `channel` / `user` parameters
2 parents 607442a + 54cca79 commit d72f824

4 files changed

Lines changed: 115 additions & 6 deletions

File tree

app/Http/Kernel.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,6 @@ class Kernel extends HttpKernel
5656
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
5757
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
5858
'ratelimit' => \App\Http\Middleware\RateLimitWithWhitelist::class,
59+
'twitch.remove_at_signs' => \App\Http\Middleware\TwitchRemoveAtSigns::class,
5960
];
6061
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
namespace App\Http\Middleware;
4+
5+
use Closure;
6+
7+
class TwitchRemoveAtSigns
8+
{
9+
/**
10+
* Removes one or more '@' characters from the beginning
11+
* of the string, if they are there.
12+
*
13+
* In this scenario it should just remove the first `@` characters
14+
* before merging the new strings back into the existing request.
15+
*
16+
* @param string $value
17+
*
18+
* @return string
19+
*/
20+
private function removeAtSigns($value)
21+
{
22+
return ltrim($value, '@');
23+
}
24+
25+
/**
26+
* Remove leading `@` characters for specific
27+
* parameters (mainly `channel` and `user`).
28+
*
29+
* @param \Illuminate\Http\Request $request
30+
* @param \Closure $next
31+
* @return mixed
32+
*/
33+
public function handle($request, Closure $next)
34+
{
35+
$old = $request->all();
36+
37+
/**
38+
* Neither `channel` or `user` is specified
39+
* So we don't need to modify anything.
40+
*/
41+
if (!isset($old['channel']) && !isset($old['user'])) {
42+
return $next($request);
43+
}
44+
45+
/**
46+
* Store new values that should be merged into the request.
47+
*/
48+
$new = [];
49+
50+
/**
51+
* Replace for `channel` parameter, if it's set.
52+
*/
53+
if (isset($old['channel'])) {
54+
$new['channel'] = $this->removeAtSigns($old['channel']);
55+
}
56+
57+
/**
58+
* Replace for `user` parameter, if it's set.
59+
*/
60+
if (isset($old['user'])) {
61+
$new['user'] = $this->removeAtSigns($old['user']);
62+
}
63+
64+
/**
65+
* Merge/replace the new strings into the request.
66+
*/
67+
$request->replace($new);
68+
69+
return $next($request);
70+
}
71+
}

app/Providers/RouteServiceProvider.php

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,43 @@ class RouteServiceProvider extends ServiceProvider
1616
*/
1717
protected $namespace = 'App\Http\Controllers';
1818

19+
/**
20+
* Removes one or more '@' characters from the beginning
21+
* of the string, if they are there.
22+
*
23+
* Primarily targeted towards /twitch routes where
24+
* `@` is used to mention Twitch usernames and thus causing a 404.
25+
*
26+
* In this scenario it should just remove the first `@` characters and continue
27+
* passing the value to the controller.
28+
*
29+
* @param string $value
30+
*
31+
* @return string
32+
*/
33+
private function removeAtSigns($value)
34+
{
35+
return ltrim($value, '@');
36+
}
37+
1938
/**
2039
* Define your route model bindings, pattern filters, etc.
2140
*
2241
* @return void
2342
*/
2443
public function boot()
2544
{
26-
//
45+
/**
46+
* Remove one or more '@' if they're at the
47+
* beginning of the parameter.
48+
*/
49+
Route::bind('channel', function($channel) {
50+
return $this->removeAtSigns($channel);
51+
});
52+
53+
Route::bind('user', function($user) {
54+
return $this->removeAtSigns($user);
55+
});
2756

2857
parent::boot();
2958
}

routes/web.php

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,18 @@
101101
->where('id', '([A-z:0-9]+)');
102102
});
103103

104-
Route::group(['prefix' => 'twitch', 'as' => 'twitch.', 'middleware' => 'ratelimit:' . env('THROTTLE_RATE_LIMIT', '100,1')], function() {
105-
// Include some extra characters that are used in examples quite often.
106-
// The error returned should hopefully clear up any confusion as to why it doesn't work.
107-
$channelRegex = '([$:{}A-z0-9]{1,50})';
104+
Route::group(['prefix' => 'twitch', 'as' => 'twitch.', 'middleware' => ['ratelimit:' . env('THROTTLE_RATE_LIMIT', '100,1'), 'twitch.remove_at_signs']], function() {
105+
106+
/**
107+
* Include some extra characters that are used in examples quite often.
108+
* The error returned should hopefully clear up any confusion as to why it doesn't work.
109+
*
110+
* `@` is included for when people use `@username` to mention users in bot commands.
111+
* Normally these would 404, but we're modifying parameters to support it.
112+
*
113+
* The prefixed `@` characters are removed in RouteServiceProvider before being passed to the controller method.
114+
*/
115+
$channelRegex = '([@$:{}A-z0-9]{1,50})';
108116

109117
Route::get('/', 'TwitchController@base');
110118

@@ -215,7 +223,7 @@
215223

216224
Route::get('{uptime}/{channel?}', 'TwitchController@uptime')
217225
->where('uptime', '(uptime(\.php)?)')
218-
->where('channel', '([A-z0-9]){1,25}');
226+
->where('channel', $channelRegex);
219227

220228
Route::get('viewercount/{channel?}', 'TwitchController@viewercount')
221229
->where('channel', $channelRegex);

0 commit comments

Comments
 (0)