router.md 7.3 KB
Newer Older
F
feilong 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
# 路由器

下面是一个 HTTP 状态代码的定义:

* 2xx:成功  
  * 200  正常,请求已完成。
  * 201  正常,紧接POST命令。
  * 202  正常,已接受用于处理,但处理尚未完成。
  * 203  正常,部分信息—返回的信息只是一部分。
  * 204  正常,无响应—已接收请求,但不存在要回送的信息。
* 3xx:重定向
  * 301  已移动,请求的数据具有新的位置且更改是永久的。
  * 302  已找到,请求的数据临时具有不同 URI。
  * 303  请参阅其它,可在另一 URI 下找到对请求的响应,且应使用 GET 方法检索此响应。  
  * 304  未修改,未按预期修改文档。
  * 305  使用代理,必须通过位置字段中提供的代理来访问请求的资源。
  * 306  未使用,不再使用,保留此代码以便将来使用。
* 4xx:客户机中出现的错误
  * 400  错误请求,请求中有语法问题,或不能满足请求。
  * 401  未授权,未授权客户机访问数据。
  * 402  需要付款,表示计费系统已有效。
  * 403  禁止,即使有授权也不需要访问。
  * 404  找不到,服务器找不到给定的资源;文档不存在。
  * 407  代理认证请求,客户机首先必须使用代理认证自身。
  * 415  介质类型不受支持,服务器拒绝服务请求,因为不支持请求实体的格式。  
* 5xx:服务器中出现的错误
  * 500  内部错误,因为意外情况,服务器不能完成请求。
  * 501  未执行,服务器不支持请求的工具。
  * 502  错误网关,服务器接收到来自上游服务器的无效响应。
  * 503  无法获得服务,由于临时过载或维护,服务器无法处理请求。

编写一个路由服务,支持注入路由配置,正确处理请求参数

```python
# -*- coding: UTF-8 -*-
from error_code import ErrorCode
import json
import logging
import traceback
logger = logging.getLogger(__name__)

class Router:
    def __init__(self, routes) -> None:
        self.routes = routes

    def dispatch(self, http_request_str):
        # TODO(You): 请实现路由逻辑,返回符合语义的HTTP状态码

if __name__ == '__main__':
    # 注册路由
    router = Router({
        '/': lambda req: print(f'goto home:{str(req)}')
    })

    # 分发路由
    router.dispatch(json.dumps({
        'path': '/',
        'data': ["Hello", "World!"]
    }))
```

以下路由的逻辑代码都一样,请选出**HTTP状态码符合语义**的选项。

## template

```python
from error_code import ErrorCode
import json
import logging
import traceback
logger = logging.getLogger(__name__)


class Router:
    def __init__(self, routes) -> None:
        self.routes = routes

    def dispatch(self, http_request_str):
        ''' 实现一个路由器
        http_request_str: 请求数据字符串,包含 {path:"",data:""}格式的JSON字符串
        '''
        assert http_request_str is not None
        assert type(http_request_str) == type('')

        req_path = None
        req = None
        try:
            http_request = json.loads(http_request_str)
            req_path = http_request.get('path')
            req = http_request.get('data')
        except Exception as e:
            logger.error(f"parse data exception:{str(e)}")
            return {'err': ErrorCode.INVALID_PARAMETERS}, 200

        if req_path is None or self.routes.get(req_path) is None:
            return {'err': ErrorCode.NOT_FOUND}, 404

        try:
            handler = self.routes.get(req_path)
            return handler(req), 200
        except Exception as e:
            logger.error(f"route to '{req_path}' exception:{str(e)}")
            logger.error(traceback.format_exc())
            return {'err': ErrorCode.FAILED}, 500


if __name__ == '__main__':
    server = Router({
        '/': lambda req: print(f'goto home:{str(req)}')
    })
    server.dispatch(json.dumps({
        'path': '/',
        'data': ["Hello", "World!"]
    }))
```

## 答案

```python
class Router:
    def dispatch(self, http_request_str):
        req_path = None
        req = None
        try:
            http_request = json.loads(http_request_str)
            req_path = http_request.get('path')
            req = http_request.get('data')
        except Exception as e:
            logger.error(f"parse data exception:{str(e)}")
            return {'err': ErrorCode.INVALID_PARAMETERS}, 400

        if req_path is None or self.routes.get(req_path) is None:
            return {'err': ErrorCode.NOT_FOUND}, 404

        try:
            handler = self.routes.get(req_path)
            return handler(req), 200
        except Exception as e:
            logger.error(f"route to '{req_path}' exception:{str(e)}")
            logger.error(traceback.format_exc())
            return {'err': ErrorCode.FAILED}, 500
```

## 选项

### A

```python
class Router:
    def dispatch(self, http_request_str):
        req_path = None
        req = None
        try:
            http_request = json.loads(http_request_str)
            req_path = http_request.get('path')
            req = http_request.get('data')
        except Exception as e:
            logger.error(f"parse data exception:{str(e)}")
            return {'err': ErrorCode.INVALID_PARAMETERS}, 200

        if req_path is None or self.routes.get(req_path) is None:
            return {'err': ErrorCode.NOT_FOUND}, 200

        try:
            handler = self.routes.get(req_path)
            return handler(req), 200
        except Exception as e:
            logger.error(f"route to '{req_path}' exception:{str(e)}")
            logger.error(traceback.format_exc())
            return {'err': ErrorCode.FAILED}, 200
```

### B

```python
class Router:
    def dispatch(self, http_request_str):
        req_path = None
        req = None
        try:
            http_request = json.loads(http_request_str)
            req_path = http_request.get('path')
            req = http_request.get('data')
        except Exception as e:
            logger.error(f"parse data exception:{str(e)}")
            return {'err': ErrorCode.INVALID_PARAMETERS}, 301

        if req_path is None or self.routes.get(req_path) is None:
            return {'err': ErrorCode.NOT_FOUND}, 404

        try:
            handler = self.routes.get(req_path)
            return handler(req), 200
        except Exception as e:
            logger.error(f"route to '{req_path}' exception:{str(e)}")
            logger.error(traceback.format_exc())
            return {'err': ErrorCode.FAILED}, 500
```

### C

```python
class Router:
    def dispatch(self, http_request_str):
        req_path = None
        req = None
        try:
            http_request = json.loads(http_request_str)
            req_path = http_request.get('path')
            req = http_request.get('data')
        except Exception as e:
            logger.error(f"parse data exception:{str(e)}")
            return {'err': ErrorCode.INVALID_PARAMETERS}, 200

        if req_path is None or self.routes.get(req_path) is None:
            return {'err': ErrorCode.NOT_FOUND}, 200

        try:
            handler = self.routes.get(req_path)
            return handler(req), 200
        except Exception as e:
            logger.error(f"route to '{req_path}' exception:{str(e)}")
            logger.error(traceback.format_exc())
            return {'err': ErrorCode.FAILED}, 500
```