may be you are right about not not properly handeling the query params and
we might need to fix this regex:

final static String REGEX_SPLIT_SERVICE_PATH = "^((?:[^/]*/){3}[^/]*)";

You should be able to do a quick test using a this Unit Test
<https://git-wip-us.apache.org/repos/asf?p=knox.git;a=blobdiff;f=gateway-server/src/test/java/org/apache/hadoop/gateway/websockets/WebsocketEchoTest.java;h=4b0fe085d7a97e9848d9e3ec06417099df587a41;hp=5d1a1175cae606b5ec118ed7b322a9ea3a789a99;hb=98a08fc;hpb=4c2675aab4bfb4ae3a08250d75f349e3387c1cb1>

Best,
Sandeep




On Mon, Jun 18, 2018 at 1:55 PM T Smith <ailurop...@gmail.com> wrote:

> Sorry, bad example.
>
> I send ws://<host>:<port>/gateway/pnda/pndaconsole/
> socket.io/?EIO=3&transport=websocket
>
> Knox sends /socket.io/
>
> That yields a 400 error, Knox throws
> org.eclipse.jetty.websocket.api.UpgradeException: Didn't switch protocols
>
>
> On Mon, Jun 18, 2018 at 6:49 PM, T Smith <ailurop...@gmail.com> wrote:
>
>> Hi Sandeep,
>>
>> Back to fighting with this. Through some nginx debugging on my backend
>> I've come to the conclusion that Knox isn't sending the query parameters on
>> to the backend, regardless of what rewrite rules I specify.
>>
>> I.e. I send
>> /gateway/pnda/pndaconsole/socket.io/?EIO=3&transport=polling&t=MDGlYhd
>> <http://34.244.121.78:8443/gateway/pnda/pndaconsole/socket.io/?EIO=3&transport=polling&t=MDGlYhd>
>>
>> Knox sends /socket.io/
>> <http://34.244.121.78:8443/gateway/pnda/pndaconsole/socket.io/?EIO=3&transport=polling&t=MDGlYhd>
>>
>> This yields a 400 error, and Knox drops the websocket to the backend.
>> What was confusing me was the 101 in the browser, but I see now that Knox
>> is terminating the connection with the browser on one side and opening
>> another connection with the backend on the other.
>>
>> I see this https://git-wip-us.apache.org/repos/asf?p=knox.git;h=98a08fc
>> but I'm wondering if this code needs further work to support query
>> parameters? What do you think?
>>
>> Thanks in advance!
>>
>> /ailuropod4
>>
>> On Thu, May 17, 2018 at 8:57 AM, T Smith <ailurop...@gmail.com> wrote:
>>
>>> Hi Sandeep,
>>>
>>> Looking at my nginx server, it never sees the transport=websocket ws://
>>> protocol request, but it does see a http request for / at the corresponding
>>> time, so I think perhaps the root problem here is in that rewrite, as you
>>> mention. By the way, the reason for ws:// and not wss:// is I switched off
>>> TLS to remove another potential source of issue, so it's all plain http. I
>>> saw the same behaviour over https.
>>>
>>> My services, now, look like this -
>>>
>>>     <route path="/pndaconsole/socket.io">
>>>       <rewrite apply="PNDACONSOLE/pndaconsole/inbound/socket"
>>> to="request.url"/>
>>>     </route>
>>>
>>>     <route path="/pndaconsole/metrics">
>>>       <rewrite apply="PNDACONSOLE/pndaconsole/inbound/metrics"
>>> to="request.url"/>
>>>     </route>
>>>
>>>     <route path="/pndaconsole/">
>>>       <rewrite apply="PNDACONSOLE/pndaconsole/inbound/root"
>>> to="request.url"/>
>>>     </route>
>>>
>>>     <route path="/pndaconsole/**">
>>>       <rewrite apply="PNDACONSOLE/pndaconsole/inbound/path"
>>> to="request.url"/>
>>>       <rewrite apply="PNDACONSOLE/pndaconsole/outbound/app"
>>> to="response.body"/>
>>>     </route>
>>>
>>> My inbound rewrites, now, look like this -
>>>
>>>     <rule dir="IN" name="PNDACONSOLE/pndaconsole/inbound/root"
>>> pattern="*://*:*/**/pndaconsole/">
>>>         <rewrite template="{$serviceUrl[PNDACONSOLE]}/"/>
>>>     </rule>
>>>
>>>     <rule dir="IN" name="PNDACONSOLE/pndaconsole/inbound/socket"
>>> pattern="*://*:*/**/pndaconsole/socket.io/?{**}
>>> <http://socket.io/?%7B**%7D>">
>>>         <rewrite template="{$serviceUrl[PNDACONSOLE]}/socket.io/?{**}
>>> <http://socket.io/?%7B**%7D>"/>
>>>     </rule>
>>>
>>>     <rule dir="IN" name="PNDACONSOLE/pndaconsole/inbound/path"
>>> pattern="*://*:*/**/pndaconsole/{**}">
>>>         <rewrite template="{$serviceUrl[PNDACONSOLE]}/{**}"/>
>>>     </rule>
>>>
>>>     <rule dir="IN" name="PNDACONSOLE/pndaconsole/inbound/metrics"
>>> pattern="*://*:*/**/pndaconsole/metrics/?{**}">
>>>         <rewrite template="{$serviceUrl[PNDACONSOLE]}/metrics/?{**}"/>
>>>     </rule>
>>>
>>> The ws://...transport=websocket requests are rewritten as /, so I tried
>>> adding an entry in my topology for WEBSOCKET and an additional inbound rule
>>> like this -
>>>
>>>     <rule dir="IN" name="PNDACONSOLE/pndaconsole/inbound/socket"
>>> pattern="ws://*:*/**/pndaconsole/socket.io/?{**}
>>> <http://socket.io/?%7B**%7D>">
>>>         <rewrite template="{$serviceUrl[WEBSSOCKET]}/socket.io/?{**}
>>> <http://socket.io/?%7B**%7D>"/>
>>>     </rule>
>>>
>>> Where the topology entry is the same as PNDACONSOLE except it uses the
>>> ws:// protocol specifier. This didn't work at all, and in fact at that
>>> point, nothing got through and everything fell through to the default
>>> rewrite rule.
>>>
>>> I've attached the gateway log with debug turned on everywhere (tarballed
>>> as it's huge).
>>>
>>> I guess what I'm missing is a clear idea of what I'm supposed to do in
>>> the service/rewrite rules to deal with the websockets request which will
>>> arrive with a different protocol specifier and a different query parameter.
>>> Should I explicitly map those through to the back end, or is this something
>>> Knox handles internally?
>>>
>>> Any insight into this appreciated, it seems very close to working, and
>>> in fact socket.io does it's usual fallback so it is functional after a
>>> fashion but it seems like this should fully work given what I see with
>>> Zeppelin.
>>>
>>>
>>> Cheers,
>>> /ailuropod4
>>>
>>>
>>> On Sun, May 13, 2018 at 3:22 PM, Sandeep Moré <moresand...@gmail.com>
>>> wrote:
>>>
>>>> Hello ailuropod4
>>>>
>>>> You should not have to reroute to a different host port, this should
>>>> work.
>>>>
>>>> Looking at the responses, it looks like protocol switching happens at
>>>> the Knox end, between browser and Knox (going by the url ws://
>>>> 34.244.121.78:8443/gateway/pnda/pndaconsole/socket.io/?EIO=3&transport=websocket&sid=n_JBdgXCw_sZL-Q5AAOW)
>>>> but it should have
>>>> been wss:// wonder why this is ws://.
>>>>
>>>> Also, can you include seperate "ws" rules for your service, similar to
>>>> Zeppelin.
>>>> Also, make sure you have, inbound routes in service.xml for e.g.
>>>>
>>>>   <routes>
>>>>     <route path="/zeppelin/ws">
>>>>       <rewrite apply="ZEPPELINWS/zeppelin/ws/inbound" to="request.url"/>
>>>>     </route>
>>>>
>>>>     <route path="/zeppelin/ws**">
>>>>       <rewrite apply="ZEPPELINWS/zeppelin/inbound" to="request.url"/>
>>>>     </route>
>>>>   </routes>
>>>>
>>>> and then reference it in rewrite.xml.
>>>>
>>>> Looking at the error, it looks like the issue is not with rewrite rules
>>>> but with the connection between Knox and the backend.
>>>> We can see that Knox is initiating an upgrade request but then for some
>>>> reason the backend service is closing/refusing it.
>>>> Can you turn up the logging in Knox to Debug and share it if you can
>>>> (this should atleast tell us whether rewrite rules are working).
>>>>
>>>> Also, do you see any errors at the backend service ? it woud be good to
>>>> know what the backend is seeing and reasons for it to refuse the upgrade
>>>> and also the error code
>>>> Unfortunately the error code is gobbled up somewhere in the process.
>>>>
>>>> Best,
>>>> Sandeep
>>>>
>>>> On Sat, May 12, 2018 at 3:16 AM, T Smith <ailurop...@gmail.com> wrote:
>>>>
>>>>> And if it helps, the stack trace as a result of this from Knox follows.
>>>>>
>>>>> Can I match a url containing &transport=websocket in one of the query
>>>>> parameters and map it through to a service defined as ws:// in the
>>>>> topology? At the moment, as above, everything is sent to a http://
>>>>> service, maybe this is the crux of the problem?
>>>>>
>>>>> 2018-05-12 07:09:47,361 ERROR gateway.websockets
>>>>> (ProxyWebSocketAdapter.java:cleanupOnError(171)) - Error:
>>>>> org.eclipse.jetty.websocket.api.UpgradeException: Didn't switch protocols
>>>>> 2018-05-12 07:09:47,362 ERROR gateway.websockets
>>>>> (ProxyWebSocketAdapter.java:onWebSocketConnect(105)) - Unable to connect 
>>>>> to
>>>>> websocket server: java.io.IOException: Connect failure
>>>>> java.io.IOException: Connect failure
>>>>>         at
>>>>> org.eclipse.jetty.websocket.jsr356.ClientContainer.connect(ClientContainer.java:157)
>>>>>         at
>>>>> org.eclipse.jetty.websocket.jsr356.ClientContainer.connectToServer(ClientContainer.java:180)
>>>>>         at
>>>>> org.apache.knox.gateway.websockets.ProxyWebSocketAdapter.onWebSocketConnect(ProxyWebSocketAdapter.java:97)
>>>>>         at org.eclipse.jetty.websocket.co
>>>>> mmon.events.JettyListenerEventDriver.onConnect(JettyListenerEventDriver.java:87)
>>>>>         at org.eclipse.jetty.websocket.co
>>>>> mmon.events.AbstractEventDriver.openSession(AbstractEventDriver.java:227)
>>>>>         at org.eclipse.jetty.websocket.co
>>>>> mmon.WebSocketSession.open(WebSocketSession.java:421)
>>>>>         at org.eclipse.jetty.websocket.se
>>>>> rver.WebSocketServerConnection.onOpen(WebSocketServerConnection.java:72)
>>>>>         at org.eclipse.jetty.io
>>>>> .AbstractEndPoint.upgrade(AbstractEndPoint.java:185)
>>>>>         at
>>>>> org.eclipse.jetty.server.HttpConnection.completed(HttpConnection.java:345)
>>>>>         at
>>>>> org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:436)
>>>>>         at
>>>>> org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)
>>>>>         at org.eclipse.jetty.io
>>>>> .AbstractConnection$2.run(AbstractConnection.java:544)
>>>>>         at
>>>>> org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
>>>>>         at
>>>>> org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
>>>>>         at java.lang.Thread.run(Thread.java:748)
>>>>> Caused by: org.eclipse.jetty.websocket.api.UpgradeException: Didn't
>>>>> switch protocols
>>>>>         at org.eclipse.jetty.websocket.cl
>>>>> ient.io.UpgradeConnection.validateResponse(UpgradeConnection.java:314)
>>>>>         at org.eclipse.jetty.websocket.cl
>>>>> ient.io.UpgradeConnection.read(UpgradeConnection.java:241)
>>>>>         at org.eclipse.jetty.websocket.cl
>>>>> ient.io.UpgradeConnection.onFillable(UpgradeConnection.java:163)
>>>>>         ... 4 more
>>>>> 2018-05-12 07:09:47,373 WARN  websockets.ProxyWebSocketAdapter
>>>>> (AbstractEventDriver.java:unhandled(245)) - Unhandled Error (closing
>>>>> connection)
>>>>> org.eclipse.jetty.io.RuntimeIOException: java.io.IOException: Connect
>>>>> failure
>>>>>         at
>>>>> org.apache.knox.gateway.websockets.ProxyWebSocketAdapter.onWebSocketConnect(ProxyWebSocketAdapter.java:106)
>>>>>         at org.eclipse.jetty.websocket.co
>>>>> mmon.events.JettyListenerEventDriver.onConnect(JettyListenerEventDriver.java:87)
>>>>>         at org.eclipse.jetty.websocket.co
>>>>> mmon.events.AbstractEventDriver.openSession(AbstractEventDriver.java:227)
>>>>>         at org.eclipse.jetty.websocket.co
>>>>> mmon.WebSocketSession.open(WebSocketSession.java:421)
>>>>>         at org.eclipse.jetty.websocket.se
>>>>> rver.WebSocketServerConnection.onOpen(WebSocketServerConnection.java:72)
>>>>>         at org.eclipse.jetty.io
>>>>> .AbstractEndPoint.upgrade(AbstractEndPoint.java:185)
>>>>>         at
>>>>> org.eclipse.jetty.server.HttpConnection.completed(HttpConnection.java:345)
>>>>>         at
>>>>> org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:436)
>>>>>         at
>>>>> org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)
>>>>>         at org.eclipse.jetty.io
>>>>> .AbstractConnection$2.run(AbstractConnection.java:544)
>>>>>         at
>>>>> org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
>>>>>         at
>>>>> org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
>>>>>         at java.lang.Thread.run(Thread.java:748)
>>>>> Caused by: java.io.IOException: Connect failure
>>>>>         at
>>>>> org.eclipse.jetty.websocket.jsr356.ClientContainer.connect(ClientContainer.java:157)
>>>>>         at
>>>>> org.eclipse.jetty.websocket.jsr356.ClientContainer.connectToServer(ClientContainer.java:180)
>>>>>         at
>>>>> org.apache.knox.gateway.websockets.ProxyWebSocketAdapter.onWebSocketConnect(ProxyWebSocketAdapter.java:97)
>>>>>         ... 12 more
>>>>> Caused by: org.eclipse.jetty.websocket.api.UpgradeException: Didn't
>>>>> switch protocols
>>>>>         at org.eclipse.jetty.websocket.cl
>>>>> ient.io.UpgradeConnection.validateResponse(UpgradeConnection.java:314)
>>>>>         at org.eclipse.jetty.websocket.cl
>>>>> ient.io.UpgradeConnection.read(UpgradeConnection.java:241)
>>>>>         at org.eclipse.jetty.websocket.cl
>>>>> ient.io.UpgradeConnection.onFillable(UpgradeConnection.java:163)
>>>>>         ... 4 more
>>>>>
>>>>>
>>>>> On Fri, May 11, 2018 at 9:04 PM, T Smith <ailurop...@gmail.com> wrote:
>>>>>
>>>>>> Sorry, the other question was version. I'm using 1.0.0.
>>>>>>
>>>>>> On Fri, May 11, 2018 at 9:03 PM, T Smith <ailurop...@gmail.com>
>>>>>> wrote:
>>>>>>
>>>>>>> Hi Sandeep,
>>>>>>>
>>>>>>> Here's what's happening -
>>>>>>>
>>>>>>>
>>>>>>>    1. Request URL:
>>>>>>>
>>>>>>>    
>>>>>>> http://34.244.121.78:8443/gateway/pnda/pndaconsole/socket.io/?EIO=3&transport=polling&t=MDGlYhd
>>>>>>>    2. Request Method:
>>>>>>>    GET
>>>>>>>    3. Status Code:
>>>>>>>    200 OK
>>>>>>>
>>>>>>>
>>>>>>>    1. Request URL:
>>>>>>>    ws://
>>>>>>>    
>>>>>>> 34.244.121.78:8443/gateway/pnda/pndaconsole/socket.io/?EIO=3&transport=websocket&sid=n_JBdgXCw_sZL-Q5AAOW
>>>>>>>    2. Request Method:
>>>>>>>    GET
>>>>>>>    3. Status Code:
>>>>>>>    101 Switching Protocols
>>>>>>>
>>>>>>> So far, so good. But, the next couple of requests fail, with 400 or
>>>>>>> 500 range errors, and the gateway log complains about protocol errors. I
>>>>>>> can supply these if you need them, I'm trying to be concise here to get 
>>>>>>> the
>>>>>>> big picture across.
>>>>>>>
>>>>>>> Looking at tcpdump, what's happening is that ws:// request is being
>>>>>>> nerfed to a GET /, which on my backend happens to resolve to a nice 
>>>>>>> front
>>>>>>> page of HTML. Websockets obviously panics as this isn't what it 
>>>>>>> expected,
>>>>>>> and then the whole process repeats. On my backend, /socket.io is
>>>>>>> routed to the socket endpoint, whereas / isn't. So, my theory is that 
>>>>>>> if I
>>>>>>> can somehow convince Knox to send out the ws:// request with the correct
>>>>>>> path including /socket.io, it might work.
>>>>>>>
>>>>>>> At the moment my service/rewrite sections are very simple, I pick up
>>>>>>> requests with socket.io and send them off to the backend.
>>>>>>>
>>>>>>> services.xml -
>>>>>>>
>>>>>>>     <policies>
>>>>>>>         <policy role="webappsec"/>
>>>>>>>         <policy role="authentication" name="Anonymous"/>
>>>>>>>         <policy role="rewrite"/>
>>>>>>>         <policy role="authorization"/>
>>>>>>>     </policies>
>>>>>>>     <routes>
>>>>>>>         <route path="/pndaconsole">
>>>>>>>         </route>
>>>>>>>         <route path="/pndaconsole/**">
>>>>>>>           <rewrite apply="PNDACONSOLE/pndaconsole/outbound/app"
>>>>>>> to="response.body"/>
>>>>>>>         </route>
>>>>>>>    </routes>
>>>>>>>
>>>>>>> rewrite.xml -
>>>>>>>
>>>>>>>     <rule dir="IN" name="PNDACONSOLE/pndaconsole/inbound/root"
>>>>>>> pattern="*://*:*/**/pndaconsole/">
>>>>>>>         <rewrite template="{$serviceUrl[PNDACONSOLE]}/"/>
>>>>>>>     </rule>
>>>>>>>     <rule dir="IN" name="PNDACONSOLE/pndaconsole/inbound/socket"
>>>>>>> pattern="*://*:*/**/pndaconsole/socket.io/?{**}
>>>>>>> <http://socket.io/?%7B**%7D>">
>>>>>>>         <rewrite template="{$serviceUrl[PNDACONSOLE]}/
>>>>>>> socket.io/?{**} <http://socket.io/?%7B**%7D>"/>
>>>>>>>     </rule>
>>>>>>>     <rule dir="IN" name="PNDACONSOLE/pndaconsole/inbound/path"
>>>>>>> pattern="*://*:*/**/pndaconsole/{**}">
>>>>>>>         <rewrite template="{$serviceUrl[PNDACONSOLE]}/{**}"/>
>>>>>>>     </rule>
>>>>>>> (I've snipped the rest of the rules handling outbound rewrites as I
>>>>>>> don't believe they're relevant, but let me know if you think otherwise)
>>>>>>>
>>>>>>> By all accounts it looks like it's *nearly* working, but I'm stumped
>>>>>>> on where my /socket.io path is going. I was considering routing all
>>>>>>> websockets stuff to a completely separate backend/port so that it would 
>>>>>>> go
>>>>>>> to the right place regardless of how it was rewritten, but that seems a 
>>>>>>> bit
>>>>>>> extreme and I was hoping to use this approach.
>>>>>>>
>>>>>>> My end to end is -
>>>>>>>
>>>>>>> client, an angularjs app  --> knox --> nginx --> reverse proxied
>>>>>>> websockets backend in nodejs
>>>>>>>
>>>>>>> --> flat files, being an angularjs app
>>>>>>>
>>>>>>> We don't have to use socket.io, I guess, but it is currently used
>>>>>>> everywhere so I'd rather avoid swapping that out to get this working if
>>>>>>> possible. It's a fairly common library.
>>>>>>>
>>>>>>> Cheers,
>>>>>>>
>>>>>>> /ailuropod4 <ailurop...@gmail.com>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Fri, May 11, 2018 at 8:18 PM, Sandeep Moré <moresand...@gmail.com
>>>>>>> > wrote:
>>>>>>>
>>>>>>>> Hello,
>>>>>>>>
>>>>>>>> I am not very familiar with socket.io apps, so you might have to
>>>>>>>> fill me in about what you are trying to do.
>>>>>>>> Looks like you are having issue rewriting Websocket url.
>>>>>>>>
>>>>>>>> What version of Knox are you using ?
>>>>>>>> Knox 0.13.0 and up supports better URL rewriting, see KNOX-776
>>>>>>>> <https://issues.apache.org/jira/browse/KNOX-776>, it also has some
>>>>>>>> examples in the comments.
>>>>>>>>
>>>>>>>> What is the ws:// url you are trying to rewrite and the rules you
>>>>>>>> are using ?
>>>>>>>>
>>>>>>>> Best,
>>>>>>>> Sandeep
>>>>>>>>
>>>>>>>> On Fri, May 11, 2018 at 2:54 PM, T Smith <ailurop...@gmail.com>
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>>> Hi all,
>>>>>>>>>
>>>>>>>>> I'm struggling to get a simple socket.io based application
>>>>>>>>> working through Knox.
>>>>>>>>>
>>>>>>>>> I see websockets is supported, but the upgrade handshake seems to
>>>>>>>>> be nerfed on the way out, specifically the /socket.io/? etc part
>>>>>>>>> simply becomes /.
>>>>>>>>>
>>>>>>>>> I've tried lots of permutations - does anyone have a working
>>>>>>>>> example they can point me towards? I've looked at the Zeppelin 
>>>>>>>>> approach,
>>>>>>>>> but this isn't quite the same thing (not socket.io).
>>>>>>>>>
>>>>>>>>> Any help appreciated!
>>>>>>>>>
>>>>>>>>> /ailuropod4 <ailurop...@gmail.com>
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>

Reply via email to