client: fix some footguns in compileRequest
Some checks are pending
Go / Lint (latest) (push) Waiting to run
Go / Build (old, libolm) (push) Waiting to run
Go / Build (latest, libolm) (push) Waiting to run
Go / Build (old, goolm) (push) Waiting to run
Go / Build (latest, goolm) (push) Waiting to run

* add warning log if RequestBody is used without length instead of
  silently discarding the body
* fix wrapping RequestBody in nopcloser
* always set content length
This commit is contained in:
Tulir Asokan 2025-09-22 16:27:01 +03:00
commit a8b5fa9156

View file

@ -418,8 +418,18 @@ var requestID int32
var logSensitiveContent = os.Getenv("MAUTRIX_LOG_SENSITIVE_CONTENT") == "yes"
func (params *FullRequest) compileRequest(ctx context.Context) (*http.Request, error) {
reqID := atomic.AddInt32(&requestID, 1)
logger := zerolog.Ctx(ctx)
if logger.GetLevel() == zerolog.Disabled || logger == zerolog.DefaultContextLogger {
logger = params.Logger
}
ctx = logger.With().
Int32("req_id", reqID).
Logger().WithContext(ctx)
var logBody any
reqBody := params.RequestBody
var reqBody io.Reader
var reqLen int64
if params.RequestJSON != nil {
jsonStr, err := json.Marshal(params.RequestJSON)
if err != nil {
@ -434,12 +444,22 @@ func (params *FullRequest) compileRequest(ctx context.Context) (*http.Request, e
logBody = params.RequestJSON
}
reqBody = bytes.NewReader(jsonStr)
reqLen = int64(len(jsonStr))
} else if params.RequestBytes != nil {
logBody = fmt.Sprintf("<%d bytes>", len(params.RequestBytes))
reqBody = bytes.NewReader(params.RequestBytes)
params.RequestLength = int64(len(params.RequestBytes))
} else if params.RequestLength > 0 && params.RequestBody != nil {
logBody = fmt.Sprintf("<%d bytes>", params.RequestLength)
reqLen = int64(len(params.RequestBytes))
} else if params.RequestBody != nil {
logBody = "<unknown stream of bytes>"
reqLen = -1
if params.RequestLength > 0 {
logBody = fmt.Sprintf("<%d bytes>", params.RequestLength)
reqLen = params.RequestLength
} else if params.RequestLength == 0 {
zerolog.Ctx(ctx).Warn().
Msg("RequestBody passed without specifying request length")
}
reqBody = params.RequestBody
if rsc, ok := params.RequestBody.(io.ReadSeekCloser); ok {
// Prevent HTTP from closing the request body, it might be needed for retries
reqBody = nopCloseSeeker{rsc}
@ -448,15 +468,8 @@ func (params *FullRequest) compileRequest(ctx context.Context) (*http.Request, e
params.RequestJSON = struct{}{}
logBody = params.RequestJSON
reqBody = bytes.NewReader([]byte("{}"))
reqLen = 2
}
reqID := atomic.AddInt32(&requestID, 1)
logger := zerolog.Ctx(ctx)
if logger.GetLevel() == zerolog.Disabled || logger == zerolog.DefaultContextLogger {
logger = params.Logger
}
ctx = logger.With().
Int32("req_id", reqID).
Logger().WithContext(ctx)
ctx = context.WithValue(ctx, LogBodyContextKey, logBody)
ctx = context.WithValue(ctx, LogRequestIDContextKey, int(reqID))
req, err := http.NewRequestWithContext(ctx, params.Method, params.URL, reqBody)
@ -472,9 +485,7 @@ func (params *FullRequest) compileRequest(ctx context.Context) (*http.Request, e
if params.RequestJSON != nil {
req.Header.Set("Content-Type", "application/json")
}
if params.RequestLength > 0 && params.RequestBody != nil {
req.ContentLength = params.RequestLength
}
req.ContentLength = reqLen
return req, nil
}