Skip to content

Commit

Permalink
Append previous provisional response to the final response
Browse files Browse the repository at this point in the history
  • Loading branch information
ghettovoice committed Feb 21, 2020
1 parent de9dacb commit 47c3459
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 20 deletions.
50 changes: 36 additions & 14 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,23 +212,24 @@ func (srv *Server) RequestWithContext(ctx context.Context, request sip.Request,
return nil, err
}

errTerminated := &sip.RequestError{
Request: request.Short(),
Code: 487,
Reason: "Request Terminated",
}

responses := make(chan sip.Response)
errs := make(chan error)
go func() {
var lastResponse sip.Response

previousResponses := make([]sip.Response, 0)
previousResponsesStatuses := make(map[sip.StatusCode]bool)

for {
select {
case <-ctx.Done():
if lastResponse != nil && lastResponse.IsProvisional() {
srv.cancelRequest(request, lastResponse)
}
errs <- errTerminated
if lastResponse != nil {
lastResponse.SetPrevious(previousResponses)
}
errs <- sip.NewRequestError(487, "Request Terminated", request, lastResponse)
// pull out later possible transaction responses and errors
go func() {
for {
Expand All @@ -243,22 +244,38 @@ func (srv *Server) RequestWithContext(ctx context.Context, request sip.Request,
return
case err, ok := <-tx.Errors():
if !ok {
errs <- errTerminated
if lastResponse != nil {
lastResponse.SetPrevious(previousResponses)
}
errs <- sip.NewRequestError(487, "Request Terminated", request, lastResponse)
return
}
errs <- err
return
case response, ok := <-tx.Responses():
if !ok {
errs <- errTerminated
if lastResponse != nil {
lastResponse.SetPrevious(previousResponses)
}
errs <- sip.NewRequestError(487, "Request Terminated", request, lastResponse)
return
}

response = sip.CopyResponse(response)
lastResponse = response

if response.IsProvisional() {
if _, ok := previousResponsesStatuses[response.StatusCode()]; !ok {
previousResponses = append(previousResponses, response)
}

continue
}

// success
if response.IsSuccess() {
response.SetPrevious(previousResponses)

if request.IsInvite() {
srv.ackInviteRequest(request, response)
srv.rememberInviteRequest(request)
Expand All @@ -270,28 +287,33 @@ func (srv *Server) RequestWithContext(ctx context.Context, request sip.Request,
}

responses <- response

return
}

// unauth request
if (response.StatusCode() == 401 || response.StatusCode() == 407) && authorizer != nil {
if err := authorizer.AuthorizeRequest(request, response); err != nil {
errs <- err

return
}

if response, err := srv.RequestWithContext(ctx, request, nil); err == nil {
responses <- response
} else {
errs <- err
}

return
}

// failed request
err := &sip.RequestError{
Request: request.Short(),
Code: uint(response.StatusCode()),
Reason: response.Reason(),
if lastResponse != nil {
lastResponse.SetPrevious(previousResponses)
}
errs <- err
errs <- sip.NewRequestError(uint(response.StatusCode()), response.Reason(), request, lastResponse)

return
}
}
Expand Down
21 changes: 18 additions & 3 deletions sip/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,24 @@ package sip
import "fmt"

type RequestError struct {
Request string
Code uint
Reason string
Request Request
Response Response
Code uint
Reason string
}

func NewRequestError(code uint, reason string, request Request, response Response) *RequestError {
err := &RequestError{
Code: code,
Reason: reason,
}
if request != nil {
err.Request = CopyRequest(request)
}
if response != nil {
err.Response = CopyResponse(response)
}
return err
}

func (err *RequestError) Error() string {
Expand Down
21 changes: 18 additions & 3 deletions sip/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ type Response interface {
SetStatusCode(code StatusCode)
Reason() string
SetReason(reason string)
// Previous returns previous provisional responses
Previous() []Response
SetPrevious(responses []Response)
/* Common helpers */
IsProvisional() bool
IsSuccess() bool
Expand All @@ -29,8 +32,9 @@ type Response interface {

type response struct {
message
status StatusCode
reason string
status StatusCode
reason string
previous []Response
}

func NewResponse(
Expand Down Expand Up @@ -86,6 +90,14 @@ func (res *response) SetReason(reason string) {
res.reason = reason
}

func (res *response) Previous() []Response {
return res.previous
}

func (res *response) SetPrevious(responses []Response) {
res.previous = responses
}

// StartLine returns Response Status Line - RFC 2361 7.2.
func (res *response) StartLine() string {
var buffer bytes.Buffer
Expand Down Expand Up @@ -247,7 +259,7 @@ func CopyResponse(res Response) Response {
hdrs = append(hdrs, header.Clone())
}

return NewResponse(
newRes := NewResponse(
res.MessageID(),
res.SipVersion(),
res.StatusCode(),
Expand All @@ -256,4 +268,7 @@ func CopyResponse(res Response) Response {
res.Body(),
res.Fields(),
)
newRes.SetPrevious(res.Previous())

return newRes
}

0 comments on commit 47c3459

Please sign in to comment.