[swift-server-dev] [HTTP] Value vs Reference Types

steve algernon salgernon at apple.com
Mon Nov 28 14:32:04 CST 2016


> On Nov 23, 2016, at 2:45 PM, Helge Heß via swift-server-dev <swift-server-dev at swift.org> wrote:
> 
> BTW: It was also mentioned that it may be highly desirable to use Foundation’s NSHTTPURLRequest/NSHTTPResponse.

A few notes in my head here: 

- The NSURL* APIs lack the ability to generate an NSHTTPURLRequest / NSHTTPURLResponse from bytes - the http parser is buried in a CFNetwork API.  (I'd like this to change and have an NSHTTPMessage -> NSHTTP(Request | Response)Message available.)

- NSURLResponse is the base class since the NSURL* APis are protocol agnostitic, so the NSURLSession APIs expose this - and everyone casts because in the end, they want an HTTP response.  We should avoid this from the get-go.

- The underlying dictionary of (case insensitive) key to value strings of these objects has a major design flaw in that it does not deal with multiple headers with the same key (Set-Cookie) It does this by arbitrarily combining value strings with some deliminter (I think its a ",") The correct API would return a value as an array even if it only contains 1 element.

- The req/resp objects do not preserve parsed header order, which may be desirable.  I'm considering adding:

	-(NSArray *)headerKeyOrder;
	-(NSArray *)headerValueArrayForKey:(NSString *)key;

- NSURLSession attempts to separate the NSURLRequest API from the existing -bodyData or -bodyStream methods.  When performing an upload the bytes of the body may be sent multiple times (in the case where we never receive a response, or the connection closes during an upload, or a proxy is involved) and long ago we had to add a delegate to request a new body stream.  The NSURLSession async convenience APIs work with data and stream objects external to the NSURLRequest, and in the stream case always defer to the delegate for an upload stream if data was not provided.  This separation of header and body is consistent with an NSURLResponse being distinct from the received data.  (Always requiring a stream be provided by a delegate guarantees that developers implement the method correctly so they continue to work in the edge cases that they can never actually test with!)

- NSHTTPURLRequest and NSHTTPURLResponse mutability is an issue that just makes for a messy API.  Making these value classes makes sense - the headers are never large enough to warrant even COW semantics for the internal dictionary.

- The client headers are not complete until they're about to be put on the wire; the URL of a request is added as a Host: very late and it is not possible to see the entire header before it is sent. (This is a limitation of the NSURLSession / NSURLConnection APIs as it necessarily involved a delegate callout and subsequent performance hit.). This may be true of a server API as well, where configuration options from the server are added immediately before the response is written.

--sma

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-server-dev/attachments/20161128/0c0d7b99/attachment.html>


More information about the swift-server-dev mailing list