Skip to content

Conversation

@murasakiakari
Copy link
Contributor

No description provided.

@murasakiakari
Copy link
Contributor Author

@chripo
here is the fix for the previous issue
Thank you for your reviewing

utils.go Outdated
case *strings.Reader:
contentLength = int64(reader.Len())
case io.Seeker:
pos, err := reader.Seek(0, io.SeekEnd)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is probably slightly incorrect as the reader could be at a position other than zero:

I think you need to:

  1. startPos, err = reader.Seek(0, io.SeekCurrent) to determine the current position
  2. totalLength, err = reader.Seek(0, io.SeekEnd) to determine the length entire stream
  3. reader.Seek(0, startPos) to restore the original starting position.
  4. return totalLength - startPos - this is how many bytes are remaining

utils.go Outdated
}

func GetContentLength(reader io.Reader) (int64, error) {
contentLength := int64(0)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

zero is a valid length for some transfers, this should probably return -1 to indicate the length is unknown or return additional bool

@murasakiakari
Copy link
Contributor Author

murasakiakari commented Dec 19, 2024

@jkowalski
Thank you for your idea, I have made the changes on getContentLength logic, feel free to take a review

@murasakiakari
Copy link
Contributor Author

The branch for bytes.Reader and strings.Reader are removed because they have implemented io.Seeker

@chripo
Copy link
Member

chripo commented Dec 19, 2024

thanks for the collaboration!
lgtm.
could you please add some tests?

@jkowalski
Copy link
Collaborator

I think you still need to modify c.put to ignore -1 content lengths (and not set the ContentLength field at all). You may also have to have special-case for zero-length buffer.

For the testing I would recommend trying the following case:

  • reader is bytes.Buffer
  • reader is bytes.NewReader()
  • another reader does not support io.Seeker
  • custom request that does support io.Seeker

For each implementation try different lengths:

Try the length of zero and make sure it is explicitly passed as Content-Length: 0 when length Is known and not set at all if length is unknown

Try some non-zero determinate and non-determinate lengths and make sure Content-Length is set accordingly.

bonus points if you can also try a very large stream of 1GB without a length to make sure it's never loaded into memory and streamed all the way to the server.

@murasakiakari
Copy link
Contributor Author

Thank for your idea, I will implement it in these days

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants