Files
gortsplib/response.go
2020-05-08 23:36:05 +02:00

151 lines
4.6 KiB
Go

package gortsplib
import (
"bufio"
"fmt"
"strconv"
)
// StatusCode is a RTSP response status code.
type StatusCode int
const (
StatusContinue StatusCode = 100
StatusOK StatusCode = 200
StatusMovedPermanently StatusCode = 301
StatusFound StatusCode = 302
StatusSeeOther StatusCode = 303
StatusNotModified StatusCode = 304
StatusUseProxy StatusCode = 305
StatusBadRequest StatusCode = 400
StatusUnauthorized StatusCode = 401
StatusPaymentRequired StatusCode = 402
StatusForbidden StatusCode = 403
StatusNotFound StatusCode = 404
StatusMethodNotAllowed StatusCode = 405
StatusNotAcceptable StatusCode = 406
StatusProxyAuthRequired StatusCode = 407
StatusRequestTimeout StatusCode = 408
StatusGone StatusCode = 410
StatusPreconditionFailed StatusCode = 412
StatusRequestEntityTooLarge StatusCode = 413
StatusRequestURITooLong StatusCode = 414
StatusUnsupportedMediaType StatusCode = 415
StatusParameterNotUnderstood StatusCode = 451
StatusNotEnoughBandwidth StatusCode = 453
StatusSessionNotFound StatusCode = 454
StatusMethodNotValidInThisState StatusCode = 455
StatusHeaderFieldNotValidForResource StatusCode = 456
StatusInvalidRange StatusCode = 457
StatusParameterIsReadOnly StatusCode = 458
StatusAggregateOperationNotAllowed StatusCode = 459
StatusOnlyAggregateOperationAllowed StatusCode = 460
StatusUnsupportedTransport StatusCode = 461
StatusDestinationUnreachable StatusCode = 462
StatusDestinationProhibited StatusCode = 463
StatusDataTransportNotReadyYet StatusCode = 464
StatusNotificationReasonUnknown StatusCode = 465
StatusKeyManagementError StatusCode = 466
StatusConnectionAuthorizationRequired StatusCode = 470
StatusConnectionCredentialsNotAccepted StatusCode = 471
StatusFailureToEstablishSecureConnection StatusCode = 472
StatusInternalServerError StatusCode = 500
StatusNotImplemented StatusCode = 501
StatusBadGateway StatusCode = 502
StatusServiceUnavailable StatusCode = 503
StatusGatewayTimeout StatusCode = 504
StatusRTSPVersionNotSupported StatusCode = 505
StatusOptionNotSupported StatusCode = 551
StatusProxyUnavailable StatusCode = 553
)
// Response is a RTSP response.
type Response struct {
StatusCode StatusCode
StatusMessage string
Header Header
Content []byte
}
func readResponse(br *bufio.Reader) (*Response, error) {
res := &Response{}
byts, err := readBytesLimited(br, ' ', 255)
if err != nil {
return nil, err
}
proto := string(byts[:len(byts)-1])
if proto != _RTSP_PROTO {
return nil, fmt.Errorf("expected '%s', got '%s'", _RTSP_PROTO, proto)
}
byts, err = readBytesLimited(br, ' ', 4)
if err != nil {
return nil, err
}
statusCodeStr := string(byts[:len(byts)-1])
statusCode64, err := strconv.ParseInt(statusCodeStr, 10, 32)
if err != nil {
return nil, fmt.Errorf("unable to parse status code")
}
res.StatusCode = StatusCode(statusCode64)
byts, err = readBytesLimited(br, '\r', 255)
if err != nil {
return nil, err
}
res.StatusMessage = string(byts[:len(byts)-1])
if len(res.StatusMessage) == 0 {
return nil, fmt.Errorf("empty status")
}
err = readByteEqual(br, '\n')
if err != nil {
return nil, err
}
res.Header, err = readHeader(br)
if err != nil {
return nil, err
}
res.Content, err = readContent(br, res.Header)
if err != nil {
return nil, err
}
return res, nil
}
func (res *Response) write(bw *bufio.Writer) error {
if res.StatusMessage == "" {
if status, ok := statusMessages[res.StatusCode]; ok {
res.StatusMessage = status
}
}
_, err := bw.Write([]byte(_RTSP_PROTO + " " + strconv.FormatInt(int64(res.StatusCode), 10) + " " + res.StatusMessage + "\r\n"))
if err != nil {
return err
}
if len(res.Content) != 0 {
res.Header["Content-Length"] = []string{strconv.FormatInt(int64(len(res.Content)), 10)}
}
err = res.Header.write(bw)
if err != nil {
return err
}
err = writeContent(bw, res.Content)
if err != nil {
return err
}
return bw.Flush()
}