k3po / k3po

"I am fluent in over 6 million forms of communication!"
Apache License 2.0
48 stars 34 forks source link

WSE specification should allow GET for create request and POST for downstream request #298

Open cmebarrow opened 8 years ago

cmebarrow commented 8 years ago

The WSE specification currently mandates that the create request method MUST be POST and the downstream MUST be GET. This is too restrictive for some clients, for example, the .Net client must use POST for all requests because the platform does not support the use of GET.

According to comments in the Kaazing Gateway code (WsebDownstreamHandler) some clients need to do 0 length POST or even a non-zero length POST for the downstream request. Here is the comment in question:

    // most clients use GET for downstream (empty POST okay too)
    // defer attach writer to message received for non-empty POSTs (such as Flash client)

This suggests that the WSE specification, Client Downstream Requirements section, is too strict in this regard when it mandates that the request method MUST be GET.

@sanjay-saxena and chao have confirmed that the .Net client uses POST for all requests. The javascript and java clients currently use GET for the create request while Flash and .Net use POST.

cmebarrow commented 8 years ago

@sanjay-saxena told me .Net client uses POST.

cmebarrow commented 8 years ago

Here is a wireshark trace of Javascript client from JMS gateway 4.2 release maknig a wse connection then closing: wse_connect_javascript.4.2.client.pcap

Here is same for Flash client: wse_connect_close_flash.4.2.client.pcap

This shows Javascript client makes a GET request for create, without any use of httpxe to transform it into a POST. Flash client makes a POST request for downstream, without any use of httpxe to transport it into a GET

cmebarrow commented 8 years ago

From Sanjay:

NET:

POST /;post/jms/;e/cb HTTP/1.1
Content-Type: text/plain
X-Accept-Commands: ping
X-WebSocket-Extensions: x-kaazing-http-revalidate
X-WebSocket-Version: wseb-1.0
X-Origin: privileged://gateway.kaazing.test:9000
X-Origin-privileged%3A%2F%2Fgateway.kaazing.test%3A9000: privileged://gateway.kaazing.test:9000
Host: gateway.kaazing.test:9000
Content-Length: 3
Expect: 100-continue
Connection: Keep-Alive

JS:

GET /echo80/;e/ctm?.kn=07664851495064795 HTTP/1.1
Host: localhost
Connection: keep-alive
X-Origin: http://localhost:8001
X-WebSocket-Version: wseb-1.0
X-Accept-Commands: ping
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36
Content-Type: text/plain; charset=utf-8
X-WebSocket-Extensions: x-kaazing-http-revalidate
X-Sequence-No: 0
Accept: ​*/*​
Referer: http://localhost/?.kr=xs
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
cmebarrow commented 8 years ago

Fix is proposed in PR #300

jfallows commented 8 years ago

The create request really ought to use the POST method because it returns a 201 Created response from the server.

The JavaScript implementation is therefore off-spec. This was originally done because the create request was getting HTTP redirected cross-origin to a peer server and the act of redirecting caused it to become a GET. There is an appropriate redirect status code that should retain the method as POST but it may not be implemented correctly on all platforms.

We should therefore state that the client requirements for create request are MUST be POST and the server requirements can be slightly more tolerant with SHOULD be POST but MAY also be GET. The classic approach of strict on writes and tolerant on reads, similar to lowercase websocket on write but case insensitive on read for the Upgrade header in the WebSocket handshake.

For the downstream request, making both GET and POST requests with .NET seems well documented:

http://stackoverflow.com/questions/4015324/http-request-with-post

We standardized the protocol on GET to avoid creating unnecessary browser history in some situations.

If the client technology supports the specified behavior, then we should hold the spec steady and fix the clients.

cmebarrow commented 8 years ago

@jfallows Can we use same approach for downstream as you suggested for upstream: client MUST use GET, server SHOULD be GET but tolerates POST? If I make server reject POST it will break existing clients (,Net and Flash). It might not be possible for Flash client to do GET.

cmebarrow commented 8 years ago

@jfallows I have updated PR #300 to reflect the above.

jfallows commented 8 years ago

@cmebarrow: yes - that seems a reasonable approach.