Skip to content

Add HTTPClientRequest #509

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Dec 2, 2021
Merged

Conversation

dnadoba
Copy link
Collaborator

@dnadoba dnadoba commented Dec 1, 2021

HTTPClientRequest and HTTPClientRequest.Body as described in the async/await proposal with some modifications:

  • .bytes(_:) and .stream(_:) from HTTPClientRequest.Body accept an additional optional length parameter to specify the length in advance. This will primarily be used to set a Content-Length header.
  • new overload for HTTPClientRequest.Body.bytes(..) that accepts a RandomAccessCollection which automatically uses the count property from the given collection as the body length.

Note that everything is still internal. This allows us to merge async/await components incrementally while still being able to release new versions from main.

@dnadoba dnadoba added the semver/none No version bump required. label Dec 1, 2021
@dnadoba dnadoba added 🔨 semver/patch No public API change. and removed semver/none No version bump required. labels Dec 1, 2021
Comment on lines 89 to 95
@available(*, deprecated, message: "no need to manually specify `length` because we automatically use `bytes.count` as the `length`")
static func bytes<Bytes>(
length: Int,
_ collection: Bytes
) -> Self where Bytes: RandomAccessCollection, Bytes.Element == UInt8 {
return .bytes(collection)
}
Copy link
Member

Choose a reason for hiding this comment

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

This is an interesting idea... It pushes people into using the right thing. However I wonder if it is a good idea to introduce new API, that we deprecate from the get go. @Lukasa wdyt?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'd be more inclined to consider marking the method @available(*, unavailable) and then not giving it an implementation beyond fatalError

Copy link
Collaborator Author

@dnadoba dnadoba Dec 2, 2021

Choose a reason for hiding this comment

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

I have tried @available(*, unavailable) but then the swift compiler will just choose the overload where Bytes: Sequence:

static func bytes<Bytes>(
length: Int? = nil,
_ bytes: Bytes
) -> Self where Bytes: Sequence, Bytes.Element == UInt8 {
self.init(.sequence(length: length) { allocator in
if let buffer = bytes.withContiguousStorageIfAvailable({ allocator.buffer(bytes: $0) }) {
// fastpath
return buffer
}
// potentially really slow path
return allocator.buffer(bytes: bytes)
})
}

Even adding @_disfavoredOverload to the Sequence overload doesn't help.

I think what we could also do is marking the method as deprecated and just adding a fatalError with a useful message. Then user will get a compiler warning and a runtime error. WDYT?

Copy link
Collaborator

@Lukasa Lukasa left a comment

Choose a reason for hiding this comment

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

I've left some notes in the diff. Are we adding tests in a separate PR?

self.init(.byteBuffer(byteBuffer))
}

static func bytes<Bytes>(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we make this method @inlinable?

})
}

static func bytes<Bytes>(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we make this method @inlinable?

/// `RandomAccessCollection` because it already provide a property `count` to get the length in O(**1**).
/// - Note: `length` is ignored in favour of `bytes.count`
@available(*, deprecated, message: "no need to manually specify `length` because we automatically use `bytes.count` as the `length`")
static func bytes<Bytes>(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we make this method @inlinable?

length: Int,
_ collection: Bytes
) -> Self where Bytes: RandomAccessCollection, Bytes.Element == UInt8 {
return .bytes(collection)
Copy link
Collaborator

Choose a reason for hiding this comment

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

If we're going to offer this overload, can we at least precondition that the length matches the count of the collection?

Comment on lines 89 to 95
@available(*, deprecated, message: "no need to manually specify `length` because we automatically use `bytes.count` as the `length`")
static func bytes<Bytes>(
length: Int,
_ collection: Bytes
) -> Self where Bytes: RandomAccessCollection, Bytes.Element == UInt8 {
return .bytes(collection)
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'd be more inclined to consider marking the method @available(*, unavailable) and then not giving it an implementation beyond fatalError

return .bytes(collection)
}

static func stream<SequenceOfBytes>(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we make this method @inlinable?

return body
}

static func stream<Bytes>(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we make this method @inlinable?

@dnadoba dnadoba requested review from fabianfett and Lukasa December 2, 2021 10:11
@dnadoba
Copy link
Collaborator Author

dnadoba commented Dec 2, 2021

Are we adding tests in a separate PR?

Yes

Copy link
Member

@fabianfett fabianfett left a comment

Choose a reason for hiding this comment

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

LGTM. Thanks!

@dnadoba dnadoba merged commit a956e7b into swift-server:main Dec 2, 2021
@dnadoba dnadoba deleted the dn-httpclientrequest branch December 7, 2021 12:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🔨 semver/patch No public API change.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants