|
| 1 | +import json |
1 | 2 | import time |
2 | 3 |
|
3 | 4 | from asyncio import Queue |
@@ -150,7 +151,7 @@ async def dispatch(self, request: Request, call_next: Any) -> Response: |
150 | 151 |
|
151 | 152 | return response |
152 | 153 |
|
153 | | - async def get_request_args(self, request: Request) -> dict[str, Any] | None: |
| 154 | + async def get_request_args(self, request: Request) -> dict[str, Any] | None: # noqa: C901 |
154 | 155 | """ |
155 | 156 | 获取请求参数 |
156 | 157 |
|
@@ -178,26 +179,65 @@ async def get_request_args(self, request: Request) -> dict[str, Any] | None: |
178 | 179 | if body_data: |
179 | 180 | # 注意:非 json 数据默认使用 data 作为键 |
180 | 181 | if 'application/json' not in content_type: |
181 | | - args['data'] = str(body_data) |
| 182 | + args['data'] = body_data.decode('utf-8', 'ignore') if isinstance(body_data, bytes) else str(body_data) |
182 | 183 | else: |
183 | 184 | json_data = await request.json() |
184 | 185 | if isinstance(json_data, dict): |
185 | 186 | args['json'] = await self.desensitization(json_data) |
186 | 187 | else: |
187 | | - args['data'] = str(body_data) |
| 188 | + args['data'] = str(json_data) |
188 | 189 |
|
189 | 190 | # 表单参数 |
190 | 191 | form_data = await request.form() |
191 | 192 | if len(form_data) > 0: |
| 193 | + serialized_form = {} |
192 | 194 | for k, v in form_data.items(): |
193 | | - form_data = {k: v.filename} if isinstance(v, UploadFile) else {k: v} |
| 195 | + if isinstance(v, UploadFile): |
| 196 | + serialized_form[k] = { |
| 197 | + 'filename': v.filename, |
| 198 | + 'content_type': v.content_type, |
| 199 | + 'size': v.size, |
| 200 | + } |
| 201 | + else: |
| 202 | + serialized_form[k] = v |
194 | 203 | if 'multipart/form-data' not in content_type: |
195 | | - args['x-www-form-urlencoded'] = await self.desensitization(form_data) |
| 204 | + args['x-www-form-urlencoded'] = await self.desensitization(serialized_form) |
196 | 205 | else: |
197 | | - args['form-data'] = await self.desensitization(form_data) |
| 206 | + args['form-data'] = await self.desensitization(serialized_form) |
| 207 | + |
| 208 | + if args: |
| 209 | + args = self.truncate(args) |
198 | 210 |
|
199 | 211 | return args or None |
200 | 212 |
|
| 213 | + @staticmethod |
| 214 | + def truncate(args: dict[str, Any]) -> dict[str, Any]: |
| 215 | + """ |
| 216 | + 截断处理 |
| 217 | +
|
| 218 | + :param args: 需要截断的请求参数字典 |
| 219 | + :return: |
| 220 | + """ |
| 221 | + max_size = 10240 # 数据最大大小(字节) |
| 222 | + |
| 223 | + try: |
| 224 | + args_str = json.dumps(args, ensure_ascii=False) |
| 225 | + args_size = len(args_str.encode('utf-8')) |
| 226 | + |
| 227 | + if args_size > max_size: |
| 228 | + truncated_str = args_str[:max_size] |
| 229 | + return { |
| 230 | + '_truncated': True, |
| 231 | + '_original_size': args_size, |
| 232 | + '_max_size': max_size, |
| 233 | + '_message': f'数据过大已截断:原始大小 {args_size} 字节,限制 {max_size} 字节', |
| 234 | + 'data_preview': truncated_str, |
| 235 | + } |
| 236 | + except Exception as e: |
| 237 | + log.error(f'请求参数截断处理失败:{e}') |
| 238 | + |
| 239 | + return args |
| 240 | + |
201 | 241 | @staticmethod |
202 | 242 | @sync_to_async |
203 | 243 | def desensitization(args: dict[str, Any]) -> dict[str, Any]: |
|
0 commit comments