俗话说:善有善报,恶有恶报;话又说:人善被人欺,马善被人骑!古今论坛,后人总结生存言谈:拥有善良之心待人,不向恶势力低头屈身。愿你吸收生存之道,日子过得美满逍遥!
oslo.middleware库可以添加在WSGI pipeline用来拦截request/response请求。其基类可以为WSGI增强功能,如添加、删除、修改HTTP头部信息,支持限制大小和连接数等。本文主要分析Oslo组件如何使用oslo.middleware来实现这些功能。
oslo.middleware中的主要pipeline
oslo.middleware中定义了多个WSGI的pipeline,如cors、request_id等。所以,本文首先总结了oslo.middleware中常用的pipeline的实现、作用以及使用场景。在oslo.middleware中,所有的pipeline的实现类都继承自一个父类ConfigurableMiddleware,其是一个基本的WSGI middleware装饰器。该类在实例化时会绑定一个WSGI应用对象APP,则该ConfigurableMiddleware对象在实际使用中便会对绑定的WSGI APP的request/response进行相应的包装。在ConfigurableMiddleware类中,分别定义了process_request(request)和process_response(response, request)方法分别对request和response进行处理。最后,该类还为paste.deploy实现了factory方法,使其可以通过读取WSGI配置文件调用相关类的装饰器。了解了ConfigurableMiddleware类的实现之后,下面便可以根据ConfigurableMiddleware类的实现针对具体的pipeline的实现进行详细的解读。
CORS
CORS指的是跨域资源共享,该机制允许Web服务器进行跨域访问控制,从而使得跨域数据传输得以安全进行。浏览器支持在API容器中使用CORS,以降低跨域HTTP请求所带来的风险。CORS在原有HTTP协议基础上新增了一组HTTP首部字段,用以表示服务器声明哪些源站可以访问哪些资源,这些字段包括Access-Control-Allow-Origin、Access-Control-Allow-Methods、Access-Control-Allow-Headers、Access-Control-Max-Age等。关于CORS的具体介绍,本文不作详细解释,感兴趣的朋友可以参考以下的博文https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS。
而oslo.middleware中的CORS即是为WSGI请求或响应添加CORS字段和处理的pipeline,其覆写了父类的process_request(request)和process_response(response, request)方法来实现其功能。
1 | simple_headers = [ |
一般地,浏览器发送HTTP请求时,每个请求和请求的响应都会包含一些基本的头部字段;这些字段包括:Accept、Accept-Language、Content-Type、Cache-Control、Content-Language、Expires、Lash-Modified、Pragma等。而oslo.middleware中CORS的功能则是通过获取请求或请求的响应,为该请求添加跨域资源共享的头部字段。CORS覆写了父类的process_response(response, request=None)方法为每个响应添加CORS头部字段。
1 | def process_response(self, response, request=None): |
首先,其会判断该响应的头部字段中是否含有Access-Control-Allow-Origin字段,如果有则直接返回该响应;否则,其会判断发送的请求的方法是否为OPTION,如果为OPTION则表示该请求为跨域资源共享预检请求,程序将调用CORS对象的_apply_cors_preflight_headers(request, response)
方法为该请求的响应添加Vary、Access-Control-Allow-Origin、Access-Control-Allow-Credentials、Access-Control-Max-Age、Access-Control-Allow-Methods、Access-Control-Allow-Headers等字段;否则表示该请求为跨域资源共享基本请求,程序将调用CORS对象的_apply_cors_request_headers(request, response)方法为该请求的响应添加Vary、Access-Control-Allow-Origin、Access-Control-Allow-Credentials、Access-Control-Allow-Headers等字段。
RequestId
request_id在OpenStack的WSGI调用中具有非常重要的作用,它唯一标识了OpenStack API的获取的每一个请求,并将其记录到日志中,便于程序员定位问题等。RequestId类便是为每个发送到OpenStack API的请求添加request_id。该类覆写了父类的call方法,首先会判断该请求是否包含一个全局的request_id,即请求头部是否包含X-Openstack-Request-Id字段,如果包含则将该全局的request_id添加到该环境变量openstack.global_request_id中;接着该类会通过oslo.context中的generate_request_id()方法生成一个request_id,将其添加到环境变量openstack.request_id中,并将其追加到对应响应的头部。
1 |
|
CorrelationId
correlation_id为OpenStack API接收到的每个请求设置一个关联的ID,程序员可以根据该ID查询与相关请求的操作。CorrelationId通过覆写process_request(request)方法,为OpenStack API接收到的每个请求添加X_CORRELATION_ID存储其correlation_id。
HTTPProxyToWSGI
HTTPProxyToWSGI为OpenStack API提供反向代理的功能,其通过一个远程HTTP反向代理服务器重载WSGI的环境变量。该类通过覆写process_request(request)方法为OpenStack API接收到的每一个请求添加了RFC7239中指定的HTTP反向代理所需的头部字段。在接收到请求时,首先判断OpenStack服务是否允许使用HTTP代理头部,如果不允许则直接返回。接着,获取请求环境变量中的HTTP_FORWARDED是否为空,如果不为空则通过RFC7239标准解析该字段,获取相应的代理参数并添加到请求wsgi的环境变量中;否则,直接获取请求环境变量中与HTTP代理相关的字段添加到请求wsgi的环境变量中
1 | def process_request(self, req): |
除了上述的pipeline外,oslo.middleware还定义了很多种pipeline,如限制请求体大小的RequestBodySizeLimiter、获取不到请求的响应抛出异常的CatchErrors、添加SSL认证的SSLMiddleware、基于API请求发送stats指令的StatsMiddleware等。而这些pipeline在实现上与上述pipeline的实现大同小异,因此这里便不在挨个展开介绍,感兴趣的朋友可以根据上述博客的内容举一反三,自行研究。下面,将详细介绍oslo.middleware在OpenStack其他组件的使用方法。
oslo.middleware的使用方式
因为oslo.middleware为WSGI的框架paste.deploy提供对应的pipeline,因此在OpenStack其他组件中的使用也非常简单。这里以Nova组件的WSGI为例,介绍oslo.middleware中各pipeline的使用。
Nova组件的WSGI配置文件api-paste.ini中,定义了多个app、pipeline以及composite,其中多个便直接使用了oslo.middleware中定义的pipeline,如2.1版本的计算服务API
openstack_compute_api_v21中便使用了cors、http_proxy_to_wsgi、sizelimit等多个oslo.middleware的pipeline。其配置文件如下:
1 | [composite:openstack_compute_api_v21] |
因此,在需要使用oslo.middleware中的pipeline时,OpenStack各组件只需要在相应服务的WSGI配置文件中添加一个对应的filter,并将paste.filter_factory指定为相应类的factory方法即可。而如果一个pipeline需要指定配置参数时,既可以直接在filter中指定,也可以在对应服务的配置文件中的oslo_middleware配置组下添加。而如果需要直接在代码中使用oslo.middleware的各pipeline的实现类,只需要将对应的模块导入即可。
原文链接:https://blog.csdn.net/Bill_Xiang_/article/details/78552271