Removing trailing slashes in Laravel, the right way

While doing a quick search for a Laravel middleware to remove trailing slashes from URL's, I found some articles at the top of the search results with some naive and incorrect solutions. Let me explain.

The proposed solutions looked something like this:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class RedirectTrailingSlash
{
    public function handle(Request $request, Closure $next)
    {
        if (preg_match('/.+\/$/', $request->getRequestUri())) {
            $url = rtrim($request->getRequestUri(), '/');

            return redirect($url, 301);
        }

        return $next($request);
    }
}

At first glance this seems to work, but it contains an obvious error.

$request->getRequestUri() returns the requested URI, which consists of the path and the query string. The regular expression that checks for the existence of a trailing slash does not work correctly when the requested URI contains a query string.

A more correct implementation should check the requested path in isolation. Something like this:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class TrimTrailingSlash
{
    public function handle(Request $request, Closure $next)
    {
        $path = $request->getPathInfo();

        // Skip root path
        if ($path === '/') {
            return $next($request);
        }

        $trimmedPath= rtrim($path, '/');

        // If $trimmedPath is not equal to actual path, a trailing
        // slash has been trimmed. We should redirect to the new path
        if ($request->getPathInfo() !== $trimmedPath) {
            $uri = $trimmedPath;

            // If the requested URI has a query string we should
            // include it in the new URI
            $queryString = $request->getQueryString();
            if ($queryString) {
                $uri = "$uri?$queryString";
            }

            return redirect($uri, 301);
        }

        return $next($request);
    }
}

Or you could use illuminatech/url-trailing-slash if you don't want to roll your own.