HTTP请求处理程序(HTTP Handler)

您可以使用HTTP请求处理程序更方便地处理HTTP请求。当调用函数时,函数计算使用您提供的执行方法来处理HTTP请求。本文介绍Python HTTP请求处理程序的结构和特点。

使用说明

使用HTTP请求处理程序前,请确保为HTTP函数配置HTTP触发器。具体信息,请参见配置HTTP触发器并使用HTTP触发

HTTP Handler签名

Python HTTP Handler的签名遵循WSGI(Python Web Server Gateway Interface)规范。

一个简单的HTTP Handler签名定义如下。

def handler(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    return [b'<h1>Hello, world!</h1>']

HTTP Handler签名的示例解析如下:

  • handler:符合WSGI标准的HTTP请求处理函数,可以传入以下两个参数。

    • environ:用于存放所有HTTP请求的信息。

    • start_response:发送HTTP响应的函数。

  • start_response('200 OK', [('Content-Type', 'text/html')]):函数响应。包含两个参数:第一个参数是HTTP状态码;第二个参数是一组Python list对象组成的HTTP Headers,每个Header是一个Python tuple对象,包含两个Python str。

  • return [b'<h1>Hello, world!</h1>']:返回信息。此返回值将作为HTTP响应的Body返回给客户端。

示例:实现Flask应用

示例代码

当实现了符合WSGI协议的HTTP Handler后,基于Flask和Django等流行的Web框架的应用能够非常快速地移植到函数计算上。如下代码展示如何在函数计算的Python Runtime中运行Flask框架的hello world应用。

from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return 'Web App with Python Flask!'

def handler(environ, start_response):
    return app(environ, start_response)

代码示例解释如下:

  • 第一部分:Flask应用的代码。从from flask import Flask开始,至return 'Web App with Python Flask!'结束。

  • 第二部分:handler函数。只需要将handler函数实现为return app(environ, start_response),即可将Flask或Django等Web框架应用运行在函数计算的Python Runtime中。

前提条件

创建服务

操作步骤

  1. 登录函数计算控制台,在左侧导航栏,单击服务及函数
  2. 在顶部菜单栏,选择地域,然后在服务列表页面,单击目标服务。
  3. 函数管理页面,单击创建函数

    创建运行环境为Python 3的HTTP函数。具体操作步骤,请参见创建函数

  4. 函数详情页面,单击函数代码页签,在代码编辑器中输入上述示例代码,然后选择Terminal > New Terminal,在终端框中执行pip install flask -t .,将Flask库安装到当前目录下,最后单击部署代码

  5. 单击测试函数

    函数执行成功后,查看返回结果,您可以看到返回结果为Web App with Python Flask!

请求结构体(environ)

用于存放HTTP请求的信息。其结构为Python字典结构。常见字段如下,更多关于请求结构体的说明,请参见environ说明

参数

类型

解释说明

REQUEST_METHOD

String

HTTP请求方法,例如GET、POST等。

HTTP_Variables

String

HTTP请求头。

CONTENT_TYPE

String

HTTP请求体(Body)类型。

CONTENT_LENGTH

String

HTTP请求体(Body)长度。

REMOTE_ADDR

String

客户端IP地址。

wsgi.input

BytesIO

HTTP请求体(Body)。

fc.request_uri

String

客户端请求的URL,由函数计算定义。

fc.context

FCContext

上下文,由函数计算定义。

说明

请求结构体(environ)中的参数HTTP_Variables是按照WSGI规范对请求头中的key做了处理的HTTP请求头,处理方式为key="HTTP_"+k.upper().replace("-","_")。例如,某个请求头是'x-Custom-key':'value',在请求结构体(environ)中会表现为environ['HTTP_X_CUSTOM_KEY']='value'

获取HTTP Handler请求结构体的示例代码如下。

# Method 1: User provide the function. FC call the function to process request and send back response.

HELLO_WORLD = b"Hello world!\n"

def handler(environ, start_response):
    context = environ['fc.context']
    request_uri = environ['fc.request_uri']
    for k, v in environ.items():
        if k.startswith("HTTP_"):
            # process custom request headers
            pass

    # get request_body
    try:
        request_body_size = int(environ.get('CONTENT_LENGTH', 0))
    except (ValueError):
        request_body_size = 0
    request_body = environ['wsgi.input'].read(request_body_size)

    # get request_method
    request_method = environ['REQUEST_METHOD']

    # get path info
    path_info = environ['PATH_INFO']

    # get server_protocol
    server_protocol = environ['SERVER_PROTOCOL']

    # get content_type
    try:
        content_type = environ['CONTENT_TYPE']
    except (KeyError):
        content_type = " "

    # get query_string
    try:
        query_string = environ['QUERY_STRING']
    except (KeyError):
        query_string = " "

    print ('request_body: {}'.format(request_body))
    print ('method: {}\n path: {}\n  query_string: {}\n server_protocol: {}\n'.format(request_method, path_info,  query_string, server_protocol))
    # do something here

    status = '200 OK'
    response_headers = [('Content-type', 'text/plain')]
    start_response(status, response_headers)
    # return value must be iterable
    return [HELLO_WORLD]

响应结构体

HTTP Handler响应结构体包含响应状态、响应头和响应体。您需要先调用start_response(),将响应状态status和响应头headers的内容返回给服务端,才能返回响应体。响应体要求为可迭代对象。

start_response是一个可调用结构(Callable),结构示例如下。关于start_response的更多信息,请参见the-start-response-callable

# Provided by FC runtime.
# status: a string like '200 OK' or '403 FORBIDDEN'
# return: must be a write(body_data) callable
def start_response(status, response_headers, exc_info=None):
...

参数说明如下。

参数

类型

解释说明

status

String

HTTP响应状态码。

response_headers

List

HTTP响应头。

exc_info

List

用于将当前的异常信息以元组的形式返回。函数计算目前未使用。

限制说明

  • 请求限制

    如果超过以下限制,会返回400状态码和InvalidArgument错误码。

    字段

    限制说明

    HTTP状态码

    错误码

    headers

    请求头中的所有键和值的总大小不能超过8 KB。

    400

    InvalidArgument

    path

    请求路径以及所有查询参数的总大小不能超过4 KB。

    body

    同步调用请求的Body的总大小不能超过32 MB,异步调用请求的Body的总大小不能超过128 KB。

  • 响应限制

    如果超过以下限制,会返回502状态码和BadResponse错误码。

    字段

    限制说明

    HTTP状态码

    错误码

    headers

    响应头中的所有键和值对的大小不能超过8 KB。

    502

    BadResponse