Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Websocket does not support NTLM proxy #1274

Closed
stonecai opened this issue Oct 12, 2016 · 16 comments
Closed

Websocket does not support NTLM proxy #1274

stonecai opened this issue Oct 12, 2016 · 16 comments
Labels
Milestone

Comments

@stonecai
Copy link

stonecai commented Oct 12, 2016

With latest version (2.1.0-alpha1), As the following codes, it works fine while connectiong to server with http; but it is failed for websocket, it alway returns 501 status code. does asynch-http-client support the proxy with NTML schema?

Scenario 1: connecting www.google.com, connection established

String url="http://www.google.com";
DefaultAsyncHttpClientConfig.Builder configBuilder = new DefaultAsyncHttpClientConfig.Builder();
configBuilder.setWebSocketMaxFrameSize(WEBSOCKET_MAX_FRAME_SIZE);
boolean isWss = SSLConfigurationUtil.isWssConnection(url);
setProxyConfig(configBuilder);
AsyncHttpClientConfig cf = configBuilder.build();
client = new DefaultAsyncHttpClient(cf);
Future<Response> responseFuture = client.prepareGet(url).execute();
int status = responseFuture.get().getStatusCode(); //status ==200, success

Scenario 2: connecting to websocket, failed. return 501 status code

String url="ws://192.168.1.100/hello";
DefaultAsyncHttpClientConfig.Builder configBuilder = new DefaultAsyncHttpClientConfig.Builder();
configBuilder.setWebSocketMaxFrameSize(WEBSOCKET_MAX_FRAME_SIZE);
boolean isWss = SSLConfigurationUtil.isWssConnection(url);
setProxyConfig(configBuilder);
AsyncHttpClientConfig cf = configBuilder.build();
client = new DefaultAsyncHttpClient(cf);
WebSocketUpgradeHandler.Builder wsHandlerBuilder = new WebSocketUpgradeHandler.Builder();
wsHandlerBuilder.addWebSocketListener(new NettyWebSocketByteListener());
WebSocketUpgradeHandler upgradeHandler = wsHandlerBuilder.build();
WebSocket session = client.prepareGet(url).execute(upgradeHandler).get(); //Invalid Status Code 501
private void setProxyConfig(Builder configBuilder) {
    try {
        ProxyServer.Builder psBuilder = new ProxyServer.Builder(proxyHost, Integer.valueOf(proxyPort));

        Realm.Builder realmBuilder = new Realm.Builder(proxyUsername, proxyPassword);
        realmBuilder.setUsePreemptiveAuth(true);
        realmBuilder.setNtlmDomain(proxyUserDomain);
        realmBuilder.setNtlmHost(proxyHost);
        realmBuilder.setScheme(AuthScheme.NTLM);
        Realm realm = realmBuilder.build();
        psBuilder.setRealm(realm);

        ProxyServer proxyServer = psBuilder.build();
        configBuilder.setProxyServer(proxyServer);
    } catch (Exception e) {
        log.error(e.getMessage(), e);
    }
}
@slandelle
Copy link
Contributor

does asynch-http-client support the proxy with NTML schema?

Yes, it's supposed to. But NTLM support might not be bullet-proof, as I can't get my hands on such environment.
Honestly, the best way to get this right is to investigate it yourself.

@stonecai
Copy link
Author

Thanks slandelle!
If I use the CONNECT method. That is something like client.prepareConnect(), then it can route to the websocket server success. But unfortunately websocket seems only support GET method, the 405 status code returned.

@slandelle
Copy link
Contributor

Do you have any idea how I could easily get a NTLM proxy running (without a Windows host)?

@stonecai
Copy link
Author

Hi @slandelle, we hava a NTLM server in internal network for testing. Currently I can not find a NTLM proxy can be reached on the internet.

@stonecai
Copy link
Author

Might I ask one more question? WebSocketUpgradeHandler in asynch-http-client requires CONNECT or GET method; According to the information from RFC (https://tools.ietf.org/html/rfc6455), the method of the WEBSOCKET request MUST be GET. So is there a way to use CONNECT for negotiating with NTLM proxy then use GET for WEBSOCKET in asynchttpclient?

@slandelle
Copy link
Contributor

According to the information from RFC (https://tools.ietf.org/html/rfc6455), the method of the WEBSOCKET request MUST be GET.

Read 4.1.3, client must perform a CONNECT when connecting through a proxy.

Currently I can not find a NTLM proxy can be reached on the internet.

Me neither. Nor a virtual box or docker image. NTLM is an entreprisey thingy, and sadly entreprises tend to rarely share. Except if I can get my hands on an NTLM environment, I won't be able to investigate this myself without a contract.

@stonecai
Copy link
Author

Hi slandelle, thanks for the update.
After degrading the version from 2.1.0-alpha1 to 2.0.14, use wss instead of ws, the websocket can go through the proxy and connect to server successful. It might be some bugs within websocket in version 2.1.0-alpha1 but I can not identify it. We will keep investigating on it and provide the update if any finding. Thank you.

@slandelle
Copy link
Contributor

use wss instead of ws

CONNECT is used for HTTP proxy tunneling, ie HTTS. You use a different path in the code. I don't think the fact that it works now has anything to do with downgrading.

@potatop
Copy link

potatop commented Oct 4, 2018

commit d596056 seems to have broken ntlm proxy.

@potatop
Copy link

potatop commented Oct 4, 2018

Changing

if (attribute instanceof OnLastHttpContentCallback && msg instanceof LastHttpContent) {
    ((OnLastHttpContentCallback) attribute).call();
}

to

if (attribute instanceof OnLastHttpContentCallback) {
    if (msg instanceof LastHttpContent) {
        ((OnLastHttpContentCallback) attribute).call();
    }
}

fix the problem

@slandelle
Copy link
Contributor

??? Both are absolutely identical!!!

@slandelle
Copy link
Contributor

Ah, ok, there's a second branch that is missing from your code.

@potatop
Copy link

potatop commented Oct 4, 2018

when msg is DefaultHttpContent and not LastHttpContent the channel is closed by the last if else.

@slandelle slandelle added this to the 2.5.4 milestone Oct 4, 2018
@slandelle
Copy link
Contributor

Thanks!

@potatop
Copy link

potatop commented Oct 4, 2018

Wow, that was fast. Thank you!

Will this be back ported to the 2.0 branch, and do you know when the next release is going to be?

@slandelle
Copy link
Contributor

Will this be back ported to the 2.0 branch

No. I don't do backports, and anyway, AHC 2.0 is based on Netty 4.0 which is EOL'ed too.

do you know when the next release is going to be?

Maybe today

anexplore added a commit to anexplore/async-http-client that referenced this issue Oct 10, 2018
…p-client

* 'master' of https://github.com/AsyncHttpClient/async-http-client:
  [maven-release-plugin] prepare for next development iteration
  [maven-release-plugin] prepare release async-http-client-project-2.5.4
  Upgrade netty 4.1.30.Final
  HttpContentDecompressor is misplaced after upgrading pipeline for HTTP tunnelling, close AsyncHttpClient#1583
  Fix regression introduced in d596056, close AsyncHttpClient#1274
  [maven-release-plugin] prepare for next development iteration
  [maven-release-plugin] prepare release async-http-client-project-2.5.3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants