62 lines
1.4 KiB
Go
62 lines
1.4 KiB
Go
// Package httpx 提供管理接口共用的 HTTP 辅助(JSON 信封、客户端 IP、HTTPS 判定)。
|
|
package httpx
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"io"
|
|
"net/http"
|
|
)
|
|
|
|
// ErrorBody 是失败响应里的 error 对象。
|
|
type ErrorBody struct {
|
|
Code string `json:"code"`
|
|
Message string `json:"message"`
|
|
}
|
|
|
|
// Envelope 是管理接口通用响应信封。
|
|
type Envelope struct {
|
|
OK bool `json:"ok"`
|
|
Data any `json:"data,omitempty"`
|
|
Error *ErrorBody `json:"error,omitempty"`
|
|
}
|
|
|
|
// WriteJSON 写入 JSON 响应。
|
|
func WriteJSON(w http.ResponseWriter, status int, v any) {
|
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
|
w.WriteHeader(status)
|
|
enc := json.NewEncoder(w)
|
|
enc.SetEscapeHTML(false)
|
|
_ = enc.Encode(v)
|
|
}
|
|
|
|
// WriteOK 写入成功信封。
|
|
func WriteOK(w http.ResponseWriter, data any) {
|
|
WriteJSON(w, http.StatusOK, Envelope{OK: true, Data: data})
|
|
}
|
|
|
|
// WriteError 写入失败信封。
|
|
func WriteError(w http.ResponseWriter, status int, code, message string) {
|
|
WriteJSON(w, status, Envelope{
|
|
OK: false,
|
|
Error: &ErrorBody{
|
|
Code: code,
|
|
Message: message,
|
|
},
|
|
})
|
|
}
|
|
|
|
// DecodeJSON 解码请求 JSON 体;空体对 dst 保持零值。
|
|
func DecodeJSON(r *http.Request, dst any) error {
|
|
defer func() { _ = r.Body.Close() }()
|
|
dec := json.NewDecoder(r.Body)
|
|
dec.DisallowUnknownFields()
|
|
if err := dec.Decode(dst); err != nil {
|
|
if errors.Is(err, io.EOF) {
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
return nil
|
|
}
|