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  }