Skip to content

Commit

Permalink
fix: potential panic in reverse proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
mcharytoniuk committed Jul 15, 2024
1 parent efb56a5 commit dfea6c4
Showing 1 changed file with 37 additions and 16 deletions.
53 changes: 37 additions & 16 deletions loadbalancer/RespondToCompletion.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package loadbalancer

import (
"fmt"
"net/http"
"time"

Expand Down Expand Up @@ -32,15 +33,19 @@ func (self *RespondToCompletion) ServeHTTP(response http.ResponseWriter, request

defer bufferedRequest.Close()

self.Logger.Info("TEST")
go self.handleRequest(bufferedRequest, true)

select {
case <-bufferedRequest.DoneChannel:
// buffer finished
self.Logger.Info("BUFFER FINISHED")
case <-request.Context().Done():
// request is canceled
self.Logger.Info("REQUEST IS CANCELED")
case <-time.After(self.LoadBalancerConfiguration.RequestBufferTimeout):
http.Error(response, "Request Timeout", http.StatusGatewayTimeout)
self.Logger.Info("REQUEST TIMEOUT")
}
}

Expand All @@ -52,12 +57,35 @@ func (self *RespondToCompletion) bufferRequest(bufferedRequest *BufferedRequest)
}
}

func (self *RespondToCompletion) StartBufferProcessor() {
ticker := time.NewTicker(time.Second)
defer ticker.Stop()

for range ticker.C {
select {
case bufferedRequest := <-self.BufferChannel:
if bufferedRequest.IsDone {
continue
}

if time.Now().After(bufferedRequest.Timeout) {
continue
}

go self.handleRequest(bufferedRequest, false)
default:
// no buffered requests
}
}
}

func (self *RespondToCompletion) handleRequest(
bufferedRequest *BufferedRequest,
isInitial bool,
) {
balancingAttemptStatusChannel := make(chan *BalancingAttemptStatus)
defer close(balancingAttemptStatusChannel)
defer self.recoverFromPanic(bufferedRequest)

go self.LoadBalancer.Balance(
balancingAttemptStatusChannel,
Expand Down Expand Up @@ -92,24 +120,17 @@ func (self *RespondToCompletion) handleRequest(
}
}

func (self *RespondToCompletion) StartBufferProcessor() {
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
func (self *RespondToCompletion) recoverFromPanic(bufferedRequest *BufferedRequest) {
r := recover()

for range ticker.C {
select {
case bufferedRequest := <-self.BufferChannel:
if bufferedRequest.IsDone {
continue
}
if r == nil {
return
}

if time.Now().After(bufferedRequest.Timeout) {
continue
}
bufferedRequest.SendError("Bad Gateway", http.StatusBadGateway)

go self.handleRequest(bufferedRequest, false)
default:
// no buffered requests
}
self.ServerEventsChannel <- goroutine.ResultMessage{
Comment: "reverse proxy panicked",
Error: fmt.Errorf("%v", r),
}
}

0 comments on commit dfea6c4

Please sign in to comment.