# 请求流程

## 1 Application 入口

![image](https://github.com/meetbill/butterfly/blob/master/images/wsgi_flow.png?raw=true)

wsgigw = httpgateway.WSGIGateway(httpgateway.get\_func\_name,logger.errlog,logger.acclog,apicube)

```
status, headders, content = wsgigw.process(environ)
start_response(status, headders)
return content
```

其中

> * httpgateway.get\_func\_name : 根据 environ\['PATH\_INFO'] 找到对应的 url
> * logger.errlog : 错误日志文件
> * logger.acclog : 访问日志文件
> * apicube : protocols 字典，key 为 func name，value 为 Protocol 实例

wsgigw\.process 主要就是做三件事

```
 1) 封装 request
 2) 路由查询
 3) 将请求 request 发到对应的 protocol 实例（对 handler 进行的封装）
```

> * 对 wsgienv 进行封装为 req
>   * req = Request(reqid, wsgienv, ip) : req 对 wsgienv 进行封装，此 req 会以参数传入后端 handler 函数中
> * 路由查询
> * 将 req 传给对 api 封装后的 protocol 实例
>   * protocol = `self._protocols.get(funcname)`
>   * httpstatus, headers, content = protocol(req)
>   * protocol 实例是对 handler 函数进行的包装，进行统一日志管理以及参数校验等操作

```
         +---------------------------------------------------------+
         |                       WEB brower                        |
         +---------------------------------------------------------+
             |                           ^       ^          ^
             |                           |       |          |
             |HTTP request               |       |          |
             |                           |       |          |
      -- +---V-----------------------------------------------------+
    /    |                       HTTPServer                        |  WSGI server
    |    |     +-------------------+ put +-------------------+     |
    |    |     |ThreadPool(Queue) <+-----+ HTTPConnection    |     |
    |    |     |+---------------+  |     | +---------------+ |     |
    |    |     ||WorkerThread   |  |     | |HTTPRequest    | |     |
    |    |     |+---------------+  |     | +---------------+ |     |
    |    |     +-------------------+     +-------------------+     |
    |    +---------------------------------------------------------+
    |          /------------\            ^       ^          ^
    |         |   environ    |           |       |          |
    |          \------------/            |       |          |
    |   .............|...................|.......|..........|.........WSGI
    |                |                   |       |          |
    |         +------V-------+           |       |          |
    |         |      req     |           |       |          |
    |         +--------------+           |       |          |
Butterfly            |                   |       |          |
    |         +------V-------+           |       |          |
    |         |apiname_getter|           |       |          |
    |         +--------------+           |       |          |
    |                |                   |       |          |
    |       +--------V--------+ False +--+--+    |          |
    |       |is_protocol_exist|------>| 400 |    |          |
    |       +-----------------+       +-----+    |          |
    |                |                           |          |
    |                | (protocol_process)        |          |
    |                V                           |          |
    |       +-----------------+                  |          |
    |       | protocol        |  Exception    +-----+       |
    |       | +-------------+ |---------------| 500 |       |
    |       | |/app1/handler| |               +-----+       |
    |       | |/app2/handler| |               +----------------------------+
    |       | +-------------+ |---------------|httpstatus, headers, content|
    \       +-----------------+               +----------------------------+
     ---
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://meetbill.gitbook.io/butterfly-project-doc/project-framework/how/api/butterfly-requestflow.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
