Skip to content

Commit

Permalink
Set content-length header when available
Browse files Browse the repository at this point in the history
When uploading raw data in the request data a file on disk,
the file size is known and can be added as a content length header.

Extended the executor to retrieve the file size and add it as a
content-length header when available.
  • Loading branch information
thschmitt committed Oct 30, 2024
1 parent 44763df commit fc542c6
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 11 deletions.
34 changes: 23 additions & 11 deletions executor/http_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ func (e HttpExecutor) progressReader(text string, completedText string, reader i
}

func (e HttpExecutor) writeMultipartBody(bodyWriter *io.PipeWriter, parameters []ExecutionParameter, errorChan chan error) (string, int64) {
contentLength := e.calculateMultipartSize(parameters)
multipartSize := e.calculateMultipartSize(parameters)
formWriter := multipart.NewWriter(bodyWriter)
go func() {
defer bodyWriter.Close()
Expand All @@ -186,7 +186,7 @@ func (e HttpExecutor) writeMultipartBody(bodyWriter *io.PipeWriter, parameters [
return
}
}()
return formWriter.FormDataContentType(), contentLength
return formWriter.FormDataContentType(), multipartSize
}

func (e HttpExecutor) writeInputBody(bodyWriter *io.PipeWriter, input utils.Stream, errorChan chan error) {
Expand Down Expand Up @@ -230,30 +230,39 @@ func (e HttpExecutor) writeJsonBody(bodyWriter *io.PipeWriter, parameters []Exec
}()
}

func (e HttpExecutor) writeBody(context ExecutionContext, errorChan chan error) (io.Reader, string, int64) {
func (e HttpExecutor) writeBody(context ExecutionContext, errorChan chan error) (io.Reader, string, int64, int64) {
if context.Input != nil {
reader, writer := io.Pipe()
e.writeInputBody(writer, context.Input, errorChan)
return reader, context.ContentType, -1
contentLength, _ := context.Input.Size()
return reader, context.ContentType, contentLength, contentLength
}
formParameters := context.Parameters.Form()
if len(formParameters) > 0 {
reader, writer := io.Pipe()
contentType, contentLength := e.writeMultipartBody(writer, formParameters, errorChan)
return reader, contentType, contentLength
contentType, multipartSize := e.writeMultipartBody(writer, formParameters, errorChan)
return reader, contentType, -1, multipartSize
}
bodyParameters := context.Parameters.Body()
if len(bodyParameters) > 0 && context.ContentType == "application/x-www-form-urlencoded" {
reader, writer := io.Pipe()
e.writeUrlEncodedBody(writer, bodyParameters, errorChan)
return reader, context.ContentType, -1
return reader, context.ContentType, -1, -1
}
if len(bodyParameters) > 0 {
reader, writer := io.Pipe()
e.writeJsonBody(writer, bodyParameters, errorChan)
return reader, context.ContentType, -1
return reader, context.ContentType, -1, -1
}
return bytes.NewReader([]byte{}), context.ContentType, -1
return bytes.NewReader([]byte{}), context.ContentType, -1, -1
}

func (e HttpExecutor) contentLength(context ExecutionContext) int64 {

Check failure on line 260 in executor/http_executor.go

View workflow job for this annotation

GitHub Actions / build

func `HttpExecutor.contentLength` is unused (unused)
if context.Input == nil {
return -1
}
contentLength, _ := context.Input.Size()
return contentLength
}

func (e HttpExecutor) send(client *http.Client, request *http.Request, errorChan chan error) (*http.Response, error) {
Expand Down Expand Up @@ -306,9 +315,9 @@ func (e HttpExecutor) call(context ExecutionContext, writer output.OutputWriter,
return err
}
requestError := make(chan error)
bodyReader, contentType, contentLength := e.writeBody(context, requestError)
bodyReader, contentType, contentLength, size := e.writeBody(context, requestError)
uploadBar := utils.NewProgressBar(logger)
uploadReader := e.progressReader("uploading...", "completing ", bodyReader, contentLength, uploadBar)
uploadReader := e.progressReader("uploading...", "completing ", bodyReader, size, uploadBar)
defer uploadBar.Remove()
request, err := http.NewRequest(context.Method, uri.String(), uploadReader)
if err != nil {
Expand All @@ -317,6 +326,9 @@ func (e HttpExecutor) call(context ExecutionContext, writer output.OutputWriter,
if contentType != "" {
request.Header.Add("Content-Type", contentType)
}
if contentLength != -1 {
request.ContentLength = contentLength
}
e.addHeaders(request, context.Parameters.Header())
auth, err := e.executeAuthenticators(context.AuthConfig, context.IdentityUri, context.Debug, context.Insecure, request)
if err != nil {
Expand Down
4 changes: 4 additions & 0 deletions test/execution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1260,6 +1260,10 @@ paths:
if contentType != "application/octet-stream" {
t.Errorf("Content-Type is not application/octet-stream, got: %v", contentType)
}
contentLength := result.RequestHeader["content-length"]
if contentLength != "11" {
t.Errorf("Content-Length is not 11, got: %v", contentLength)
}
if result.RequestBody != "hello-world" {
t.Errorf("Request body is not as expected, got: %v", result.RequestBody)
}
Expand Down

0 comments on commit fc542c6

Please sign in to comment.