Added accessors for determining ServeConn call start time and the sequence number of request served in the connection

This commit is contained in:
Aliaksandr Valialkin
2015-11-17 16:29:14 +02:00
parent 2eff1422af
commit f3b4ff17b1
2 changed files with 70 additions and 3 deletions
+25 -3
View File
@@ -197,6 +197,9 @@ type RequestCtx struct {
id uint64
serveConnRequestNum uint64
serveConnTime time.Time
time time.Time
logger ctxLogger
@@ -269,6 +272,18 @@ func (ctx *RequestCtx) Time() time.Time {
return ctx.time
}
// ServeConnTime returns the time server starts serving the connection
// the current request came from.
func (ctx *RequestCtx) ServeConnTime() time.Time {
return ctx.serveConnTime
}
// ServeConnRequestNum returns request sequence number
// for the current connection.
func (ctx *RequestCtx) ServeConnRequestNum() uint64 {
return ctx.serveConnRequestNum
}
// SetConnectionClose sets 'Connection: close' response header and closes
// connection after the RequestHandler returns.
func (ctx *RequestCtx) SetConnectionClose() {
@@ -641,19 +656,22 @@ func (s *Server) serveConn(c net.Conn) error {
readTimeout := s.ReadTimeout
writeTimeout := s.WriteTimeout
currentTime := time.Now()
ctx := s.acquireCtx(c)
ctx.serveConnRequestNum = 0
ctx.serveConnTime = currentTime
var br *bufio.Reader
var bw *bufio.Writer
var dt time.Duration
var prevReadTime time.Time
var err error
var currentTime time.Time
var connectionClose bool
var errMsg string
for {
currentTime = time.Now()
ctx.id++
ctx.serveConnRequestNum++
ctx.time = currentTime
if readTimeout > 0 {
@@ -724,6 +742,8 @@ func (s *Server) serveConn(c net.Conn) error {
break
}
}
currentTime = time.Now()
}
if br != nil {
@@ -869,7 +889,9 @@ func (ctx *RequestCtx) Init(req *Request, remoteAddr net.Addr, logger Logger) {
ctx.initID()
req.CopyTo(&ctx.Request)
ctx.Response.Clear()
ctx.time = time.Now()
ctx.serveConnRequestNum = 0
ctx.serveConnTime = time.Now()
ctx.time = ctx.serveConnTime
}
var fakeServer Server
+45
View File
@@ -166,6 +166,51 @@ func TestServerConnectionClose(t *testing.T) {
}
}
func TestServerRequestNumAndTime(t *testing.T) {
n := uint64(0)
var connT time.Time
s := &Server{
Handler: func(ctx *RequestCtx) {
n++
if ctx.ServeConnRequestNum() != n {
t.Fatalf("unexpected request number: %d. Expecting %d", ctx.ServeConnRequestNum(), n)
}
if connT.IsZero() {
connT = ctx.ServeConnTime()
}
if ctx.ServeConnTime() != connT {
t.Fatalf("unexpected serve conn time: %s. Expecting %s", ctx.ServeConnTime(), connT)
}
},
}
rw := &readWriter{}
rw.r.WriteString("GET /foo1 HTTP/1.1\r\nHost: google.com\r\n\r\n")
rw.r.WriteString("GET /bar HTTP/1.1\r\nHost: google.com\r\n\r\n")
rw.r.WriteString("GET /baz HTTP/1.1\r\nHost: google.com\r\n\r\n")
ch := make(chan error)
go func() {
ch <- s.ServeConn(rw)
}()
select {
case err := <-ch:
if err != nil {
t.Fatalf("Unexpected error from serveConn: %s", err)
}
case <-time.After(100 * time.Millisecond):
t.Fatalf("timeout")
}
if n != 3 {
t.Fatalf("unexpected number of requests served: %d. Expecting %d", n, 3)
}
br := bufio.NewReader(&rw.w)
verifyResponse(t, br, 200, string(defaultContentType), "")
}
func TestServerEmptyResponse(t *testing.T) {
s := &Server{
Handler: func(ctx *RequestCtx) {