HTTP请求处理程序(HTTP Handler)

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
    # get request_body
        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
        content_type = environ['CONTENT_TYPE']
    except (KeyError):
        content_type = " "
    # get query_string
        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