118 lines
3.0 KiB
Go
118 lines
3.0 KiB
Go
package testweb
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"strings"
|
||
"time"
|
||
)
|
||
|
||
// ToPostmanCollection 将解析后的日志转为 Postman Collection v2.1(ApiPost 可导入)。
|
||
func ToPostmanCollection(log *ParsedAPILog, useInbound bool) ([]byte, error) {
|
||
if log == nil {
|
||
return nil, fmt.Errorf("nil log")
|
||
}
|
||
sec := log.Outbound
|
||
name := "file upload outbound"
|
||
if useInbound {
|
||
sec = log.Inbound
|
||
name = "file upload inbound"
|
||
}
|
||
if sec.URL == "" && log.Outbound.URL != "" {
|
||
sec = log.Outbound
|
||
}
|
||
|
||
headers := make([]map[string]any, 0, len(sec.Headers))
|
||
for k, v := range sec.Headers {
|
||
headers = append(headers, map[string]any{
|
||
"key": k,
|
||
"value": v,
|
||
"type": "text",
|
||
})
|
||
}
|
||
|
||
_, bodyObj := postmanBody(sec)
|
||
url := sec.URL
|
||
if url == "" {
|
||
url = "{{fileTarget}}"
|
||
}
|
||
|
||
item := map[string]any{
|
||
"name": name,
|
||
"request": map[string]any{
|
||
"method": "POST",
|
||
"header": headers,
|
||
"body": bodyObj,
|
||
"url": url,
|
||
"description": "从 forward-go api-log 导出;multipart 请在 ApiPost 中重新选择 PDF 文件",
|
||
},
|
||
}
|
||
|
||
if log.Response.Body != "" || log.Response.BodyJSON != "" {
|
||
body := log.Response.Body
|
||
if log.Response.BodyJSON != "" {
|
||
body = log.Response.BodyJSON
|
||
}
|
||
item["response"] = []map[string]any{{
|
||
"name": "example",
|
||
"status": "OK",
|
||
"code": log.Response.Status,
|
||
"header": responseHeaders(log.Response.Headers),
|
||
"body": body,
|
||
"_postman_previewlanguage": "json",
|
||
}}
|
||
}
|
||
|
||
col := map[string]any{
|
||
"info": map[string]any{
|
||
"name": fmt.Sprintf("forward-file-%s", time.Now().Format("20060102150405")),
|
||
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
|
||
},
|
||
"item": []map[string]any{item},
|
||
}
|
||
return json.MarshalIndent(col, "", " ")
|
||
}
|
||
|
||
func postmanBody(sec RequestSection) (mode string, body map[string]any) {
|
||
ct := strings.ToLower(sec.Headers["Content-Type"])
|
||
if strings.Contains(ct, "multipart/form-data") {
|
||
formdata := []map[string]any{
|
||
{
|
||
"key": "file",
|
||
"type": "file",
|
||
"src": "",
|
||
"description": "请在 ApiPost 中选择 PDF;日志中为 body_base64 落盘",
|
||
},
|
||
{
|
||
"key": "_note",
|
||
"type": "text",
|
||
"value": fmt.Sprintf("body_len=%d,从 forward api-log 导出", sec.BodyLen),
|
||
"disabled": true,
|
||
},
|
||
}
|
||
return "formdata", map[string]any{"mode": "formdata", "formdata": formdata}
|
||
}
|
||
raw := sec.BodyRaw
|
||
if len(sec.BodyBytes) > 0 && !sec.BodyPlain {
|
||
raw = string(sec.BodyBytes)
|
||
}
|
||
if raw == "" && sec.BodyBase64 != "" {
|
||
raw = "[base64 body, len=" + fmt.Sprint(sec.BodyLen) + "]"
|
||
}
|
||
return "raw", map[string]any{
|
||
"mode": "raw",
|
||
"raw": raw,
|
||
"options": map[string]any{
|
||
"raw": map[string]any{"language": "json"},
|
||
},
|
||
}
|
||
}
|
||
|
||
func responseHeaders(h map[string]string) []map[string]string {
|
||
out := make([]map[string]string, 0, len(h))
|
||
for k, v := range h {
|
||
out = append(out, map[string]string{"key": k, "value": v})
|
||
}
|
||
return out
|
||
}
|