Beispiel #1
0
func (p *Pool) Handle(logRecord *logger.HAProxyLogRecord) {
	pTime := time.Now()
	if p.Dummy {
		logger.Printf("[pool %s] Dummy", p.Name)
		logRecord.Error(logger.BadGatewayMsg, http.StatusBadGateway)
		logRecord.Terminate("Pool: " + logger.BadGatewayMsg)
		return
	}
	p.Metrics.ConnectionStart()
	defer p.Metrics.ConnectionDone()

	server := p.Next()
	if server == nil {
		// reachable when all servers in pool report StatusMaintenance
		logger.Printf("[pool %s] no server", p.Name)
		logRecord.Error(logger.ServiceUnavailableMsg, http.StatusServiceUnavailable)
		logRecord.Terminate("Pool: " + logger.ServiceUnavailableMsg)
		return
	}
	logRecord.PoolUpdateRecord(p.Name, p.Metrics.GetActiveConnections(), p.Metrics.GetTotalConnections(), pTime)
	server.Handle(logRecord, p.Config.RequestTimeout)
}
Beispiel #2
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)
	}
}