91 lines
2.3 KiB
Go
91 lines
2.3 KiB
Go
package httpclient
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"io"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// NetHTTPClient 使用 net/http 实现 HTTPClient 接口
|
|
type NetHTTPClient struct {
|
|
client *http.Client
|
|
// 可根据需要添加对象池
|
|
}
|
|
|
|
// NewNetHTTPClient 返回一个初始化的 NetHTTPClient
|
|
func NewNetHTTPClient() *NetHTTPClient {
|
|
return &NetHTTPClient{client: &http.Client{}}
|
|
}
|
|
|
|
// Do 发送非流式请求
|
|
func (c *NetHTTPClient) Do(req *Request) (*Response, error) {
|
|
r, err := http.NewRequest(req.Method, req.URL, bytes.NewReader(req.Body))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for k, v := range req.Headers {
|
|
r.Header.Set(k, v)
|
|
}
|
|
resp, err := c.client.Do(r)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
body, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
headers := make(map[string]string)
|
|
for k, v := range resp.Header {
|
|
headers[k] = v[0]
|
|
}
|
|
return &Response{StatusCode: resp.StatusCode, Body: body, Headers: headers}, nil
|
|
}
|
|
|
|
// Stream 发送流式请求,逐块通过 callback 回调 SSE 数据
|
|
func (c *NetHTTPClient) Stream(req *Request, callback func(chunk SSEChunk) error) error {
|
|
r, err := http.NewRequest(req.Method, req.URL, bytes.NewReader(req.Body))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for k, v := range req.Headers {
|
|
r.Header.Set(k, v)
|
|
}
|
|
resp, err := c.client.Do(r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
scanner := bufio.NewScanner(resp.Body)
|
|
for scanner.Scan() {
|
|
text := scanner.Text()
|
|
if text == "" {
|
|
continue
|
|
}
|
|
const prefix = "data: "
|
|
if strings.HasPrefix(text, prefix) {
|
|
payload := text[len(prefix):]
|
|
isDone := payload == "[DONE]"
|
|
var dataBytes []byte
|
|
if !isDone {
|
|
dataBytes = []byte(payload)
|
|
}
|
|
chunk := SSEChunk{
|
|
Data: dataBytes,
|
|
Timestamp: time.Now().UnixNano(),
|
|
IsDone: isDone,
|
|
}
|
|
if err := callback(chunk); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
if err := scanner.Err(); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|