全局中间件

  • 中间件的定义参考Laravel5手册
protected $middleware = [
        // 判断当前程序当前是否处于维护状态
        \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
        // Post请求最大值长度验证
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        // 过滤请求数据 使用trim函数
        \App\Http\Middleware\TrimStrings::class,
        // 过滤请求数据 空("") 转化为 Null 值
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
        // Laravel5.5 新增全局中间件 用于分布式分流SSL,https链接生成
        \App\Http\Middleware\TrustProxies::class,
];
CheckForMaintenanceMode 中间件源码 (判断当前程序是否处于维护状态)
//> laravel 的上线下线命令
php artisan down   //> 进入维护状态
php artisan up       //> 上线状态
//> php artisan down 会在/storage/framework/下面生成一个down文件,记录进入维护状态时间和一些参数(参看图一)
//> php artisan up 会删除该文件
全局中间件_第1张图片
图一
  • \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode源码
app = $app;
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     *
     * @throws \Symfony\Component\HttpKernel\Exception\HttpException
     */
    public function handle($request, Closure $next)
    {
        //> isDownForMaintenance() 判断当前程序是否处于维护状态
        if ($this->app->isDownForMaintenance()) {
            //> php artisan down 生成的是一个json文件类型数据,转换成数组
            $data = json_decode(file_get_contents($this->app->storagePath().'/framework/down'), true);
            //> 抛出一个异常 响应一个503状态
            throw new MaintenanceModeException($data['time'], $data['retry'], $data['message']);
        }

        return $next($request);
    }
}
//> 参看一下 (\Illuminate\Foundation\Application) app 应用的 isDownForMaintenance() 方法的定义
    /**
     * Determine if the application is currently down for maintenance.
     *
     * @return bool
     */
    public function isDownForMaintenance()
    {
        //> file_exists() 检查目录或文件是否存在
        return file_exists($this->storagePath().'/framework/down');
    }

ValidatePostSize 验证POST的最大请求量
//> php.ini 中 post_max_size 允许接收POST数据的最大值(一般默认8M或16M)0表示不启用post请求
//> php可以通过 ini_set() 方法设置php配置相关值(包括post_max_size大小)
//> ini_get() 函数能获取php配置文件相关值
  • \Illuminate\Foundation\Http\Middleware\ValidatePostSize 源码
 获取php配置文件里 php_max_size 大小值
        $max = $this->getPostMaxSize();

        //> CONTENT_LENGTH post请求数据长度
        if ($max > 0 && $request->server('CONTENT_LENGTH') > $max) {
            //> 抛出异常 post请求太长 PostTooLargeException 是原生的 Excption 的一个子类
            throw new PostTooLargeException;
        }

        return $next($request);
    }

    /**
     * Determine the server 'post_max_size' as bytes.
     *
     * @return int
     */
    protected function getPostMaxSize()
    {
        //> ini_get() 获取 post_max_size 配置值 可能(8M、1G、12K、等)
        //> is_numeric() 判断当前变量值是否是数值或数值类型的字符串 | 返回值 bool
        if (is_numeric($postMaxSize = ini_get('post_max_size'))) {
            return (int) $postMaxSize;
        }

        $metric = strtoupper(substr($postMaxSize, -1));

        switch ($metric) {
            case 'K':
                return (int) $postMaxSize * 1024;
            case 'M':
                return (int) $postMaxSize * 1048576;
            case 'G':
                return (int) $postMaxSize * 1073741824;
            default:
                return (int) $postMaxSize;
        }
    }
}

TrimStrings 请求数据都执行一遍 trim() 函数
  • \App\Http\Middleware\TrimStrings 源码
/* TrimStrings 类 */
except 排除过滤
        if (in_array($key, $this->except, true)) {
            return $value;
        }

        // 如果请求值不存在 $this->except 中,判断是否为字符串
        // 是字符串使用trim函数过滤
        return is_string($value) ? trim($value) : $value;
    }
}
/* TransformsRequest */
attributes = $attributes;

        // 重置 GET 、POST | JSON 请求数据
        // 使用 trim() 函数过滤数据
        $this->clean($request);

        return $next($request);
    }

    /**
     * Clean the request's data.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return void
     */
    protected function clean($request)
    {
        // 过滤 $_GET 全局变量里数据 使用trim()函数
        $this->cleanParameterBag($request->query);

        // 如果请求是JSON提交,过滤json提交的数据
        if ($request->isJson()) {
            $this->cleanParameterBag($request->json());
        } else {
            // 过滤请求是 $_POST 全局变量里数据 使用trim()函数
            $this->cleanParameterBag($request->request);
        }
    }

    /**
     * Clean the data in the parameter bag.
     *
     * @param  \Symfony\Component\HttpFoundation\ParameterBag  $bag
     * @return void
     */
    protected function cleanParameterBag(ParameterBag $bag)
    {
        $bag->replace($this->cleanArray($bag->all()));
    }

    /**
     * Clean the data in the given array.
     *
     * @param  array  $data
     * @return array
     */
    protected function cleanArray(array $data)
    {
        return collect($data)->map(function ($value, $key) {
            return $this->cleanValue($key, $value);
        })->all();
    }

    /**
     * Clean the given value.
     *
     * @param  string  $key
     * @param  mixed  $value
     * @return mixed
     */
    protected function cleanValue($key, $value)
    {
        if (is_array($value)) {
            return $this->cleanArray($value);
        }

        return $this->transform($key, $value);
    }

    /**
     * Transform the given value.
     *
     * @param  string  $key
     * @param  mixed  $value
     * @return mixed
     */
    protected function transform($key, $value)
    {
        return $value;
    }
}

ConvertEmptyStringsToNull 把请求中所有''字符串转换为null值
  • Illuminate\Foundation\Http\Middleware 源码(和TrimStrings代码基本一致)
 把所有请求的 '' 字符串转换为 null 值
        return is_string($value) && $value === '' ? null : $value;
    }
}
// 该中间件和继承TransformsRequest源码参考TrimStrings中间件

TrustProxies
当你在运行的应用位于会终止 TLS/SSL 证书的负载均衡之后时,
你可能会注意到应用有时候不会生成 HTTPS 链接,通常这是因
为你的应用在80端口上被负载均衡器转发流量了,然后就不知道
应该生成安全链接了 (参看 服务器 均衡负载 相关 "Apache均衡负载")
 'FORWARDED',
        Request::HEADER_X_FORWARDED_FOR => 'X_FORWARDED_FOR',
        Request::HEADER_X_FORWARDED_HOST => 'X_FORWARDED_HOST',
        Request::HEADER_X_FORWARDED_PORT => 'X_FORWARDED_PORT',
        Request::HEADER_X_FORWARDED_PROTO => 'X_FORWARDED_PROTO',
    ];
}

你可能感兴趣的:(全局中间件)