github.com/volts-dev/volts@v0.0.0-20240120094013-5e9c65924106/transport/http_resopnse.go (about) 1 package transport 2 3 import ( 4 "bufio" 5 "context" 6 "fmt" 7 "net" 8 "net/http" 9 "reflect" 10 11 "github.com/volts-dev/volts/internal/body" 12 ) 13 14 // 参考Tango 15 type ( 16 IResponseWriter interface { 17 http.ResponseWriter 18 // Status returns the status code of the response or 0 if the response has not been written. 19 Status() int 20 // Written returns whether or not the ResponseWriter has been written. 21 Written() bool 22 // Size returns the size of the response body. 23 Size() int 24 } 25 26 THttpResponse struct { 27 body *body.TBody // 28 http.ResponseWriter 29 status int 30 size int 31 32 Val reflect.Value 33 } 34 ) 35 36 func NewHttpResponse(ctx context.Context, req *THttpRequest) *THttpResponse { 37 resp := &THttpResponse{ 38 body: body.New(req.Codec()), 39 } 40 resp.Val = reflect.ValueOf(resp) 41 return resp 42 } 43 44 func (self *THttpResponse) Body() *body.TBody { 45 return self.body 46 } 47 48 func (self *THttpResponse) WriteHeader(s int) { 49 self.status = s 50 self.ResponseWriter.WriteHeader(s) 51 } 52 53 func (self *THttpResponse) Write(b []byte) (int, error) { 54 size, err := self.ResponseWriter.Write(b) 55 if self.status == 0 { 56 self.status = http.StatusOK // 至少不是0 57 } 58 self.size += size 59 return size, err 60 } 61 62 // write data as stream 63 func (self *THttpResponse) WriteStream(data interface{}) error { 64 _, err := self.body.Encode(data) 65 if err != nil { 66 return err 67 } 68 69 _, err = self.Write(self.body.Data.Bytes()) 70 if err != nil { 71 return err 72 } 73 74 return nil 75 } 76 77 // writable 78 func (self *THttpResponse) Written() bool { 79 return self.status != 0 80 } 81 82 func (self *THttpResponse) Flush() { 83 flusher, ok := self.ResponseWriter.(http.Flusher) 84 if ok { 85 flusher.Flush() 86 } 87 } 88 89 // Hijack让调用者接管连接,在调用Hijack()后,http server库将不再对该连接进行处理,对于该连接的管理和关闭责任将由调用者接管. 90 func (self *THttpResponse) Hijack() (net.Conn, *bufio.ReadWriter, error) { 91 hijacker, ok := self.ResponseWriter.(http.Hijacker) 92 if !ok { 93 return nil, nil, fmt.Errorf("the ResponseWriter doesn't support the Hijacker interface") 94 } 95 return hijacker.Hijack() 96 } 97 98 func (self *THttpResponse) Status() int { 99 return self.status 100 } 101 102 func (self *THttpResponse) Size() int { 103 return self.size 104 } 105 106 func (self *THttpResponse) Close() { 107 rwc, buf, _ := self.ResponseWriter.(http.Hijacker).Hijack() 108 if buf != nil { 109 buf.Flush() 110 } 111 112 if rwc != nil { 113 rwc.Close() 114 } 115 // Trace("THttpResponse.Close") 116 } 117 118 // Inite and Connect a new ResponseWriter when a new request is coming 119 func (self *THttpResponse) Connect(w http.ResponseWriter) { 120 self.ResponseWriter = w 121 if self.body.Data.Len() > 0 { 122 self.body.Data.Reset() 123 } 124 self.status = 0 125 self.size = 0 126 } 127 128 func (self *THttpResponse) Value() reflect.Value { 129 return self.Val 130 }