question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[🐛 Bug]: Default NettyClient configuration results to frequent 407 proxy authentication failures

See original GitHub issue

What happened?

When connecting to BrowserStack via our company proxy, successful connection happens by chance, with a failure rate of 90%. Even if it managed to get a successful connection, though, after just few minutes the connection gets terminated with 407 Proxy Authentication error.

The only way I was able to solve this issue, is by replacing this part of NettyClient with a replacement code below:

Realm.Builder companyRealm = new Realm.Builder(
    System.getProperty("http.proxyUser"),
    System.getProperty("http.proxyPassword"));

companyRealm.setUsePreemptiveAuth(true)
    .setScheme(Realm.AuthScheme.BASIC)
    .setRealmName("COMPANY_AD");

ProxyServer.Builder companyProxy = new ProxyServer.Builder(
    System.getProperty("http.proxyHost"),
    Integer.parseInt(System.getProperty("http.proxyPort")));

companyProxy.setRealm(companyRealm.build());

DefaultAsyncHttpClientConfig.Builder clientConfig = new DefaultAsyncHttpClientConfig.Builder()
    .setThreadFactory(new DefaultThreadFactory("AsyncHttpClient", true))
    .setUseInsecureTrustManager(true)
    .setAggregateWebSocketFrameFragments(true)
    .setWebSocketMaxBufferSize(Integer.MAX_VALUE)
    .setWebSocketMaxFrameSize(Integer.MAX_VALUE)
    .setNettyTimer(TIMER)
    .setRequestTimeout(toClampedInt(config.readTimeout().toMillis()))
    .setConnectTimeout(toClampedInt(config.connectionTimeout().toMillis()))
    .setReadTimeout(toClampedInt(config.readTimeout().toMillis()))
    .setFollowRedirect(true)
    .setMaxRequestRetry(0)
    .setProxyServer(companyProxy.build());
return Dsl.asyncHttpClient(clientConfig.build());

There was a similar code there before which was then moved into NettyMessages. Our proxy connection is successful even without this realm and proxy setting in the NettyMessages, as long as there is realm and proxy setting in the NettyClient.

Can you please consider putting back the realm and proxy setting when instantiating an AsyncHttpClient in NettyClient? Or if it is already possible using a different method, please let me know.

How can we reproduce the issue?

This code which is similar approach to an example given here is the one that suffers from frequent 407 proxy authentication issues:

HttpCommandExecutor executor = new HttpCommandExecutor(
        MobileCommand.commandRepository,
        ClientConfig.defaultConfig()
                .baseUrl(browserstackUrl)
                .authenticateAs(new UsernameAndPassword(System.getProperty("http.proxyUser"),System.getProperty("http.proxyPassword")))
                .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(System.getProperty("http.proxyHost"), Integer.parseInt(System.getProperty("http.proxyPort"))))),
        new NettyClient.Factory()
);

The only way I can successfully connect to our proxy is through the code below in combination with the modified version of NettyClient I mentioned above.

HttpCommandExecutor executor = new HttpCommandExecutor(
        MobileCommand.commandRepository,
        browserstackUrl, 
        new ModifiedNettyClient.Factory()
);

When creating a modified NettyClient, though, I also have to create my own copy of NettyWebSocket, NettyMessages, and NettyDomainSocketClient. Therefore, it would be nice if we are able, by default, to configure the Netty (AsyncHttpClient) to contain these realm and proxy settings.

Relevant log output

Below is part of the log output when using the default NettyClient configuration; the connection was successfully started but then after few minutes it gets terminated due to 407 error - Can't handle 407 as auth was already performed

09:20:55.689 [Forwarding findElement on session 3442b80d09dbaf30a02161f714793309beb009cf to remote] DEBUG o.a.netty.request.NettyRequestSender *** Using pooled Channel '[id: 0xd1a269d4, L:/10.196.135.127:55596 - R:proxy.company/128.11.227.250:80]' for 'POST' to 'https://bsUser:bsAccessKey@hub-cloud.browserstack.com/wd/hub/session/3442b80d09dbaf30a02161f714793309beb009cf/element'
09:20:55.689 [Forwarding findElement on session 3442b80d09dbaf30a02161f714793309beb009cf to remote] DEBUG o.a.netty.request.NettyRequestSender *** Using open Channel [id: 0xd1a269d4, L:/10.196.135.127:55596 - R:proxy.company/128.11.227.250:80] for POST '/wd/hub/session/3442b80d09dbaf30a02161f714793309beb009cf/element'
09:20:55.814 [AsyncHttpClient-1-3] DEBUG o.a.netty.handler.HttpHandler ***

Request DefaultHttpRequest(decodeResult: success, version: HTTP/1.1)
POST /wd/hub/session/3442b80d09dbaf30a02161f714793309beb009cf/element HTTP/1.1
User-Agent: selenium/4.4.0 (java mac)
Content-Length: 50
Content-Type: application/json; charset=utf-8
host: hub-cloud.browserstack.com
authorization: Basic Xxxxxxx
accept: */*

Response DefaultHttpResponse(decodeResult: success, version: HTTP/1.1)
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 26 Sep 2022 08:20:55 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Source-From: 02
x-powered-by: Express
vary: X-HTTP-Method-Override
etag: W/"c7-+"
content-length: 456

09:20:55.815 [AsyncHttpClient-1-3] DEBUG o.a.netty.channel.ChannelManager *** Adding key: CompositePartitionKey(targetHostBaseUrl=https://hub-cloud.browserstack.com:443, virtualHost=null, proxyHost=proxy.company, proxyPort=80, proxyType=HTTP for channel [id: 0xd1a269d4, L:/10.196.135.127:55596 - R:proxy.company/128.11.227.250:80]
09:20:55.815 [Forwarding isElementDisplayed on session 3442b80d09dbaf30a02161f714793309beb009cf to remote] DEBUG o.a.netty.request.NettyRequestSender *** Using pooled Channel '[id: 0xd1a269d4, L:/10.196.135.127:55596 - R:proxy.company/128.11.227.250:80]' for 'GET' to 'https://bsUser:bsAccessKey@hub-cloud.browserstack.com/wd/hub/session/3442b80d09dbaf30a02161f714793309beb009cf/element/00000000-0000-0a2b-ffff-ffff00000294/displayed'
09:20:55.815 [Forwarding isElementDisplayed on session 3442b80d09dbaf30a02161f714793309beb009cf to remote] DEBUG o.a.netty.request.NettyRequestSender *** Using open Channel [id: 0xd1a269d4, L:/10.196.135.127:55596 - R:proxy.company/128.11.227.250:80] for GET '/wd/hub/session/3442b80d09dbaf30a02161f714793309beb009cf/element/00000000-0000-0a2b-ffff-ffff00000294/displayed'
09:20:55.912 [AsyncHttpClient-1-3] DEBUG o.a.netty.handler.HttpHandler ***

Request DefaultFullHttpRequest(decodeResult: success, version: HTTP/1.1, content: EmptyByteBufBE)
GET /wd/hub/session/3442b80d09dbaf30a02161f714793309beb009cf/element/00000000-0000-0a2b-ffff-ffff00000294/displayed HTTP/1.1
User-Agent: selenium/4.4.0 (java mac)
Cache-Control: no-cache
Content-Type: application/json; charset=utf-8
host: hub-cloud.browserstack.com
authorization: Basic Xxxxxxx
accept: */*

Response DefaultHttpResponse(decodeResult: success, version: HTTP/1.1)
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 26 Sep 2022 08:20:55 GMT
Content-Type: application/json; charset=utf-8
Connection: close
Source-From: 02
x-powered-by: Express
etag: W/"4c-"
content-length: 80

09:20:55.913 [AsyncHttpClient-1-3] DEBUG o.a.netty.channel.ChannelManager *** Closing Channel [id: 0xd1a269d4, L:/10.196.135.127:55596 - R:proxy.company/128.11.227.250:80]
09:20:55.913 [AsyncHttpClient-1-3] DEBUG o.a.netty.handler.HttpHandler *** Channel Closed: [id: 0xd1a269d4, L:/10.196.135.127:55596 ! R:proxy.company/128.11.227.250:80] with attribute DISCARD
09:20:55.949 [AsyncHttpClient-1-4] DEBUG o.a.n.channel.NettyConnectListener *** Using new Channel '[id: 0xec6ab2bc, L:/10.196.135.127:55608 - R:proxy.company/128.11.227.250:80]' for 'CONNECT' to 'hub-cloud.browserstack.com:443'
09:20:56.194 [AsyncHttpClient-1-4] DEBUG o.a.netty.handler.HttpHandler ***

Request DefaultFullHttpRequest(decodeResult: success, version: HTTP/1.1, content: EmptyByteBufBE)
CONNECT hub-cloud.browserstack.com:443 HTTP/1.1
user-agent: selenium/4.4.0 (java mac)
host: hub-cloud.browserstack.com
authorization: Basic Xxxxxxx
proxy-authorization: Basic Xxxxxxx
accept: */*

Response DefaultHttpResponse(decodeResult: success, version: HTTP/1.1)
HTTP/1.1 407 Proxy Authentication Required
Proxy-Authenticate: NEGOTIATE
Proxy-Authenticate: NTLM
Proxy-Authenticate: BASIC realm="COMPANY_AD"
Cache-Control: no-cache
Pragma: no-cache
X-XSS-Protection: 1
Content-Type: text/html; charset=utf-8
Proxy-Connection: close
Connection: close
content-length: 1122

09:20:56.195 [AsyncHttpClient-1-4] INFO  o.a.n.h.i.ProxyUnauthorized407Interceptor *** Can't handle 407 as auth was already performed
09:20:56.195 [AsyncHttpClient-1-4] DEBUG o.a.netty.channel.ChannelManager *** Closing Channel [id: 0xec6ab2bc, L:/10.196.135.127:55608 - R:proxy.company/128.11.227.250:80]
09:20:56.196 [AsyncHttpClient-1-4] DEBUG o.a.netty.handler.HttpHandler *** Channel Closed: [id: 0xec6ab2bc, L:/10.196.135.127:55608 ! R:proxy.company/128.11.227.250:80] with attribute DISCARD

From here on, no matter how many times it tries to re-connect, AsyncHttpClient will always throw the 407 error - Can't handle 407 as auth was already performed

Operating System

macOS Monterey

Selenium version

selenium-java 4.5.0

What are the browser(s) and version(s) where you see this issue?

Appium

What are the browser driver(s) and version(s) where you see this issue?

Appium 8.2.0

Are you using Selenium Grid?

No

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:8 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
ldiarycommented, Oct 18, 2022

@pujagani yes, I’m fine with that. Let me close this bug since a workaround is already provided as well for those who might face same issues with their proxy.

0reactions
github-actions[bot]commented, Nov 18, 2022

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How To Fix HTTP Error 407 "Proxy Authentication Required"
Errors are one of the most frustrating aspects of running a WordPress site. Some problems like HTTP Error 407 can make your content ......
Read more >
407 Proxy Authentication Required - HTTP - MDN Web Docs
The HTTP 407 Proxy Authentication Required client error status response code indicates that the request has not been applied because it ...
Read more >
1929247 – HTTP proxy with authentication fails with 407
Bug 1929247 - HTTP proxy with authentication fails with 407 ... 407 "Proxy Authentication Required" ~~~ Expected results: Test to be a ...
Read more >
What is a 407 Proxy Authentication Required - Airbrake Blog
Server- or Client-Side? All HTTP response status codes that are in the 4xx category are considered client error responses . Errors in the...
Read more >
Dealing with 407 Proxy Authentication Required errors using ...
It's odd that it is working intermittently and that opening IE resolves the issue. That implies that the .NET code is picking up...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found