Beispiel #1
0
func (s *Server) Handle(logRecord *logger.HAProxyLogRecord, tout time.Duration) {
	sTime := time.Now()
	s.Metrics.RequestStart()
	defer s.Metrics.RequestDone()

	// X-Forwarded-For; we are a proxy.
	ip := strings.Split(logRecord.Request.RemoteAddr, ":")[0]
	logRecord.Request.Header.Add("X-Forwarded-For", ip)
	logRecord.ServerUpdateRecord(s.Address, s.Metrics.RequestsServiced, s.Metrics.Cost(), sTime)
	resErrCh := make(chan ResponseError)
	tstart := time.Now()
	go s.RoundTrip(logRecord.Request, resErrCh)
	tend := time.Now()
	logRecord.UpdateTr(tstart, tend)
	select {
	case resErr := <-resErrCh:
		if resErr.Error == nil {
			defer resErr.Response.Body.Close()

			logRecord.CopyHeaders(resErr.Response.Header)
			logRecord.WriteHeader(resErr.Response.StatusCode)

			err := logRecord.Copy(resErr.Response.Body)
			if err != nil {
				logger.Errorf("[server %s] failed attempting to copy response body: %s\n", s.Address, err)
			} else {
				logRecord.Log()
			}
		} else {
			logger.Errorf("[server %s] failed attempting the roundtrip: %s\n", s.Address, resErr.Error)
			logRecord.Error(logger.BadGatewayMsg, http.StatusBadGateway)
			logRecord.Terminate("Server: " + logger.BadGatewayMsg)
		}
	case <-time.After(tout):
		s.Transport.CancelRequest(logRecord.Request)
		logger.Printf("[server %s] round trip timed out!", s.Address)
		logRecord.Error(logger.GatewayTimeoutMsg, http.StatusGatewayTimeout)
		logRecord.Terminate("Server: " + logger.GatewayTimeoutMsg)
	}
}