HTTP Header field handling in Zinc

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

HTTP Header field handling in Zinc

Udo Schneider
All,

Is there a supported way to change the capitalization of HTTP header
fields in Zinc? I'm currently running into problems with a websocketpp
(https://github.com/zaphoyd/websocketpp) based backend which expects a
specifically capitalized Sec-WebSocket-* header field. E.g.
Sec-WebSocket-* works, Sec-Websocket-* does not.

As far as as I can see Zinc nicely capitalizes HTTP header fields. E.g.
even if you provide "Sec-WebSocket-Key" the actual transmitted header is
"Sec-Websocket-Key".

I know that HTTP specified that header fields are case-insensitive. So
problem is clearly on the websocketpp side. I just want to know if I can
somehow instruct Zinc to not touch the capitalization to make working
with non-compliant backends easier.

Thanks,

Udo


Reply | Threaded
Open this post in threaded view
|

Re: HTTP Header field handling in Zinc

Sven Van Caekenberghe-2
Hi Udo,

On 26 Jul 2013, at 22:54, Udo Schneider <[hidden email]> wrote:

> All,
>
> Is there a supported way to change the capitalization of HTTP header fields in Zinc? I'm currently running into problems with a websocketpp (https://github.com/zaphoyd/websocketpp) based backend which expects a specifically capitalized Sec-WebSocket-* header field. E.g. Sec-WebSocket-* works, Sec-Websocket-* does not.
>
> As far as as I can see Zinc nicely capitalizes HTTP header fields. E.g. even if you provide "Sec-WebSocket-Key" the actual transmitted header is "Sec-Websocket-Key".
>
> I know that HTTP specified that header fields are case-insensitive. So problem is clearly on the websocketpp side. I just want to know if I can somehow instruct Zinc to not touch the capitalization to make working with non-compliant backends easier.
>
> Thanks,
>
> Udo

Good analysis: you are completely right.

Be sure to tell the websocketpp guys about this issue ;-)

A quick hack from our side would be to bypass the normal protocol of ZnHeader (specifically #normalizeHeaderKey:) and access its internal dictionary directly, using a private selector (named #headers) like this:

| request |
request := ZnRequest get: 'http://foo.com/bar?x=1'.
request headers headers at: 'FUNy-headER' put: 'test'.
request writeToTranscript

which would go on the wire like

GET /bar?x=1 HTTP/1.1
Accept: */*
User-Agent: Zinc HTTP Components 1.0
FUNy-headER: test
Host: foo.com


It is not perfect, but I guess it would do.

Thanks for the feedback, make sure to tell me how it goes.

Sven

PS: You do know about Zinc-WebSockets, I guess ?

--
Sven Van Caekenberghe
Proudly supporting Pharo
http://pharo.org
http://association.pharo.org
http://consortium.pharo.org





Reply | Threaded
Open this post in threaded view
|

Re: HTTP Header field handling in Zinc

Udo Schneider
Hi Sven,


On 27.07.13 00:57, Sven Van Caekenberghe wrote:
> Be sure to tell the websocketpp guys about this issue ;-)
Already did. The fact that websocketpp based apps return with 500 is
even "funnier" IMHO...

> A quick hack from our side would be to bypass the normal protocol of ZnHeader (specifically #normalizeHeaderKey:) and access its internal dictionary directly, using a private selector (named #headers) like this:
>
> | request |
> request := ZnRequest get: 'http://foo.com/bar?x=1'.
> request headers headers at: 'FUNy-headER' put: 'test'.
> request writeToTranscript
>
> which would go on the wire like
>
> GET /bar?x=1 HTTP/1.1
> Accept: */*
> User-Agent: Zinc HTTP Components 1.0
> FUNy-headER: test
> Host: foo.com
>
>
> It is not perfect, but I guess it would do.
I stumbled about #normalizeHeaderKey: as well and took another route
(which is IMHO nicer ... to remove once websocketpp is fixed).

ZnHeaders class>>#addWebSocketHeaders
        CommonHeaders addAll: #('Sec-WebSocket-Version' 'Sec-WebSocket-Key')

ZnWebSocket already uses these strings with the exact same
capitilization - and being in CommonHeaders bypasses
#normalizeHeaderKey: for "known" headers. Still a hack but works.

> Thanks for the feedback, make sure to tell me how it goes.
After finding out about this everything else just works fine - Zinc is
simply amazing when working with HTTP. For me it's the first framework
(not only in Smalltalk) which really models HTTP in an OOP way without
being too complicated.
Simple things are easy - hard things possible :-)

> PS: You do know about Zinc-WebSockets, I guess ?
Yep - using them. I wasn't mentioning this explicitly as the headers
"problem" applies to ZnClient and might thus be affecting all HTTP based
stuff.

Best Regards,

Udo



Reply | Threaded
Open this post in threaded view
|

Re: HTTP Header field handling in Zinc

Sven Van Caekenberghe-2
Udo,

On 27 Jul 2013, at 12:50, Udo Schneider <[hidden email]> wrote:

> Hi Sven,
>
> On 27.07.13 00:57, Sven Van Caekenberghe wrote:
>> Be sure to tell the websocketpp guys about this issue ;-)
> Already did.

Good.

> The fact that websocketpp based apps return with 500 is even "funnier" IMHO…

:-)

>> A quick hack from our side would be to bypass the normal protocol of ZnHeader (specifically #normalizeHeaderKey:) and access its internal dictionary directly, using a private selector (named #headers) like this:
>>
>> | request |
>> request := ZnRequest get: 'http://foo.com/bar?x=1'.
>> request headers headers at: 'FUNy-headER' put: 'test'.
>> request writeToTranscript
>>
>> which would go on the wire like
>>
>> GET /bar?x=1 HTTP/1.1
>> Accept: */*
>> User-Agent: Zinc HTTP Components 1.0
>> FUNy-headER: test
>> Host: foo.com
>>
>>
>> It is not perfect, but I guess it would do.
> I stumbled about #normalizeHeaderKey: as well and took another route (which is IMHO nicer ... to remove once websocketpp is fixed).
>
> ZnHeaders class>>#addWebSocketHeaders
> CommonHeaders addAll: #('Sec-WebSocket-Version' 'Sec-WebSocket-Key')
>
> ZnWebSocket already uses these strings with the exact same capitilization - and being in CommonHeaders bypasses #normalizeHeaderKey: for "known" headers. Still a hack but works.

Yes, that is an excellent hack.
I introduced CommonHeaders quite recently as a performance improvement.
But is is no solution either, like you said.

>> Thanks for the feedback, make sure to tell me how it goes.
> After finding out about this everything else just works fine - Zinc is simply amazing when working with HTTP. For me it's the first framework (not only in Smalltalk) which really models HTTP in an OOP way without being too complicated.
> Simple things are easy - hard things possible :-)

Thanks a lot !

>> PS: You do know about Zinc-WebSockets, I guess ?
> Yep - using them. I wasn't mentioning this explicitly as the headers "problem" applies to ZnClient and might thus be affecting all HTTP based stuff.

OK, I thought so, but I wasn't sure.

> Best Regards,
>
> Udo

Keep the feedback coming, it is really important.

Sven


--
Sven Van Caekenberghe
http://stfx.eu
Smalltalk is the Red Pill