func (h *Http) readResponses(tee *conn.Tee, lastTxn chan *HttpTxn) { for { var err error txn := <-lastTxn resp, err := http.ReadResponse(tee.ReadBuffer(), txn.Req.Request) txn.Duration = time.Since(txn.Start) h.reqTimer.Update(txn.Duration) if err != nil { tee.Warn("Error reading response from server: %v", err) // no more responses to be read, we're done break } // make sure we read the body of the response so that // we don't block the reader _, _ = httputil.DumpResponse(resp, true) txn.Resp = &HttpResponse{Response: resp} txn.Resp.BodyBytes, txn.Resp.Body, err = extractBody(resp.Body) if err != nil { tee.Warn("Failed to extract response body: %v", err) } h.Txns.In() <- txn } }
func (h *Http) readResponses(tee *conn.Tee, lastTxn chan *HttpTxn) { for txn := range lastTxn { resp, err := http.ReadResponse(tee.ReadBuffer(), txn.Req.Request) txn.Duration = time.Since(txn.Start) h.reqTimer.Update(txn.Duration) if err != nil { tee.Warn("Error reading response from server: %v", err) // no more responses to be read, we're done break } // make sure we read the body of the response so that // we don't block the reader _, _ = httputil.DumpResponse(resp, true) txn.Resp = &HttpResponse{Response: resp} // apparently, Body can be nil in some cases if resp.Body != nil { txn.Resp.BodyBytes, txn.Resp.Body, err = extractBody(resp.Body) if err != nil { tee.Warn("Failed to extract response body: %v", err) } } h.Txns.In() <- txn // XXX: remove web socket shim in favor of a real websocket protocol analyzer if txn.Req.Header.Get("Upgrade") == "websocket" { tee.Info("Upgrading to websocket") var wg sync.WaitGroup // shim for websockets // in order for websockets to work, we need to continue reading all of the // the bytes in the analyzer so that the joined connections will continue // sending bytes to each other wg.Add(2) go func() { ioutil.ReadAll(tee.WriteBuffer()) wg.Done() }() go func() { ioutil.ReadAll(tee.ReadBuffer()) wg.Done() }() wg.Wait() break } } }