Convert HTTPVersion to struct


(Chris Bailey) #1

Based on our discussed approach of reviewing each of the types in the HTTP
project, I've raised the following PR to convert HTTPVersion from (Int,
Int) to a struct based on Paulo's proposal:
        https://github.com/swift-server/http/pull/6

I've not yet added Hashable, Equatable and CustomStringConvertible
protocols - we can do that if we're happy with the change.

Chris
Unless stated otherwise above:
IBM United Kingdom Limited - Registered in England and Wales with number
741598.
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU


#2

I’m thinking that maybe It will be better to make both major/minor Int16/UInt16 instead, since the value we get from the http parser is an unsigned short, and making it a short help write the hash as the following without worrying about overflow due to bad programming from user.

var hashValue: Int { return Int(major) << 16 &+ Int(minor) }

may be a bit over engineering. Just a thought

Michael.

···

On Jun 13, 2017, at 1:44 PM, Chris Bailey via swift-server-dev <swift-server-dev@swift.org> wrote:

Based on our discussed approach of reviewing each of the types in the HTTP project, I've raised the following PR to convert HTTPVersion from (Int, Int) to a struct based on Paulo's proposal:
        https://github.com/swift-server/http/pull/6

I've not yet added Hashable, Equatable and CustomStringConvertible protocols - we can do that if we're happy with the change.

Chris
Unless stated otherwise above:
IBM United Kingdom Limited - Registered in England and Wales with number 741598.
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU
_______________________________________________
swift-server-dev mailing list
swift-server-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-server-dev


(Rien) #3

The choices seem to be:

1) String
2) Enum
3) Tuple
4) Struct
5) Class

1) String
Advantage: it is in fact an utf-8 string. No conversions needed.
Disadvantage: It is mostly thought of as a number, thus the abstraction does not match the type, very minor performance penalty in comparing. Illogical to add HTTP-version extensions to the type.

2) Enum
Advantage: shortest possible representation (?), fastest compare (?), easy to use.
Disadvantage: Needs converting to and from.

3) Tuple
Advantage: Matches fairly wel with the abstraction.
Disadvantage: Fairly complex conversion, adding members/operations is non-intuitive, not very easy to use.

4) Struct
Advantage: Matches fairly wel with the abstraction.
Disadvantage: Fairly complex conversion. Not very easy to use without adding members/operations.

5) This was for completeness only, I would be very surprised if anybody would actually propose this… :wink:

To me that leaves option 2 and 4.
Advantage of 2 over 4:

- I find the abstraction a better match. The difference between 1, 1.1 and 2 is such that it makes little sense to be to differentiate based on the numerical values. It makes much more sense to differentiate based on the “whole number”. AFAIIC they could just as easily have named the versions A, B, C etc. The numbers do not convey any information as such.
- Switch is easier and more intuitive to use.
- Enums can have additional properties and operations similar to struct.

Advantage of 4 over 2:
I don’t see any.

Regards,
Rien

Site: http://balancingrock.nl
Blog: http://swiftrien.blogspot.com
Github: http://github.com/Balancingrock
Project: http://swiftfire.nl - An HTTP(S) web server framework in Swift

···

On 13 Jun 2017, at 22:44, Chris Bailey via swift-server-dev <swift-server-dev@swift.org> wrote:

Based on our discussed approach of reviewing each of the types in the HTTP project, I've raised the following PR to convert HTTPVersion from (Int, Int) to a struct based on Paulo's proposal:
        https://github.com/swift-server/http/pull/6

I've not yet added Hashable, Equatable and CustomStringConvertible protocols - we can do that if we're happy with the change.

Chris
Unless stated otherwise above:
IBM United Kingdom Limited - Registered in England and Wales with number 741598.
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU
_______________________________________________
swift-server-dev mailing list
swift-server-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-server-dev


#4

I think currently the http version is come from the http_parser which has parsed the version string to number anyway. hence the performance should be similar.

I do see some advantage to use struct tho, for example comparing only major version.

Michael

···

On Jun 13, 2017, at 11:41 PM, Rien via swift-server-dev <swift-server-dev@swift.org> wrote:

The choices seem to be:

1) String
2) Enum
3) Tuple
4) Struct
5) Class

1) String
Advantage: it is in fact an utf-8 string. No conversions needed.
Disadvantage: It is mostly thought of as a number, thus the abstraction does not match the type, very minor performance penalty in comparing. Illogical to add HTTP-version extensions to the type.

2) Enum
Advantage: shortest possible representation (?), fastest compare (?), easy to use.
Disadvantage: Needs converting to and from.

3) Tuple
Advantage: Matches fairly wel with the abstraction.
Disadvantage: Fairly complex conversion, adding members/operations is non-intuitive, not very easy to use.

4) Struct
Advantage: Matches fairly wel with the abstraction.
Disadvantage: Fairly complex conversion. Not very easy to use without adding members/operations.

5) This was for completeness only, I would be very surprised if anybody would actually propose this… :wink:

To me that leaves option 2 and 4.
Advantage of 2 over 4:

- I find the abstraction a better match. The difference between 1, 1.1 and 2 is such that it makes little sense to be to differentiate based on the numerical values. It makes much more sense to differentiate based on the “whole number”. AFAIIC they could just as easily have named the versions A, B, C etc. The numbers do not convey any information as such.
- Switch is easier and more intuitive to use.
- Enums can have additional properties and operations similar to struct.

Advantage of 4 over 2:
I don’t see any.

Regards,
Rien

Site: http://balancingrock.nl
Blog: http://swiftrien.blogspot.com
Github: http://github.com/Balancingrock
Project: http://swiftfire.nl - An HTTP(S) web server framework in Swift

On 13 Jun 2017, at 22:44, Chris Bailey via swift-server-dev <swift-server-dev@swift.org> wrote:

Based on our discussed approach of reviewing each of the types in the HTTP project, I've raised the following PR to convert HTTPVersion from (Int, Int) to a struct based on Paulo's proposal:
      https://github.com/swift-server/http/pull/6

I've not yet added Hashable, Equatable and CustomStringConvertible protocols - we can do that if we're happy with the change.

Chris
Unless stated otherwise above:
IBM United Kingdom Limited - Registered in England and Wales with number 741598.
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU
_______________________________________________
swift-server-dev mailing list
swift-server-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-server-dev

_______________________________________________
swift-server-dev mailing list
swift-server-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-server-dev


(Tanner Nelson) #5

I approved the changes in Chris's PR swift-server/http#6, I think moving
away from typealias wherever possible is a great idea. IMO typealiases
really only make sense for protocol composition.

On an unrelated note, I'm considering submitting a PR that would move the
HTTP models into a module named `HTTP`. This would name space things like
`HTTPVersion` to `HTTP.Version` (usable as just `Version` when no
ambiguities exist). I think this would make the package more concise and
feel less like Obj-C.
Any arguments against name spacing?

···

On Wed, Jun 14, 2017 at 8:13 AM Michael Chiu via swift-server-dev < swift-server-dev@swift.org> wrote:

I think currently the http version is come from the http_parser which has
parsed the version string to number anyway. hence the performance should be
similar.

I do see some advantage to use struct tho, for example comparing only
major version.

Michael

> On Jun 13, 2017, at 11:41 PM, Rien via swift-server-dev < > swift-server-dev@swift.org> wrote:
>
> The choices seem to be:
>
> 1) String
> 2) Enum
> 3) Tuple
> 4) Struct
> 5) Class
>
> 1) String
> Advantage: it is in fact an utf-8 string. No conversions needed.
> Disadvantage: It is mostly thought of as a number, thus the abstraction
does not match the type, very minor performance penalty in comparing.
Illogical to add HTTP-version extensions to the type.
>
> 2) Enum
> Advantage: shortest possible representation (?), fastest compare (?),
easy to use.
> Disadvantage: Needs converting to and from.
>
> 3) Tuple
> Advantage: Matches fairly wel with the abstraction.
> Disadvantage: Fairly complex conversion, adding members/operations is
non-intuitive, not very easy to use.
>
> 4) Struct
> Advantage: Matches fairly wel with the abstraction.
> Disadvantage: Fairly complex conversion. Not very easy to use without
adding members/operations.
>
> 5) This was for completeness only, I would be very surprised if anybody
would actually propose this… :wink:
>
>
> To me that leaves option 2 and 4.
> Advantage of 2 over 4:
>
> - I find the abstraction a better match. The difference between 1, 1.1
and 2 is such that it makes little sense to be to differentiate based on
the numerical values. It makes much more sense to differentiate based on
the “whole number”. AFAIIC they could just as easily have named the
versions A, B, C etc. The numbers do not convey any information as such.
> - Switch is easier and more intuitive to use.
> - Enums can have additional properties and operations similar to struct.
>
> Advantage of 4 over 2:
> I don’t see any.
>
> Regards,
> Rien
>
> Site: http://balancingrock.nl
> Blog: http://swiftrien.blogspot.com
> Github: http://github.com/Balancingrock
> Project: http://swiftfire.nl - An HTTP(S) web server framework in Swift
>
>
>
>> On 13 Jun 2017, at 22:44, Chris Bailey via swift-server-dev < > swift-server-dev@swift.org> wrote:
>>
>> Based on our discussed approach of reviewing each of the types in the
HTTP project, I've raised the following PR to convert HTTPVersion from
(Int, Int) to a struct based on Paulo's proposal:
>> https://github.com/swift-server/http/pull/6
>>
>> I've not yet added Hashable, Equatable and CustomStringConvertible
protocols - we can do that if we're happy with the change.
>>
>> Chris
>> Unless stated otherwise above:
>> IBM United Kingdom Limited - Registered in England and Wales with
number 741598.
>> Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6
3AU
>> _______________________________________________
>> swift-server-dev mailing list
>> swift-server-dev@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-server-dev
>
> _______________________________________________
> swift-server-dev mailing list
> swift-server-dev@swift.org
> https://lists.swift.org/mailman/listinfo/swift-server-dev

_______________________________________________
swift-server-dev mailing list
swift-server-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-server-dev


(Chris Bailey) #6

One factor is whether you consider the version to be discrete values or a
structured format for data - I'd argue that we have a structured format
due to the expectation that future versions of the HTTP spec could arrive.

Adding conformance to Hashable/Equatable and CustomStringConvertible
provides the operations, and whilst it may look strange we could also
provide convenience constants if it makes sense, ie:
    public static let http1_0 = HTTPVersion(major: 1, minor: 0)
    public static let http1_1 = HTTPVersion(major: 1, minor: 1)
    public static let http2_0 = HTTPVersion(major: 2, minor: 0)

Having said that, there is slight additional storage overhead for structs
vs. enums, as a slight additional compare cost.

Chris

To: Rien <Rien@Balancingrock.nl>
Cc: Chris Bailey <BAILEYC@uk.ibm.com>, swift-server-dev@swift.org
Date: 14/06/2017 08:12
Subject: Re: [swift-server-dev] Convert HTTPVersion to struct

I think currently the http version is come from the http_parser
which has parsed the version string to number anyway. hence the
performance should be similar.

I do see some advantage to use struct tho, for example comparing
only major version.

Michael

>
> The choices seem to be:
>
> 1) String
> 2) Enum
> 3) Tuple
> 4) Struct
> 5) Class
>
> 1) String
> Advantage: it is in fact an utf-8 string. No conversions needed.
> Disadvantage: It is mostly thought of as a number, thus the
abstraction does not match the type, very minor performance penalty
in comparing. Illogical to add HTTP-version extensions to the type.
>
> 2) Enum
> Advantage: shortest possible representation (?), fastest compare
(?), easy to use.
> Disadvantage: Needs converting to and from.
>
> 3) Tuple
> Advantage: Matches fairly wel with the abstraction.
> Disadvantage: Fairly complex conversion, adding members/operations
is non-intuitive, not very easy to use.
>
> 4) Struct
> Advantage: Matches fairly wel with the abstraction.
> Disadvantage: Fairly complex conversion. Not very easy to use
without adding members/operations.
>
> 5) This was for completeness only, I would be very surprised if
anybody would actually propose this… :wink:
>
>
> To me that leaves option 2 and 4.
> Advantage of 2 over 4:
>
> - I find the abstraction a better match. The difference between 1,
1.1 and 2 is such that it makes little sense to be to differentiate
based on the numerical values. It makes much more sense to
differentiate based on the “whole number”. AFAIIC they could just as
easily have named the versions A, B, C etc. The numbers do not
convey any information as such.
> - Switch is easier and more intuitive to use.
> - Enums can have additional properties and operations similar to

struct.

>
> Advantage of 4 over 2:
> I don’t see any.
>
> Regards,
> Rien
>
> Site: http://balancingrock.nl
> Blog: http://swiftrien.blogspot.com
> Github: http://github.com/Balancingrock
> Project: http://swiftfire.nl - An HTTP(S) web server framework in

Swift

>
>
>
>>
>> Based on our discussed approach of reviewing each of the types in
the HTTP project, I've raised the following PR to convert
HTTPVersion from (Int, Int) to a struct based on Paulo's proposal:
>> https://github.com/swift-server/http/pull/6
>>
>> I've not yet added Hashable, Equatable and
CustomStringConvertible protocols - we can do that if we're happy
with the change.
>>
>> Chris
>> Unless stated otherwise above:
>> IBM United Kingdom Limited - Registered in England and Wales with
number 741598.
>> Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire

PO6 3AU

>> _______________________________________________
>> swift-server-dev mailing list
>> swift-server-dev@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-server-dev
>
> _______________________________________________
> swift-server-dev mailing list
> swift-server-dev@swift.org
> https://lists.swift.org/mailman/listinfo/swift-server-dev

Unless stated otherwise above:
IBM United Kingdom Limited - Registered in England and Wales with number
741598.
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU

···

Michael Chiu <hatsuneyuji@icloud.com> wrote on 14/06/2017 08:12:35: > From: Michael Chiu <hatsuneyuji@icloud.com>

> On Jun 13, 2017, at 11:41 PM, Rien via swift-server-dev <swift- > server-dev@swift.org> wrote:
>> On 13 Jun 2017, at 22:44, Chris Bailey via swift-server-dev > <swift-server-dev@swift.org> wrote:


(Alex Blewitt) #7

The problem with using any fixed-sized, closed set enum is that you are not going to capture every possible status code in the implementation. Sure, you might capture them as they exist /now/ but they may be added to in the future. In addition, you can't really group them into ranges (e.g. 1xx, 2xx, 3xx, 4xx, 5xx) which have definite meanings even if the actual status code is not known at the time the program was written.

Having worked with HTTP libraries in the early days of Java, and seeing the HTTP/1.0 -> HTTP/1.1 and then subsequent RFCs adding further codes (e.g. https://tools.ietf.org/html/rfc6585) expecting the set of codes to be a closed set doesn't work. You might be able to get away with an enum-of-five (corresponding to the 1xx, 2xx, 3xx, 4xx, 5xx) but that doesn't add much and you'd still need to have the numerical values stored anyway.

Alex

···

On 14 Jun 2017, at 07:41, Rien via swift-server-dev <swift-server-dev@swift.org> wrote:

The choices seem to be:

1) String
2) Enum
3) Tuple
4) Struct
5) Class

To me that leaves option 2 and 4.
Advantage of 2 over 4:

- I find the abstraction a better match. The difference between 1, 1.1 and 2 is such that it makes little sense to be to differentiate based on the numerical values. It makes much more sense to differentiate based on the “whole number”. AFAIIC they could just as easily have named the versions A, B, C etc. The numbers do not convey any information as such.
- Switch is easier and more intuitive to use.
- Enums can have additional properties and operations similar to struct.

Advantage of 4 over 2:
I don’t see any.


(Rien) #8

I think currently the http version is come from the http_parser which has parsed the version string to number anyway. hence the performance should be similar.

That is likely, but imo the HTTP API should be judged on its own merits.

I do see some advantage to use struct tho, for example comparing only major version.

That is where I don’t see a real world advantage. Theoretically you are correct, but in a real world example?, do you have an example where this is indeed useful?
Given the limited range of useful versions numbers (only 3!) I just don’t see it.

I realize that this reaches into preferred programming techniques, but I like to use capability test on the type.
I.e. I would write

enum HttpVersion { case http1_0, http1_1, http2_0 }

extension HttpVersion {
  var isMultipleDomainCapable: Bool {
    switch self {
    case .http1_0: return false
    case .http1_1: return true
    case .http2_0: return true
    }
  }
}

if version.isMultipleDomainCapable { }

instead of:

struct HttpVersion {
  let major: Int
  let minor: Int

  static func == ...
}

if (version == HttpVersion(1, 1) || (version == HttpVersion(2, 0)) {
  // supports multiple domains
}

Regards,
Rien

Site: http://balancingrock.nl
Blog: http://swiftrien.blogspot.com
Github: http://github.com/Balancingrock
Project: http://swiftfire.nl - An HTTP(S) web server framework in Swift

···

On 14 Jun 2017, at 09:12, Michael Chiu <hatsuneyuji@icloud.com> wrote:

Michael

On Jun 13, 2017, at 11:41 PM, Rien via swift-server-dev <swift-server-dev@swift.org> wrote:

The choices seem to be:

1) String
2) Enum
3) Tuple
4) Struct
5) Class

1) String
Advantage: it is in fact an utf-8 string. No conversions needed.
Disadvantage: It is mostly thought of as a number, thus the abstraction does not match the type, very minor performance penalty in comparing. Illogical to add HTTP-version extensions to the type.

2) Enum
Advantage: shortest possible representation (?), fastest compare (?), easy to use.
Disadvantage: Needs converting to and from.

3) Tuple
Advantage: Matches fairly wel with the abstraction.
Disadvantage: Fairly complex conversion, adding members/operations is non-intuitive, not very easy to use.

4) Struct
Advantage: Matches fairly wel with the abstraction.
Disadvantage: Fairly complex conversion. Not very easy to use without adding members/operations.

5) This was for completeness only, I would be very surprised if anybody would actually propose this… :wink:

To me that leaves option 2 and 4.
Advantage of 2 over 4:

- I find the abstraction a better match. The difference between 1, 1.1 and 2 is such that it makes little sense to be to differentiate based on the numerical values. It makes much more sense to differentiate based on the “whole number”. AFAIIC they could just as easily have named the versions A, B, C etc. The numbers do not convey any information as such.
- Switch is easier and more intuitive to use.
- Enums can have additional properties and operations similar to struct.

Advantage of 4 over 2:
I don’t see any.

Regards,
Rien

Site: http://balancingrock.nl
Blog: http://swiftrien.blogspot.com
Github: http://github.com/Balancingrock
Project: http://swiftfire.nl - An HTTP(S) web server framework in Swift

On 13 Jun 2017, at 22:44, Chris Bailey via swift-server-dev <swift-server-dev@swift.org> wrote:

Based on our discussed approach of reviewing each of the types in the HTTP project, I've raised the following PR to convert HTTPVersion from (Int, Int) to a struct based on Paulo's proposal:
     https://github.com/swift-server/http/pull/6

I've not yet added Hashable, Equatable and CustomStringConvertible protocols - we can do that if we're happy with the change.

Chris
Unless stated otherwise above:
IBM United Kingdom Limited - Registered in England and Wales with number 741598.
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU
_______________________________________________
swift-server-dev mailing list
swift-server-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-server-dev

_______________________________________________
swift-server-dev mailing list
swift-server-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-server-dev


#9

This automatically include all future version without modify any existing code.

extension HTTPVersion {
    public func > (lhs: HTTPVersion, rhs: HTTPVersion) -> Bool
    {
         return lhs.major > rhs.major ? true : (lhs.minor > rhs.minor)
    }

    public static var minimumVersionSupportsMulitpleDomain: HTTPVersion {
        return HTTPVersion(1,1)
    }

    var isMulitpleDomainCapable: Bool {
        return self > HTTPVersion.minimumVersionSupportsMulitpleDomain
    }
}

Cheers,
Michael

···

On Jun 14, 2017, at 2:30 AM, Rien <Rien@Balancingrock.nl> wrote:

On 14 Jun 2017, at 09:12, Michael Chiu <hatsuneyuji@icloud.com <mailto:hatsuneyuji@icloud.com>> wrote:

I think currently the http version is come from the http_parser which has parsed the version string to number anyway. hence the performance should be similar.

That is likely, but imo the HTTP API should be judged on its own merits.

I do see some advantage to use struct tho, for example comparing only major version.

That is where I don’t see a real world advantage. Theoretically you are correct, but in a real world example?, do you have an example where this is indeed useful?
Given the limited range of useful versions numbers (only 3!) I just don’t see it.

I realize that this reaches into preferred programming techniques, but I like to use capability test on the type.
I.e. I would write

enum HttpVersion { case http1_0, http1_1, http2_0 }

extension HttpVersion {
  var isMultipleDomainCapable: Bool {
    switch self {
    case .http1_0: return false
    case .http1_1: return true
    case .http2_0: return true
    }
  }
}

if version.isMultipleDomainCapable { }

instead of:

struct HttpVersion {
  let major: Int
  let minor: Int

  static func == ...
}

if (version == HttpVersion(1, 1) || (version == HttpVersion(2, 0)) {
  // supports multiple domains
}

Regards,
Rien

Site: http://balancingrock.nl <http://balancingrock.nl/>
Blog: http://swiftrien.blogspot.com <http://swiftrien.blogspot.com/>
Github: http://github.com/Balancingrock
Project: http://swiftfire.nl <http://swiftfire.nl/> - An HTTP(S) web server framework in Swift

Michael

On Jun 13, 2017, at 11:41 PM, Rien via swift-server-dev <swift-server-dev@swift.org <mailto:swift-server-dev@swift.org>> wrote:

The choices seem to be:

1) String
2) Enum
3) Tuple
4) Struct
5) Class

1) String
Advantage: it is in fact an utf-8 string. No conversions needed.
Disadvantage: It is mostly thought of as a number, thus the abstraction does not match the type, very minor performance penalty in comparing. Illogical to add HTTP-version extensions to the type.

2) Enum
Advantage: shortest possible representation (?), fastest compare (?), easy to use.
Disadvantage: Needs converting to and from.

3) Tuple
Advantage: Matches fairly wel with the abstraction.
Disadvantage: Fairly complex conversion, adding members/operations is non-intuitive, not very easy to use.

4) Struct
Advantage: Matches fairly wel with the abstraction.
Disadvantage: Fairly complex conversion. Not very easy to use without adding members/operations.

5) This was for completeness only, I would be very surprised if anybody would actually propose this… :wink:

To me that leaves option 2 and 4.
Advantage of 2 over 4:

- I find the abstraction a better match. The difference between 1, 1.1 and 2 is such that it makes little sense to be to differentiate based on the numerical values. It makes much more sense to differentiate based on the “whole number”. AFAIIC they could just as easily have named the versions A, B, C etc. The numbers do not convey any information as such.
- Switch is easier and more intuitive to use.
- Enums can have additional properties and operations similar to struct.

Advantage of 4 over 2:
I don’t see any.

Regards,
Rien

Site: http://balancingrock.nl <http://balancingrock.nl/>
Blog: http://swiftrien.blogspot.com <http://swiftrien.blogspot.com/>
Github: http://github.com/Balancingrock
Project: http://swiftfire.nl <http://swiftfire.nl/> - An HTTP(S) web server framework in Swift

On 13 Jun 2017, at 22:44, Chris Bailey via swift-server-dev <swift-server-dev@swift.org <mailto:swift-server-dev@swift.org>> wrote:

Based on our discussed approach of reviewing each of the types in the HTTP project, I've raised the following PR to convert HTTPVersion from (Int, Int) to a struct based on Paulo's proposal:
     https://github.com/swift-server/http/pull/6

I've not yet added Hashable, Equatable and CustomStringConvertible protocols - we can do that if we're happy with the change.

Chris
Unless stated otherwise above:
IBM United Kingdom Limited - Registered in England and Wales with number 741598.
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU
_______________________________________________
swift-server-dev mailing list
swift-server-dev@swift.org <mailto:swift-server-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-server-dev

_______________________________________________
swift-server-dev mailing list
swift-server-dev@swift.org <mailto:swift-server-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-server-dev


(Rien) #10

One factor is whether you consider the version to be discrete values or a structured format for data - I'd argue that we have a structured format due to the expectation that future versions of the HTTP spec could arrive.

But do you want your code littered with numerical tests or conceptual tests?
Suppose a new version of HTTP does arrive, do you really want to manually walk through the code and find all tests on the numerical values?
Or would it be easier to use switch statements on an enum and have all missing cases pointed out to you?

Regards,
Rien

Site: http://balancingrock.nl
Blog: http://swiftrien.blogspot.com
Github: http://github.com/Balancingrock
Project: http://swiftfire.nl - An HTTP(S) web server framework in Swift

···

On 14 Jun 2017, at 11:14, Chris Bailey <BAILEYC@uk.ibm.com> wrote:

Adding conformance to Hashable/Equatable and CustomStringConvertible provides the operations, and whilst it may look strange we could also provide convenience constants if it makes sense, ie:
    public static let http1_0 = HTTPVersion(major: 1, minor: 0)
    public static let http1_1 = HTTPVersion(major: 1, minor: 1)
    public static let http2_0 = HTTPVersion(major: 2, minor: 0)

Having said that, there is slight additional storage overhead for structs vs. enums, as a slight additional compare cost.

Chris

Michael Chiu <hatsuneyuji@icloud.com> wrote on 14/06/2017 08:12:35: > > > From: Michael Chiu <hatsuneyuji@icloud.com>
> To: Rien <Rien@Balancingrock.nl>
> Cc: Chris Bailey <BAILEYC@uk.ibm.com>, swift-server-dev@swift.org
> Date: 14/06/2017 08:12
> Subject: Re: [swift-server-dev] Convert HTTPVersion to struct
>
> I think currently the http version is come from the http_parser
> which has parsed the version string to number anyway. hence the
> performance should be similar.
>
> I do see some advantage to use struct tho, for example comparing
> only major version.
>
> Michael
>
> > On Jun 13, 2017, at 11:41 PM, Rien via swift-server-dev <swift- > > server-dev@swift.org> wrote:
> >
> > The choices seem to be:
> >
> > 1) String
> > 2) Enum
> > 3) Tuple
> > 4) Struct
> > 5) Class
> >
> > 1) String
> > Advantage: it is in fact an utf-8 string. No conversions needed.
> > Disadvantage: It is mostly thought of as a number, thus the
> abstraction does not match the type, very minor performance penalty
> in comparing. Illogical to add HTTP-version extensions to the type.
> >
> > 2) Enum
> > Advantage: shortest possible representation (?), fastest compare
> (?), easy to use.
> > Disadvantage: Needs converting to and from.
> >
> > 3) Tuple
> > Advantage: Matches fairly wel with the abstraction.
> > Disadvantage: Fairly complex conversion, adding members/operations
> is non-intuitive, not very easy to use.
> >
> > 4) Struct
> > Advantage: Matches fairly wel with the abstraction.
> > Disadvantage: Fairly complex conversion. Not very easy to use
> without adding members/operations.
> >
> > 5) This was for completeness only, I would be very surprised if
> anybody would actually propose this… :wink:
> >
> >
> > To me that leaves option 2 and 4.
> > Advantage of 2 over 4:
> >
> > - I find the abstraction a better match. The difference between 1,
> 1.1 and 2 is such that it makes little sense to be to differentiate
> based on the numerical values. It makes much more sense to
> differentiate based on the “whole number”. AFAIIC they could just as
> easily have named the versions A, B, C etc. The numbers do not
> convey any information as such.
> > - Switch is easier and more intuitive to use.
> > - Enums can have additional properties and operations similar to struct.
> >
> > Advantage of 4 over 2:
> > I don’t see any.
> >
> > Regards,
> > Rien
> >
> > Site: http://balancingrock.nl
> > Blog: http://swiftrien.blogspot.com
> > Github: http://github.com/Balancingrock
> > Project: http://swiftfire.nl - An HTTP(S) web server framework in Swift
> >
> >
> >
> >> On 13 Jun 2017, at 22:44, Chris Bailey via swift-server-dev > > <swift-server-dev@swift.org> wrote:
> >>
> >> Based on our discussed approach of reviewing each of the types in
> the HTTP project, I've raised the following PR to convert
> HTTPVersion from (Int, Int) to a struct based on Paulo's proposal:
> >> https://github.com/swift-server/http/pull/6
> >>
> >> I've not yet added Hashable, Equatable and
> CustomStringConvertible protocols - we can do that if we're happy
> with the change.
> >>
> >> Chris
> >> Unless stated otherwise above:
> >> IBM United Kingdom Limited - Registered in England and Wales with
> number 741598.
> >> Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU
> >> _______________________________________________
> >> swift-server-dev mailing list
> >> swift-server-dev@swift.org
> >> https://lists.swift.org/mailman/listinfo/swift-server-dev
> >
> > _______________________________________________
> > swift-server-dev mailing list
> > swift-server-dev@swift.org
> > https://lists.swift.org/mailman/listinfo/swift-server-dev
>

Unless stated otherwise above:
IBM United Kingdom Limited - Registered in England and Wales with number 741598.
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU


(Rien) #11

This automatically include all future version without modify any existing code.

extension HTTPVersion {
    public func > (lhs: HTTPVersion, rhs: HTTPVersion) -> Bool
    {
         return lhs.major > rhs.major ? true : (lhs.minor > rhs.minor)
    }

    public static var minimumVersionSupportsMulitpleDomain: HTTPVersion {
        return HTTPVersion(1,1)
    }

    var isMulitpleDomainCapable: Bool {
        return self > HTTPVersion.minimumVersionSupportsMulitpleDomain
    }
}

Yes, I did say it comes down to programming style… :wink:

Myself I don’t mind a little rework for something as important as the HTTP Version. Keeps me on my toes, and sometimes it makes me realise that I need to change something after all...

Regards,
Rien

Site: http://balancingrock.nl
Blog: http://swiftrien.blogspot.com
Github: http://github.com/Balancingrock
Project: http://swiftfire.nl - An HTTP(S) web server framework in Swift

···

On 14 Jun 2017, at 11:46, Michael Chiu <hatsuneyuji@icloud.com> wrote:

Cheers,
Michael

On Jun 14, 2017, at 2:30 AM, Rien <Rien@Balancingrock.nl> wrote:

On 14 Jun 2017, at 09:12, Michael Chiu <hatsuneyuji@icloud.com> wrote:

I think currently the http version is come from the http_parser which has parsed the version string to number anyway. hence the performance should be similar.

That is likely, but imo the HTTP API should be judged on its own merits.

I do see some advantage to use struct tho, for example comparing only major version.

That is where I don’t see a real world advantage. Theoretically you are correct, but in a real world example?, do you have an example where this is indeed useful?
Given the limited range of useful versions numbers (only 3!) I just don’t see it.

I realize that this reaches into preferred programming techniques, but I like to use capability test on the type.
I.e. I would write

enum HttpVersion { case http1_0, http1_1, http2_0 }

extension HttpVersion {
  var isMultipleDomainCapable: Bool {
    switch self {
    case .http1_0: return false
    case .http1_1: return true
    case .http2_0: return true
    }
  }
}

if version.isMultipleDomainCapable { }

instead of:

struct HttpVersion {
  let major: Int
  let minor: Int

  static func == ...
}

if (version == HttpVersion(1, 1) || (version == HttpVersion(2, 0)) {
  // supports multiple domains
}

Regards,
Rien

Site: http://balancingrock.nl
Blog: http://swiftrien.blogspot.com
Github: http://github.com/Balancingrock
Project: http://swiftfire.nl - An HTTP(S) web server framework in Swift

Michael

On Jun 13, 2017, at 11:41 PM, Rien via swift-server-dev <swift-server-dev@swift.org> wrote:

The choices seem to be:

1) String
2) Enum
3) Tuple
4) Struct
5) Class

1) String
Advantage: it is in fact an utf-8 string. No conversions needed.
Disadvantage: It is mostly thought of as a number, thus the abstraction does not match the type, very minor performance penalty in comparing. Illogical to add HTTP-version extensions to the type.

2) Enum
Advantage: shortest possible representation (?), fastest compare (?), easy to use.
Disadvantage: Needs converting to and from.

3) Tuple
Advantage: Matches fairly wel with the abstraction.
Disadvantage: Fairly complex conversion, adding members/operations is non-intuitive, not very easy to use.

4) Struct
Advantage: Matches fairly wel with the abstraction.
Disadvantage: Fairly complex conversion. Not very easy to use without adding members/operations.

5) This was for completeness only, I would be very surprised if anybody would actually propose this… :wink:

To me that leaves option 2 and 4.
Advantage of 2 over 4:

- I find the abstraction a better match. The difference between 1, 1.1 and 2 is such that it makes little sense to be to differentiate based on the numerical values. It makes much more sense to differentiate based on the “whole number”. AFAIIC they could just as easily have named the versions A, B, C etc. The numbers do not convey any information as such.
- Switch is easier and more intuitive to use.
- Enums can have additional properties and operations similar to struct.

Advantage of 4 over 2:
I don’t see any.

Regards,
Rien

Site: http://balancingrock.nl
Blog: http://swiftrien.blogspot.com
Github: http://github.com/Balancingrock
Project: http://swiftfire.nl - An HTTP(S) web server framework in Swift

On 13 Jun 2017, at 22:44, Chris Bailey via swift-server-dev <swift-server-dev@swift.org> wrote:

Based on our discussed approach of reviewing each of the types in the HTTP project, I've raised the following PR to convert HTTPVersion from (Int, Int) to a struct based on Paulo's proposal:
     https://github.com/swift-server/http/pull/6

I've not yet added Hashable, Equatable and CustomStringConvertible protocols - we can do that if we're happy with the change.

Chris
Unless stated otherwise above:
IBM United Kingdom Limited - Registered in England and Wales with number 741598.
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU
_______________________________________________
swift-server-dev mailing list
swift-server-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-server-dev

_______________________________________________
swift-server-dev mailing list
swift-server-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-server-dev


(Rien) #12

I approved the changes in Chris's PR swift-server/http#6, I think moving away from typealias wherever possible is a great idea. IMO typealiases really only make sense for protocol composition.

On an unrelated note, I'm considering submitting a PR that would move the HTTP models into a module named `HTTP`. This would name space things like `HTTPVersion` to `HTTP.Version` (usable as just `Version` when no ambiguities exist). I think this would make the package more concise and feel less like Obj-C.
Any arguments against name spacing?

+1

Regards,
Rien

Site: http://balancingrock.nl
Blog: http://swiftrien.blogspot.com
Github: http://github.com/Balancingrock
Project: http://swiftfire.nl - An HTTP(S) web server framework in Swift

···

On 14 Jun 2017, at 11:13, Tanner Nelson <tanner@vapor.codes> wrote:

On Wed, Jun 14, 2017 at 8:13 AM Michael Chiu via swift-server-dev <swift-server-dev@swift.org> wrote:
I think currently the http version is come from the http_parser which has parsed the version string to number anyway. hence the performance should be similar.

I do see some advantage to use struct tho, for example comparing only major version.

Michael

> On Jun 13, 2017, at 11:41 PM, Rien via swift-server-dev <swift-server-dev@swift.org> wrote:
>
> The choices seem to be:
>
> 1) String
> 2) Enum
> 3) Tuple
> 4) Struct
> 5) Class
>
> 1) String
> Advantage: it is in fact an utf-8 string. No conversions needed.
> Disadvantage: It is mostly thought of as a number, thus the abstraction does not match the type, very minor performance penalty in comparing. Illogical to add HTTP-version extensions to the type.
>
> 2) Enum
> Advantage: shortest possible representation (?), fastest compare (?), easy to use.
> Disadvantage: Needs converting to and from.
>
> 3) Tuple
> Advantage: Matches fairly wel with the abstraction.
> Disadvantage: Fairly complex conversion, adding members/operations is non-intuitive, not very easy to use.
>
> 4) Struct
> Advantage: Matches fairly wel with the abstraction.
> Disadvantage: Fairly complex conversion. Not very easy to use without adding members/operations.
>
> 5) This was for completeness only, I would be very surprised if anybody would actually propose this… :wink:
>
>
> To me that leaves option 2 and 4.
> Advantage of 2 over 4:
>
> - I find the abstraction a better match. The difference between 1, 1.1 and 2 is such that it makes little sense to be to differentiate based on the numerical values. It makes much more sense to differentiate based on the “whole number”. AFAIIC they could just as easily have named the versions A, B, C etc. The numbers do not convey any information as such.
> - Switch is easier and more intuitive to use.
> - Enums can have additional properties and operations similar to struct.
>
> Advantage of 4 over 2:
> I don’t see any.
>
> Regards,
> Rien
>
> Site: http://balancingrock.nl
> Blog: http://swiftrien.blogspot.com
> Github: http://github.com/Balancingrock
> Project: http://swiftfire.nl - An HTTP(S) web server framework in Swift
>
>
>
>> On 13 Jun 2017, at 22:44, Chris Bailey via swift-server-dev <swift-server-dev@swift.org> wrote:
>>
>> Based on our discussed approach of reviewing each of the types in the HTTP project, I've raised the following PR to convert HTTPVersion from (Int, Int) to a struct based on Paulo's proposal:
>> https://github.com/swift-server/http/pull/6
>>
>> I've not yet added Hashable, Equatable and CustomStringConvertible protocols - we can do that if we're happy with the change.
>>
>> Chris
>> Unless stated otherwise above:
>> IBM United Kingdom Limited - Registered in England and Wales with number 741598.
>> Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU
>> _______________________________________________
>> swift-server-dev mailing list
>> swift-server-dev@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-server-dev
>
> _______________________________________________
> swift-server-dev mailing list
> swift-server-dev@swift.org
> https://lists.swift.org/mailman/listinfo/swift-server-dev

_______________________________________________
swift-server-dev mailing list
swift-server-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-server-dev


(Helge Heß) #13

This is actually a argument *for* using numbers. When using an enum in an API makes the same break every time you change it. And that is killer for a an API representing a living protocol like HTTP.

Also in proper source you would check for: `if major >= 2`, not `==`, another advantage of using version _numbers_.

In the context of HTTPVersion I think there shouldn’t be too much discussion though, for two reasons:
- If we get HTTP/3.x, we almost certainly have a new API revision.
- The HTTP version should only matter for logging purposes. The differences in capabilities
  should be handled by the implementation (e.g. keep alive vs not, multiplexing or not, etc).
  In other words, you should never have to check for the versions, but rather features.

hh

···

On 14. Jun 2017, at 11:36, Rien via swift-server-dev <swift-server-dev@swift.org> wrote:

On 14 Jun 2017, at 11:14, Chris Bailey <BAILEYC@uk.ibm.com> wrote:

One factor is whether you consider the version to be discrete values or a structured format for data - I'd argue that we have a structured format due to the expectation that future versions of the HTTP spec could arrive.

But do you want your code littered with numerical tests or conceptual tests?
Suppose a new version of HTTP does arrive, do you really want to manually walk through the code and find all tests on the numerical values?
Or would it be easier to use switch statements on an enum and have all missing cases pointed out to you?


(Rien) #14

One factor is whether you consider the version to be discrete values or a structured format for data - I'd argue that we have a structured format due to the expectation that future versions of the HTTP spec could arrive.

But do you want your code littered with numerical tests or conceptual tests?
Suppose a new version of HTTP does arrive, do you really want to manually walk through the code and find all tests on the numerical values?
Or would it be easier to use switch statements on an enum and have all missing cases pointed out to you?

This is actually a argument *for* using numbers. When using an enum in an API makes the same break every time you change it. And that is killer for a an API representing a living protocol like HTTP.

Also in proper source you would check for: `if major >= 2`, not `==`, another advantage of using version _numbers_.

In the context of HTTPVersion

Precisely. I am making the argument for enum’s only for the HTTPVersion since it is such a unique feature.

I think there shouldn’t be too much discussion though, for two reasons:
- If we get HTTP/3.x, we almost certainly have a new API revision.

Absolutely.

- The HTTP version should only matter for logging purposes. The differences in capabilities
should be handled by the implementation (e.g. keep alive vs not, multiplexing or not, etc).

Agreed, which is why the decision should be made carefully. An API developer usually sees things differently from an API user. Conceptually a version number is just a tag. It does not represent a numerical value. Which makes testing for numerical values error prone, which leads to your following point:

In other words, you should never have to check for the versions, but rather features.

Again, fully agreed. But which I interpret as an argument in favour of enums...

Rien.

···

On 14 Jun 2017, at 12:11, Helge Heß via swift-server-dev <swift-server-dev@swift.org> wrote:
On 14. Jun 2017, at 11:36, Rien via swift-server-dev <swift-server-dev@swift.org> wrote:

On 14 Jun 2017, at 11:14, Chris Bailey <BAILEYC@uk.ibm.com> wrote:

hh

_______________________________________________
swift-server-dev mailing list
swift-server-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-server-dev


(Tanner Nelson) #15

Unless there is a need to be able to exhaustively switch over all supported
HTTP versions, using an enum seems overly restrictive. Especially when
considering that adding or removing cases from enums is a breaking change
(requires a major version bump). As authors of a general purpose HTTP
package, we should be avoiding unnecessary restrictions wherever possible.

As an aside, Go also uses two integers to represent major and minor.
https://golang.org/pkg/net/http/#Request

···

On Wed, Jun 14, 2017 at 11:38 Rien via swift-server-dev < swift-server-dev@swift.org> wrote:

> On 14 Jun 2017, at 12:11, Helge Heß via swift-server-dev < > swift-server-dev@swift.org> wrote:
>
> On 14. Jun 2017, at 11:36, Rien via swift-server-dev < > swift-server-dev@swift.org> wrote:
>>> On 14 Jun 2017, at 11:14, Chris Bailey <BAILEYC@uk.ibm.com> wrote:
>>>
>>> One factor is whether you consider the version to be discrete values
or a structured format for data - I'd argue that we have a structured
format due to the expectation that future versions of the HTTP spec could
arrive.
>>
>> But do you want your code littered with numerical tests or conceptual
tests?
>> Suppose a new version of HTTP does arrive, do you really want to
manually walk through the code and find all tests on the numerical values?
>> Or would it be easier to use switch statements on an enum and have all
missing cases pointed out to you?
>
> This is actually a argument *for* using numbers. When using an enum in
an API makes the same break every time you change it. And that is killer
for a an API representing a living protocol like HTTP.
>
> Also in proper source you would check for: `if major >= 2`, not `==`,
another advantage of using version _numbers_.
>
> In the context of HTTPVersion

Precisely. I am making the argument for enum’s only for the HTTPVersion
since it is such a unique feature.

> I think there shouldn’t be too much discussion though, for two reasons:
> - If we get HTTP/3.x, we almost certainly have a new API revision.

Absolutely.

> - The HTTP version should only matter for logging purposes. The
differences in capabilities
> should be handled by the implementation (e.g. keep alive vs not,
multiplexing or not, etc).

Agreed, which is why the decision should be made carefully. An API
developer usually sees things differently from an API user. Conceptually a
version number is just a tag. It does not represent a numerical value.
Which makes testing for numerical values error prone, which leads to your
following point:

> In other words, you should never have to check for the versions, but
rather features.

Again, fully agreed. But which I interpret as an argument in favour of
enums...

Rien.

>
> hh
>
> _______________________________________________
> swift-server-dev mailing list
> swift-server-dev@swift.org
> https://lists.swift.org/mailman/listinfo/swift-server-dev

_______________________________________________
swift-server-dev mailing list
swift-server-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-server-dev


(Rien) #16

Unless there is a need to be able to exhaustively switch over all supported HTTP versions, using an enum seems overly restrictive. Especially when considering that adding or removing cases from enums is a breaking change (requires a major version bump).

I presume that supporting a new HTTP version will always require a major version bump.

Rien.

···

On 14 Jun 2017, at 13:29, Tanner Nelson <tanner@vapor.codes> wrote:

As authors of a general purpose HTTP package, we should be avoiding unnecessary restrictions wherever possible.

As an aside, Go also uses two integers to represent major and minor. https://golang.org/pkg/net/http/#Request
On Wed, Jun 14, 2017 at 11:38 Rien via swift-server-dev <swift-server-dev@swift.org> wrote:

> On 14 Jun 2017, at 12:11, Helge Heß via swift-server-dev <swift-server-dev@swift.org> wrote:
>
> On 14. Jun 2017, at 11:36, Rien via swift-server-dev <swift-server-dev@swift.org> wrote:
>>> On 14 Jun 2017, at 11:14, Chris Bailey <BAILEYC@uk.ibm.com> wrote:
>>>
>>> One factor is whether you consider the version to be discrete values or a structured format for data - I'd argue that we have a structured format due to the expectation that future versions of the HTTP spec could arrive.
>>
>> But do you want your code littered with numerical tests or conceptual tests?
>> Suppose a new version of HTTP does arrive, do you really want to manually walk through the code and find all tests on the numerical values?
>> Or would it be easier to use switch statements on an enum and have all missing cases pointed out to you?
>
> This is actually a argument *for* using numbers. When using an enum in an API makes the same break every time you change it. And that is killer for a an API representing a living protocol like HTTP.
>
> Also in proper source you would check for: `if major >= 2`, not `==`, another advantage of using version _numbers_.
>
> In the context of HTTPVersion

Precisely. I am making the argument for enum’s only for the HTTPVersion since it is such a unique feature.

> I think there shouldn’t be too much discussion though, for two reasons:
> - If we get HTTP/3.x, we almost certainly have a new API revision.

Absolutely.

> - The HTTP version should only matter for logging purposes. The differences in capabilities
> should be handled by the implementation (e.g. keep alive vs not, multiplexing or not, etc).

Agreed, which is why the decision should be made carefully. An API developer usually sees things differently from an API user. Conceptually a version number is just a tag. It does not represent a numerical value. Which makes testing for numerical values error prone, which leads to your following point:

> In other words, you should never have to check for the versions, but rather features.

Again, fully agreed. But which I interpret as an argument in favour of enums...

Rien.

>
> hh
>
> _______________________________________________
> swift-server-dev mailing list
> swift-server-dev@swift.org
> https://lists.swift.org/mailman/listinfo/swift-server-dev

_______________________________________________
swift-server-dev mailing list
swift-server-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-server-dev


(Tanner Nelson) #17

Requiring a new version to support new features and having existing code be
compatible with a new version are two different things.

···

On Wed, Jun 14, 2017 at 12:44 Rien <Rien@balancingrock.nl> wrote:

> On 14 Jun 2017, at 13:29, Tanner Nelson <tanner@vapor.codes> wrote:
>
> Unless there is a need to be able to exhaustively switch over all
supported HTTP versions, using an enum seems overly restrictive. Especially
when considering that adding or removing cases from enums is a breaking
change (requires a major version bump).

I presume that supporting a new HTTP version will always require a major
version bump.

Rien.

> As authors of a general purpose HTTP package, we should be avoiding
unnecessary restrictions wherever possible.
>
> As an aside, Go also uses two integers to represent major and minor.
https://golang.org/pkg/net/http/#Request
> On Wed, Jun 14, 2017 at 11:38 Rien via swift-server-dev < > swift-server-dev@swift.org> wrote:
>
> > On 14 Jun 2017, at 12:11, Helge Heß via swift-server-dev < > swift-server-dev@swift.org> wrote:
> >
> > On 14. Jun 2017, at 11:36, Rien via swift-server-dev < > swift-server-dev@swift.org> wrote:
> >>> On 14 Jun 2017, at 11:14, Chris Bailey <BAILEYC@uk.ibm.com> wrote:
> >>>
> >>> One factor is whether you consider the version to be discrete values
or a structured format for data - I'd argue that we have a structured
format due to the expectation that future versions of the HTTP spec could
arrive.
> >>
> >> But do you want your code littered with numerical tests or conceptual
tests?
> >> Suppose a new version of HTTP does arrive, do you really want to
manually walk through the code and find all tests on the numerical values?
> >> Or would it be easier to use switch statements on an enum and have
all missing cases pointed out to you?
> >
> > This is actually a argument *for* using numbers. When using an enum in
an API makes the same break every time you change it. And that is killer
for a an API representing a living protocol like HTTP.
> >
> > Also in proper source you would check for: `if major >= 2`, not `==`,
another advantage of using version _numbers_.
> >
> > In the context of HTTPVersion
>
> Precisely. I am making the argument for enum’s only for the HTTPVersion
since it is such a unique feature.
>
>
> > I think there shouldn’t be too much discussion though, for two reasons:
> > - If we get HTTP/3.x, we almost certainly have a new API revision.
>
> Absolutely.
>
> > - The HTTP version should only matter for logging purposes. The
differences in capabilities
> > should be handled by the implementation (e.g. keep alive vs not,
multiplexing or not, etc).
>
> Agreed, which is why the decision should be made carefully. An API
developer usually sees things differently from an API user. Conceptually a
version number is just a tag. It does not represent a numerical value.
Which makes testing for numerical values error prone, which leads to your
following point:
>
> > In other words, you should never have to check for the versions, but
rather features.
>
> Again, fully agreed. But which I interpret as an argument in favour of
enums...
>
> Rien.
>
> >
> > hh
> >
> > _______________________________________________
> > swift-server-dev mailing list
> > swift-server-dev@swift.org
> > https://lists.swift.org/mailman/listinfo/swift-server-dev
>
> _______________________________________________
> swift-server-dev mailing list
> swift-server-dev@swift.org
> https://lists.swift.org/mailman/listinfo/swift-server-dev


(Rien) #18

Requiring a new version to support new features and having existing code be compatible with a new version are two different things.

Yes! thank you.
Lets go for the struct.

I was sitting too much in my own little world and not thinking as an API developer.

Regards,
Rien

Site: http://balancingrock.nl
Blog: http://swiftrien.blogspot.com
Github: http://github.com/Balancingrock
Project: http://swiftfire.nl - An HTTP(S) web server framework in Swift

···

On 14 Jun 2017, at 13:46, Tanner Nelson <tanner@vapor.codes> wrote:

On Wed, Jun 14, 2017 at 12:44 Rien <Rien@balancingrock.nl> wrote:

> On 14 Jun 2017, at 13:29, Tanner Nelson <tanner@vapor.codes> wrote:
>
> Unless there is a need to be able to exhaustively switch over all supported HTTP versions, using an enum seems overly restrictive. Especially when considering that adding or removing cases from enums is a breaking change (requires a major version bump).

I presume that supporting a new HTTP version will always require a major version bump.

Rien.

> As authors of a general purpose HTTP package, we should be avoiding unnecessary restrictions wherever possible.
>
> As an aside, Go also uses two integers to represent major and minor. https://golang.org/pkg/net/http/#Request
> On Wed, Jun 14, 2017 at 11:38 Rien via swift-server-dev <swift-server-dev@swift.org> wrote:
>
> > On 14 Jun 2017, at 12:11, Helge Heß via swift-server-dev <swift-server-dev@swift.org> wrote:
> >
> > On 14. Jun 2017, at 11:36, Rien via swift-server-dev <swift-server-dev@swift.org> wrote:
> >>> On 14 Jun 2017, at 11:14, Chris Bailey <BAILEYC@uk.ibm.com> wrote:
> >>>
> >>> One factor is whether you consider the version to be discrete values or a structured format for data - I'd argue that we have a structured format due to the expectation that future versions of the HTTP spec could arrive.
> >>
> >> But do you want your code littered with numerical tests or conceptual tests?
> >> Suppose a new version of HTTP does arrive, do you really want to manually walk through the code and find all tests on the numerical values?
> >> Or would it be easier to use switch statements on an enum and have all missing cases pointed out to you?
> >
> > This is actually a argument *for* using numbers. When using an enum in an API makes the same break every time you change it. And that is killer for a an API representing a living protocol like HTTP.
> >
> > Also in proper source you would check for: `if major >= 2`, not `==`, another advantage of using version _numbers_.
> >
> > In the context of HTTPVersion
>
> Precisely. I am making the argument for enum’s only for the HTTPVersion since it is such a unique feature.
>
>
> > I think there shouldn’t be too much discussion though, for two reasons:
> > - If we get HTTP/3.x, we almost certainly have a new API revision.
>
> Absolutely.
>
> > - The HTTP version should only matter for logging purposes. The differences in capabilities
> > should be handled by the implementation (e.g. keep alive vs not, multiplexing or not, etc).
>
> Agreed, which is why the decision should be made carefully. An API developer usually sees things differently from an API user. Conceptually a version number is just a tag. It does not represent a numerical value. Which makes testing for numerical values error prone, which leads to your following point:
>
> > In other words, you should never have to check for the versions, but rather features.
>
> Again, fully agreed. But which I interpret as an argument in favour of enums...
>
> Rien.
>
> >
> > hh
> >
> > _______________________________________________
> > swift-server-dev mailing list
> > swift-server-dev@swift.org
> > https://lists.swift.org/mailman/listinfo/swift-server-dev
>
> _______________________________________________
> swift-server-dev mailing list
> swift-server-dev@swift.org
> https://lists.swift.org/mailman/listinfo/swift-server-dev


(Helge Heß) #19

I gave my feedback on the type in the this thread already. Struct is fine for me, tuple is OK too. I don’t actually care much as “The HTTP version should only matter for logging purposes”. If it comes with comparison operations and such, something is likely wrong with the API.

The only HTTP/2 specific note I have is this thing:

  From the HTTPRequest API design perspective there is a small
  change in that method/version are just headers in HTTP/2.
  I brought that up before.
  E.g. why does ‘method' deserve a special enum, but not
  content-type etc which is equally important for dispatching
  a request. Either approach is fine though.)

This affects the discussion as it may make sense to expose the
HTTPVersion as a regular header to mirror the new HTTP/2 setup
instead of basing the API on the old HTTP/0,1 model.
(I think either is fine, with a slight preference for going
with the ‘future’)

Or in other words: Why struct or tuple, just keep it as a string
like the other headers.

If HTTPVersion is not exposed as a String but as a specific type,
that would then affect the way headers in general are handled
(and I’m very much in favour of NOT using strings for the common
ones for various reasons).

hh

···

On 14 Jun 2017, at 14:59, Paulo Faria <paulo@zewo.io> wrote:

You're completely right we should care about HTTP 2.0 now. But let's do it one step at a time, or else we won't get things done. The current topic is the HTTPVersion type. So could you please give your feedback in the HTTPVersion thread about how the current proposal of HTTPversion fits with HTTP 2.0? We should go from lower abstractions to higher abstractions incrementally but definitely considering the upper abstractions. Let's keep focus and move on! :blush:


#20

So are we going to write our own http parser?

If not, I don’t see the benefit of ditching version and method properties since both major/minor version and method are given by the http_parser, and users are expecting to find it in the property since these components are well defined in RFC and guaranteed its existence in a proper http req/res. Hence they deserve to be an independent property.

On the other hand, there’s no one guarantee the existence of Content-Type and Content-Length etc header exists in HTTP protocol (I can be wrong).

Michael.

···

On Jun 14, 2017, at 6:27 AM, Tanner Nelson via swift-server-dev <swift-server-dev@swift.org <mailto:swift-server-dev@swift.org>> wrote:

On Wed, Jun 14, 2017 at 2:11 PM Helge Heß via swift-server-dev <swift-server-dev@swift.org <mailto:swift-server-dev@swift.org>> wrote:
On 14 Jun 2017, at 14:59, Paulo Faria <paulo@zewo.io <mailto:paulo@zewo.io>> wrote:
> You're completely right we should care about HTTP 2.0 now. But let's do it one step at a time, or else we won't get things done. The current topic is the HTTPVersion type. So could you please give your feedback in the HTTPVersion thread about how the current proposal of HTTPversion fits with HTTP 2.0? We should go from lower abstractions to higher abstractions incrementally but definitely considering the upper abstractions. Let's keep focus and move on! :blush:

I gave my feedback on the type in the this thread already. Struct is fine for me, tuple is OK too. I don’t actually care much as “The HTTP version should only matter for logging purposes”. If it comes with comparison operations and such, something is likely wrong with the API.

The only HTTP/2 specific note I have is this thing:

  From the HTTPRequest API design perspective there is a small
  change in that method/version are just headers in HTTP/2.
  I brought that up before.
  E.g. why does ‘method' deserve a special enum, but not
  content-type etc which is equally important for dispatching
  a request. Either approach is fine though.)

In that case, maybe we ditch the version and method properties in favor of something more generic like:

(just spitballing some pseudo swift here)


    struct Request {
        ...
        enum Metadata {
            case original(major: Int, minor: Int, Method)
            case headers
        }

        var metadata: Metadata
        ...
    }

    extension Request {
        var method: Method {
            switch metadata {
            case .original(_, _, let method):
                return method
            case .headers:
                return Method(rawValue: headers["Method"])
            }
        }
    }

Here an enum's ability to exhaustively switch would be useful. Then `req.method` is implemented as an extension similar to how `req.version` and `req.contentType` could be implemented.

This affects the discussion as it may make sense to expose the
HTTPVersion as a regular header to mirror the new HTTP/2 setup
instead of basing the API on the old HTTP/0,1 model.
(I think either is fine, with a slight preference for going
with the ‘future’)

Or in other words: Why struct or tuple, just keep it as a string
like the other headers.

If HTTPVersion is not exposed as a String but as a specific type,
that would then affect the way headers in general are handled
(and I’m very much in favour of NOT using strings for the common
ones for various reasons).

hh

_______________________________________________
swift-server-dev mailing list
swift-server-dev@swift.org <mailto:swift-server-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-server-dev
_______________________________________________
swift-server-dev mailing list
swift-server-dev@swift.org <mailto:swift-server-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-server-dev