-
Notifications
You must be signed in to change notification settings - Fork 40
/
http.go
110 lines (95 loc) · 2.38 KB
/
http.go
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
package http
import (
"bytes"
"encoding/xml"
"net/http"
"strconv"
modelgateway "github.com/bnb-chain/greenfield-storage-provider/model/gateway"
"github.com/bnb-chain/greenfield-storage-provider/pkg/log"
)
const (
successCode = "0"
unknownErrorCode = "-1"
)
// responseWriterDelegator implements http.ResponseWriter and extracts the statusCode.
type responseWriterDelegator struct {
w http.ResponseWriter
written bool
size int
statusCode int
body bytes.Buffer
}
func (wd *responseWriterDelegator) Header() http.Header {
return wd.w.Header()
}
func (wd *responseWriterDelegator) Write(b []byte) (int, error) {
if wd.statusCode == 0 {
wd.statusCode = http.StatusOK
}
if wd.statusCode != http.StatusOK {
// write response body to customized body which used for metrics
wd.body.Write(b)
}
// write response body to http.ResponseWriter
n, err := wd.w.Write(b)
wd.size += n
return n, err
}
func (wd *responseWriterDelegator) GetBody() []byte {
return wd.body.Bytes()
}
func (wd *responseWriterDelegator) WriteHeader(statusCode int) {
wd.written = true
wd.statusCode = statusCode
wd.w.WriteHeader(statusCode)
}
func (wd *responseWriterDelegator) StatusCode() int {
if !wd.written {
return http.StatusOK
}
return wd.statusCode
}
func (wd *responseWriterDelegator) Status() string {
return strconv.Itoa(wd.StatusCode())
}
func (wd *responseWriterDelegator) GetSPErrorCode() string {
// get error response code if exists
var (
errorResp = &modelgateway.ErrorResponse{}
errorCode string
)
if wd.statusCode == http.StatusOK {
errorCode = successCode // no error
} else {
body := wd.GetBody()
err := xml.Unmarshal(body, errorResp)
if err != nil {
log.Errorw("cannot parse gateway error response", "error", err)
errorCode = unknownErrorCode // unknown error code
return errorCode
}
errorCode = strconv.Itoa(int(errorResp.Code))
}
return errorCode
}
// computeApproximateRequestSize compute HTTP request size
func computeApproximateRequestSize(r *http.Request) int {
s := 0
if r.URL != nil {
s += len(r.URL.String())
}
s += len(r.Method)
s += len(r.Proto)
for name, values := range r.Header {
s += len(name)
for _, value := range values {
s += len(value)
}
}
s += len(r.Host)
// N.B. r.Form and r.MultipartForm are assumed to be included in r.URL.
if r.ContentLength != -1 {
s += int(r.ContentLength)
}
return s
}