问:
SSL Handshake failure with TLSv1 by using Java 6, HTMLUnit and Bouncy Castle
I am trying to connect SSL site https://link.bollore-logistics.com by using Java 6 and HTMLUnit, I have added more supported Ciphers by using Bouncy Castle. But still, I am receiving handshake failure. I cannot upgrade Java version due to production limitation. Please kindly help

Code of configuration:

```<code>HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    });

    if (Security.getProvider("BC") == null){
        logger.info("Bouncy Castle provider is NOT available");
    }
    else{
        logger.info("Bouncy Castle provider is available");
    }

    Provider provider = new BouncyCastleProvider();
    Security.addProvider(provider);

    SSLContext context = SSLContext.getInstance("SSL");

    context.init(null, new X509TrustManager[]{new X509TrustManager() {

        @Override
        public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    }}, new SecureRandom());

    String[] scs = context.getSocketFactory().getSupportedCipherSuites();
    Arrays.sort(scs);

    for(String s : scs) {
        System.out.println(s);
     }
    HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());

    // Create all-trusting host name verifier
    HostnameVerifier allHostsValid = new HostnameVerifier() {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };
    HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
</code>```

Code to make connection (HTMLUnit):

```<code>WebClient webClient = new WebClient(BrowserVersion.CHROME);
webClient.getOptions().setUseInsecureSSL(true);
webClient.getOptions().setRedirectEnabled(true);
webClient.getOptions().setThrowExceptionOnScriptError(false);
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(true);
webClient.getPage(url);
</code>```

Here is the error log:

```<code>2017-12-06 11:27:40 DEBUG WebClient:325 - Get page for window named '', using WebRequest[<url="http://link.bollore-logistics.com/Contact/SmartSearch/77707575", GET, EncodingType[name=application/x-www-form-urlencoded], [], {Accept-Encoding=gzip, deflate, Accept=*/*}, null>]
2017-12-06 11:27:40 DEBUG WebClient:1259 - Load response for GET http://link.bollore-logistics.com/Contact/SmartSearch/77707575
trigger seeding of SecureRandom
done seeding SecureRandom
2017-12-06 11:27:40 DEBUG RequestAddCookies:122 - CookieSpec selected: mine
2017-12-06 11:27:40 DEBUG RequestAuthCache:76 - Auth cache not set in the context
2017-12-06 11:27:40 DEBUG PoolingHttpClientConnectionManager:249 - Connection request: [route: {}->http://link.bollore-logistics.com:80][total kept alive: 0; route allocated: 0 of 6; total allocated: 0 of 20]
2017-12-06 11:27:40 DEBUG PoolingHttpClientConnectionManager:282 - Connection leased: [id: 0][route: {}->http://link.bollore-logistics.com:80][total kept alive: 0; route allocated: 1 of 6; total allocated: 1 of 20]
2017-12-06 11:27:40 DEBUG MainClientExec:234 - Opening connection {}->http://link.bollore-logistics.com:80
2017-12-06 11:27:40 DEBUG DefaultHttpClientConnectionOperator:131 - Connecting to link.bollore-logistics.com/195.101.158.66:80
2017-12-06 11:27:40 DEBUG DefaultHttpClientConnectionOperator:138 - Connection established 192.168.171.168:52556<->195.101.158.66:80
2017-12-06 11:27:40 DEBUG MainClientExec:255 - Executing request GET /Contact/SmartSearch/77707575 HTTP/1.1
2017-12-06 11:27:40 DEBUG MainClientExec:260 - Target auth state: UNCHALLENGED
2017-12-06 11:27:40 DEBUG MainClientExec:266 - Proxy auth state: UNCHALLENGED
2017-12-06 11:27:40 DEBUG headers:124 - http-outgoing-0 >> GET /Contact/SmartSearch/77707575 HTTP/1.1
2017-12-06 11:27:40 DEBUG headers:127 - http-outgoing-0 >> Host: link.bollore-logistics.com
2017-12-06 11:27:40 DEBUG headers:127 - http-outgoing-0 >> User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
2017-12-06 11:27:40 DEBUG headers:127 - http-outgoing-0 >> Accept-Language: en-US
2017-12-06 11:27:40 DEBUG headers:127 - http-outgoing-0 >> Accept-Encoding: gzip, deflate
2017-12-06 11:27:40 DEBUG headers:127 - http-outgoing-0 >> Accept: */*
2017-12-06 11:27:40 DEBUG headers:127 - http-outgoing-0 >> Connection: Keep-Alive
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "GET /Contact/SmartSearch/77707575 HTTP/1.1[\r][\n]"
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "Host: link.bollore-logistics.com[\r][\n]"
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36[\r][\n]"
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "Accept-Language: en-US[\r][\n]"
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "Accept-Encoding: gzip, deflate[\r][\n]"
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "Accept: */*[\r][\n]"
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]"
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "[\r][\n]"
2017-12-06 11:27:41 DEBUG wire:72 - http-outgoing-0 << "HTTP/1.0 302 Found[\r][\n]"
2017-12-06 11:27:41 DEBUG wire:72 - http-outgoing-0 << "Location: https://link.bollore-logistics.com/Contact/SmartSearch/77707575[\r][\n]"
2017-12-06 11:27:41 DEBUG wire:72 - http-outgoing-0 << "Server: BigIP[\r][\n]"
2017-12-06 11:27:41 DEBUG wire:72 - http-outgoing-0 << "Connection: Keep-Alive[\r][\n]"
2017-12-06 11:27:41 DEBUG wire:72 - http-outgoing-0 << "Content-Length: 0[\r][\n]"
2017-12-06 11:27:41 DEBUG wire:72 - http-outgoing-0 << "[\r][\n]"
2017-12-06 11:27:41 DEBUG headers:113 - http-outgoing-0 << HTTP/1.0 302 Found
2017-12-06 11:27:41 DEBUG headers:116 - http-outgoing-0 << Location: https://link.bollore-logistics.com/Contact/SmartSearch/77707575
2017-12-06 11:27:41 DEBUG headers:116 - http-outgoing-0 << Server: BigIP
2017-12-06 11:27:41 DEBUG headers:116 - http-outgoing-0 << Connection: Keep-Alive
2017-12-06 11:27:41 DEBUG headers:116 - http-outgoing-0 << Content-Length: 0
2017-12-06 11:27:41 DEBUG MainClientExec:284 - Connection can be kept alive indefinitely
2017-12-06 11:27:41 DEBUG PoolingHttpClientConnectionManager:314 - Connection [id: 0][route: {}->http://link.bollore-logistics.com:80] can be kept alive indefinitely
2017-12-06 11:27:41 DEBUG PoolingHttpClientConnectionManager:320 - Connection released: [id: 0][route: {}->http://link.bollore-logistics.com:80][total kept alive: 1; route allocated: 1 of 6; total allocated: 1 of 20]
2017-12-06 11:27:41 DEBUG WebClient:1349 - Got a redirect status code [302] new location = [https://link.bollore-logistics.com/Contact/SmartSearch/77707575]
2017-12-06 11:27:41 DEBUG WebClient:1259 - Load response for GET https://link.bollore-logistics.com/Contact/SmartSearch/77707575
2017-12-06 11:27:41 DEBUG RequestAddCookies:122 - CookieSpec selected: mine
2017-12-06 11:27:41 DEBUG RequestAuthCache:76 - Auth cache not set in the context
2017-12-06 11:27:41 DEBUG PoolingHttpClientConnectionManager:249 - Connection request: [route: {s}->https://link.bollore-logistics.com:443][total kept alive: 1; route allocated: 0 of 6; total allocated: 1 of 20]
2017-12-06 11:27:41 DEBUG PoolingHttpClientConnectionManager:282 - Connection leased: [id: 1][route: {s}->https://link.bollore-logistics.com:443][total kept alive: 1; route allocated: 1 of 6; total allocated: 2 of 20]
2017-12-06 11:27:41 DEBUG MainClientExec:234 - Opening connection {s}->https://link.bollore-logistics.com:443
2017-12-06 11:27:41 DEBUG DefaultHttpClientConnectionOperator:131 - Connecting to link.bollore-logistics.com/195.101.158.66:443
2017-12-06 11:27:41 DEBUG HtmlUnitSSLConnectionSocketFactory:335 - Connecting socket to link.bollore-logistics.com/195.101.158.66:443 with timeout 90000
2017-12-06 11:27:41 DEBUG HtmlUnitSSLConnectionSocketFactory:388 - Enabled protocols: [TLSv1]
2017-12-06 11:27:41 DEBUG HtmlUnitSSLConnectionSocketFactory:389 - Enabled cipher suites:[SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA]
2017-12-06 11:27:41 DEBUG HtmlUnitSSLConnectionSocketFactory:393 - Starting handshake
%% No cached client session
*** ClientHello, TLSv1
RandomCookie:  GMT: 1512530605 bytes = { 147, 117, 177, 152, 172, 87, 109, 103, 219, 130, 24, 140, 216, 108, 154, 3, 162, 211, 205, 89, 29, 221, 91, 103, 85, 39, 206, 187 }
Session ID:  {}
Cipher Suites: [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
***
[write] MD5 and SHA1 hashes:  len = 161
0000: 01 00 00 9D 03 01 5A 27   63 AD 93 75 B1 98 AC 57  ......Z'c..u...W
0010: 6D 67 DB 82 18 8C D8 6C   9A 03 A2 D3 CD 59 1D DD  mg.....l.....Y..
0020: 5B 67 55 27 CE BB 00 00   36 00 04 00 05 00 2F C0  [gU'....6...../.
0030: 02 C0 04 C0 0C C0 0E C0   07 C0 09 C0 11 C0 13 00  ................
0040: 33 00 32 00 0A C0 03 C0   0D C0 08 C0 12 00 16 00  3.2.............
0050: 13 00 09 00 15 00 12 00   03 00 08 00 14 00 11 01  ................
0060: 00 00 3E 00 0A 00 34 00   32 00 17 00 01 00 03 00  ..>...4.2.......
0070: 13 00 15 00 06 00 07 00   09 00 0A 00 18 00 0B 00  ................
0080: 0C 00 19 00 0D 00 0E 00   0F 00 10 00 11 00 02 00  ................
0090: 12 00 04 00 05 00 14 00   08 00 16 00 0B 00 02 01  ................
00A0: 00                                                 .
http-bio-8080-exec-3, WRITE: TLSv1 Handshake, length = 161
[Raw write]: length = 166
0000: 16 03 01 00 A1 01 00 00   9D 03 01 5A 27 63 AD 93  ...........Z'c..
0010: 75 B1 98 AC 57 6D 67 DB   82 18 8C D8 6C 9A 03 A2  u...Wmg.....l...
0020: D3 CD 59 1D DD 5B 67 55   27 CE BB 00 00 36 00 04  ..Y..[gU'....6..
0030: 00 05 00 2F C0 02 C0 04   C0 0C C0 0E C0 07 C0 09  .../............
0040: C0 11 C0 13 00 33 00 32   00 0A C0 03 C0 0D C0 08  .....3.2........
0050: C0 12 00 16 00 13 00 09   00 15 00 12 00 03 00 08  ................
0060: 00 14 00 11 01 00 00 3E   00 0A 00 34 00 32 00 17  .......>...4.2..
0070: 00 01 00 03 00 13 00 15   00 06 00 07 00 09 00 0A  ................
0080: 00 18 00 0B 00 0C 00 19   00 0D 00 0E 00 0F 00 10  ................
0090: 00 11 00 02 00 12 00 04   00 05 00 14 00 08 00 16  ................
00A0: 00 0B 00 02 01 00                                  ......
[Raw read]: length = 5
0000: 15 03 01 00 02                                     .....
[Raw read]: length = 2
0000: 02 28                                              .(
http-bio-8080-exec-3, READ: TLSv1 Alert, length = 2
http-bio-8080-exec-3, RECV TLSv1 ALERT:  fatal, handshake_failure
http-bio-8080-exec-3, called closeSocket()
http-bio-8080-exec-3, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
2017-12-06 11:27:41 DEBUG DefaultManagedHttpClientConnection:87 - http-outgoing-1: Shutdown connection
2017-12-06 11:27:41 DEBUG MainClientExec:128 - Connection discarded
2017-12-06 11:27:41 DEBUG DefaultManagedHttpClientConnection:79 - http-outgoing-1: Close connection
2017-12-06 11:27:41 DEBUG PoolingHttpClientConnectionManager:320 - Connection released: [id: 1][route: {s}->https://link.bollore-logistics.com:443][total kept alive: 1; route allocated: 0 of 6; total allocated: 1 of 20]
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1694)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:939)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1120)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1147)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1131)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:394)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:353)
    at com.gargoylesoftware.htmlunit.HtmlUnitSSLConnectionSocketFactory.connectSocket(HtmlUnitSSLConnectionSocketFactory.java:155)
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:134)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353)
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:71)
    at com.gargoylesoftware.htmlunit.HttpWebConnection.getResponse(HttpWebConnection.java:178)
    at com.gargoylesoftware.htmlunit.WebClient.loadWebResponseFromWebConnection(WebClient.java:1313)
    at com.gargoylesoftware.htmlunit.WebClient.loadWebResponseFromWebConnection(WebClient.java:1371)
    at com.gargoylesoftware.htmlunit.WebClient.loadWebResponse(WebClient.java:1230)
    at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:338)
    at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:407)
    at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:392)
    at com.grabber.Grabber.accessWebpage(Grabber.java:204)
    at com.grabber.Grabber.doGet(Grabber.java:53)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:218)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:110)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:506)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:962)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:445)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1087)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:619)
</code>```

答:
Assuming Sun/Oracle Java 6, since you didn't say IBM (which implements crypto differently):

Your problem is not ciphers (which BC-provider could fix only if the problem was lack of ECC ciphers), nor protocols. https://www.ssllabs.com/ssltest/analyze.html?d=link.bollore-logistics.com shows that server accepts ciphers and protocols that Java 6 could do without any augmentation.

Your problem is SNI (Server Name Indication). The ssllabs report shows that the only simulated clients that fail are the ones that don't send SNI (Android 2, Windows XP, Java 6) and a simple test with openssl confirms the server requires SNI. Java 6 JSSE did not implement SNI.

It might work to use the BC version of JSSE -- this is a separate jar bctls-jdk15on-$ver not bcprov-jdk15on-$ver and providername BCJSSE not BC. In the most recent versions (1.57 and 1.58) according to the source it appears to me the client should do SNI by default, if you connect using a domainname (not IPaddress or local alias). However I can't verify because I can't get BCJSSE to instantiate at all due to some problem with SecureRandom that I don't have time now to track down.

Body:
I am trying to connect SSL site https://link.bollore-logistics.com by using Java 6 and HTMLUnit, I have added more supported Ciphers by using Bouncy Castle. But still, I am receiving handshake failure. I cannot upgrade Java version due to production limitation. Please kindly help

Code of configuration:

HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    });

    if (Security.getProvider("BC") == null){
        logger.info("Bouncy Castle provider is NOT available");
    }
    else{
        logger.info("Bouncy Castle provider is available");
    }

    Provider provider = new BouncyCastleProvider();
    Security.addProvider(provider);

    SSLContext context = SSLContext.getInstance("SSL");

    context.init(null, new X509TrustManager[]{new X509TrustManager() {

        @Override
        public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    }}, new SecureRandom());

    String[] scs = context.getSocketFactory().getSupportedCipherSuites();
    Arrays.sort(scs);

    for(String s : scs) {
        System.out.println(s);
     }
    HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());

    // Create all-trusting host name verifier
    HostnameVerifier allHostsValid = new HostnameVerifier() {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };
    HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);

Code to make connection (HTMLUnit):

WebClient webClient = new WebClient(BrowserVersion.CHROME);
webClient.getOptions().setUseInsecureSSL(true);
webClient.getOptions().setRedirectEnabled(true);
webClient.getOptions().setThrowExceptionOnScriptError(false);
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(true);
webClient.getPage(url);

Here is the error log:

2017-12-06 11:27:40 DEBUG WebClient:325 - Get page for window named '', using WebRequest[<url="http://link.bollore-logistics.com/Contact/SmartSearch/77707575", GET, EncodingType[name=application/x-www-form-urlencoded], [], {Accept-Encoding=gzip, deflate, Accept=*/*}, null>]
2017-12-06 11:27:40 DEBUG WebClient:1259 - Load response for GET http://link.bollore-logistics.com/Contact/SmartSearch/77707575
trigger seeding of SecureRandom
done seeding SecureRandom
2017-12-06 11:27:40 DEBUG RequestAddCookies:122 - CookieSpec selected: mine
2017-12-06 11:27:40 DEBUG RequestAuthCache:76 - Auth cache not set in the context
2017-12-06 11:27:40 DEBUG PoolingHttpClientConnectionManager:249 - Connection request: [route: {}->http://link.bollore-logistics.com:80][total kept alive: 0; route allocated: 0 of 6; total allocated: 0 of 20]
2017-12-06 11:27:40 DEBUG PoolingHttpClientConnectionManager:282 - Connection leased: [id: 0][route: {}->http://link.bollore-logistics.com:80][total kept alive: 0; route allocated: 1 of 6; total allocated: 1 of 20]
2017-12-06 11:27:40 DEBUG MainClientExec:234 - Opening connection {}->http://link.bollore-logistics.com:80
2017-12-06 11:27:40 DEBUG DefaultHttpClientConnectionOperator:131 - Connecting to link.bollore-logistics.com/195.101.158.66:80
2017-12-06 11:27:40 DEBUG DefaultHttpClientConnectionOperator:138 - Connection established 192.168.171.168:52556<->195.101.158.66:80
2017-12-06 11:27:40 DEBUG MainClientExec:255 - Executing request GET /Contact/SmartSearch/77707575 HTTP/1.1
2017-12-06 11:27:40 DEBUG MainClientExec:260 - Target auth state: UNCHALLENGED
2017-12-06 11:27:40 DEBUG MainClientExec:266 - Proxy auth state: UNCHALLENGED
2017-12-06 11:27:40 DEBUG headers:124 - http-outgoing-0 >> GET /Contact/SmartSearch/77707575 HTTP/1.1
2017-12-06 11:27:40 DEBUG headers:127 - http-outgoing-0 >> Host: link.bollore-logistics.com
2017-12-06 11:27:40 DEBUG headers:127 - http-outgoing-0 >> User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
2017-12-06 11:27:40 DEBUG headers:127 - http-outgoing-0 >> Accept-Language: en-US
2017-12-06 11:27:40 DEBUG headers:127 - http-outgoing-0 >> Accept-Encoding: gzip, deflate
2017-12-06 11:27:40 DEBUG headers:127 - http-outgoing-0 >> Accept: */*
2017-12-06 11:27:40 DEBUG headers:127 - http-outgoing-0 >> Connection: Keep-Alive
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "GET /Contact/SmartSearch/77707575 HTTP/1.1[\r][\n]"
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "Host: link.bollore-logistics.com[\r][\n]"
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36[\r][\n]"
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "Accept-Language: en-US[\r][\n]"
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "Accept-Encoding: gzip, deflate[\r][\n]"
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "Accept: */*[\r][\n]"
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]"
2017-12-06 11:27:40 DEBUG wire:72 - http-outgoing-0 >> "[\r][\n]"
2017-12-06 11:27:41 DEBUG wire:72 - http-outgoing-0 << "HTTP/1.0 302 Found[\r][\n]"
2017-12-06 11:27:41 DEBUG wire:72 - http-outgoing-0 << "Location: https://link.bollore-logistics.com/Contact/SmartSearch/77707575[\r][\n]"
2017-12-06 11:27:41 DEBUG wire:72 - http-outgoing-0 << "Server: BigIP[\r][\n]"
2017-12-06 11:27:41 DEBUG wire:72 - http-outgoing-0 << "Connection: Keep-Alive[\r][\n]"
2017-12-06 11:27:41 DEBUG wire:72 - http-outgoing-0 << "Content-Length: 0[\r][\n]"
2017-12-06 11:27:41 DEBUG wire:72 - http-outgoing-0 << "[\r][\n]"
2017-12-06 11:27:41 DEBUG headers:113 - http-outgoing-0 << HTTP/1.0 302 Found
2017-12-06 11:27:41 DEBUG headers:116 - http-outgoing-0 << Location: https://link.bollore-logistics.com/Contact/SmartSearch/77707575
2017-12-06 11:27:41 DEBUG headers:116 - http-outgoing-0 << Server: BigIP
2017-12-06 11:27:41 DEBUG headers:116 - http-outgoing-0 << Connection: Keep-Alive
2017-12-06 11:27:41 DEBUG headers:116 - http-outgoing-0 << Content-Length: 0
2017-12-06 11:27:41 DEBUG MainClientExec:284 - Connection can be kept alive indefinitely
2017-12-06 11:27:41 DEBUG PoolingHttpClientConnectionManager:314 - Connection [id: 0][route: {}->http://link.bollore-logistics.com:80] can be kept alive indefinitely
2017-12-06 11:27:41 DEBUG PoolingHttpClientConnectionManager:320 - Connection released: [id: 0][route: {}->http://link.bollore-logistics.com:80][total kept alive: 1; route allocated: 1 of 6; total allocated: 1 of 20]
2017-12-06 11:27:41 DEBUG WebClient:1349 - Got a redirect status code [302] new location = [https://link.bollore-logistics.com/Contact/SmartSearch/77707575]
2017-12-06 11:27:41 DEBUG WebClient:1259 - Load response for GET https://link.bollore-logistics.com/Contact/SmartSearch/77707575
2017-12-06 11:27:41 DEBUG RequestAddCookies:122 - CookieSpec selected: mine
2017-12-06 11:27:41 DEBUG RequestAuthCache:76 - Auth cache not set in the context
2017-12-06 11:27:41 DEBUG PoolingHttpClientConnectionManager:249 - Connection request: [route: {s}->https://link.bollore-logistics.com:443][total kept alive: 1; route allocated: 0 of 6; total allocated: 1 of 20]
2017-12-06 11:27:41 DEBUG PoolingHttpClientConnectionManager:282 - Connection leased: [id: 1][route: {s}->https://link.bollore-logistics.com:443][total kept alive: 1; route allocated: 1 of 6; total allocated: 2 of 20]
2017-12-06 11:27:41 DEBUG MainClientExec:234 - Opening connection {s}->https://link.bollore-logistics.com:443
2017-12-06 11:27:41 DEBUG DefaultHttpClientConnectionOperator:131 - Connecting to link.bollore-logistics.com/195.101.158.66:443
2017-12-06 11:27:41 DEBUG HtmlUnitSSLConnectionSocketFactory:335 - Connecting socket to link.bollore-logistics.com/195.101.158.66:443 with timeout 90000
2017-12-06 11:27:41 DEBUG HtmlUnitSSLConnectionSocketFactory:388 - Enabled protocols: [TLSv1]
2017-12-06 11:27:41 DEBUG HtmlUnitSSLConnectionSocketFactory:389 - Enabled cipher suites:[SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA]
2017-12-06 11:27:41 DEBUG HtmlUnitSSLConnectionSocketFactory:393 - Starting handshake
%% No cached client session
*** ClientHello, TLSv1
RandomCookie:  GMT: 1512530605 bytes = { 147, 117, 177, 152, 172, 87, 109, 103, 219, 130, 24, 140, 216, 108, 154, 3, 162, 211, 205, 89, 29, 221, 91, 103, 85, 39, 206, 187 }
Session ID:  {}
Cipher Suites: [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
***
[write] MD5 and SHA1 hashes:  len = 161
0000: 01 00 00 9D 03 01 5A 27   63 AD 93 75 B1 98 AC 57  ......Z'c..u...W
0010: 6D 67 DB 82 18 8C D8 6C   9A 03 A2 D3 CD 59 1D DD  mg.....l.....Y..
0020: 5B 67 55 27 CE BB 00 00   36 00 04 00 05 00 2F C0  [gU'....6...../.
0030: 02 C0 04 C0 0C C0 0E C0   07 C0 09 C0 11 C0 13 00  ................
0040: 33 00 32 00 0A C0 03 C0   0D C0 08 C0 12 00 16 00  3.2.............
0050: 13 00 09 00 15 00 12 00   03 00 08 00 14 00 11 01  ................
0060: 00 00 3E 00 0A 00 34 00   32 00 17 00 01 00 03 00  ..>...4.2.......
0070: 13 00 15 00 06 00 07 00   09 00 0A 00 18 00 0B 00  ................
0080: 0C 00 19 00 0D 00 0E 00   0F 00 10 00 11 00 02 00  ................
0090: 12 00 04 00 05 00 14 00   08 00 16 00 0B 00 02 01  ................
00A0: 00                                                 .
http-bio-8080-exec-3, WRITE: TLSv1 Handshake, length = 161
[Raw write]: length = 166
0000: 16 03 01 00 A1 01 00 00   9D 03 01 5A 27 63 AD 93  ...........Z'c..
0010: 75 B1 98 AC 57 6D 67 DB   82 18 8C D8 6C 9A 03 A2  u...Wmg.....l...
0020: D3 CD 59 1D DD 5B 67 55   27 CE BB 00 00 36 00 04  ..Y..[gU'....6..
0030: 00 05 00 2F C0 02 C0 04   C0 0C C0 0E C0 07 C0 09  .../............
0040: C0 11 C0 13 00 33 00 32   00 0A C0 03 C0 0D C0 08  .....3.2........
0050: C0 12 00 16 00 13 00 09   00 15 00 12 00 03 00 08  ................
0060: 00 14 00 11 01 00 00 3E   00 0A 00 34 00 32 00 17  .......>...4.2..
0070: 00 01 00 03 00 13 00 15   00 06 00 07 00 09 00 0A  ................
0080: 00 18 00 0B 00 0C 00 19   00 0D 00 0E 00 0F 00 10  ................
0090: 00 11 00 02 00 12 00 04   00 05 00 14 00 08 00 16  ................
00A0: 00 0B 00 02 01 00                                  ......
[Raw read]: length = 5
0000: 15 03 01 00 02                                     .....
[Raw read]: length = 2
0000: 02 28                                              .(
http-bio-8080-exec-3, READ: TLSv1 Alert, length = 2
http-bio-8080-exec-3, RECV TLSv1 ALERT:  fatal, handshake_failure
http-bio-8080-exec-3, called closeSocket()
http-bio-8080-exec-3, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
2017-12-06 11:27:41 DEBUG DefaultManagedHttpClientConnection:87 - http-outgoing-1: Shutdown connection
2017-12-06 11:27:41 DEBUG MainClientExec:128 - Connection discarded
2017-12-06 11:27:41 DEBUG DefaultManagedHttpClientConnection:79 - http-outgoing-1: Close connection
2017-12-06 11:27:41 DEBUG PoolingHttpClientConnectionManager:320 - Connection released: [id: 1][route: {s}->https://link.bollore-logistics.com:443][total kept alive: 1; route allocated: 0 of 6; total allocated: 1 of 20]
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1694)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:939)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1120)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1147)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1131)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:394)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:353)
    at com.gargoylesoftware.htmlunit.HtmlUnitSSLConnectionSocketFactory.connectSocket(HtmlUnitSSLConnectionSocketFactory.java:155)
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:134)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353)
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:71)
    at com.gargoylesoftware.htmlunit.HttpWebConnection.getResponse(HttpWebConnection.java:178)
    at com.gargoylesoftware.htmlunit.WebClient.loadWebResponseFromWebConnection(WebClient.java:1313)
    at com.gargoylesoftware.htmlunit.WebClient.loadWebResponseFromWebConnection(WebClient.java:1371)
    at com.gargoylesoftware.htmlunit.WebClient.loadWebResponse(WebClient.java:1230)
    at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:338)
    at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:407)
    at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:392)
    at com.grabber.Grabber.accessWebpage(Grabber.java:204)
    at com.grabber.Grabber.doGet(Grabber.java:53)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:218)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:110)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:506)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:962)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:445)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1087)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:619)


来源: stackexchange

问:
implementing operator * in C++
```<code>class Rational {

 const Rational operator*(const Rational& rhs) const

  ...
};

 Rational oneHalf(1,2);

 Rational result = oneHalf * 2;   // fine (with non-explicit ctor)
 result          = 2 * oneHalf;  // error! (even with non-explicit ctor)
</code>```

It was mentioned by scott meyers in Effective C++ book as below

Even when Rationl's constructor is not explicit, one compiles and one doesnot. Reason is given as below:

It turns out that parameters are eligible for implicit conversion "only if they are listed in the parameter list".

The implicit parameter corresponding to object on which member function is invoked -- the one  "this" points to -- is
 never eligible  for implicit conversions.  That's way first call compiles and the second one doesnot.

My question is what does author mean in above statment "only if they are listed in the parameter list" ? What is parameter list?

答:
When you write an operator, try to think of it in terms of an explicit function call.

```<code>Rational oneHalf(1, 2);
Rational result = oneHalf.multiply(2); // Ok, can convert
Rational result = 2.multiply(oneHalf); // OWAIT, no such function on int.
</code>```

Since there is no such operator on an int, the compiler doesn't know how to handle oneHalf to make the call work, and throws an error. The "Parameter list" in this case is the argument to the operator. You need to make a free function.

ContentLicense: CC BY-SA 2.5

Title: implementing operator * in C++

Body:
class Rational {

 const Rational operator*(const Rational& rhs) const

  ...
};

 Rational oneHalf(1,2);

 Rational result = oneHalf * 2;   // fine (with non-explicit ctor)
 result          = 2 * oneHalf;  // error! (even with non-explicit ctor)

It was mentioned by scott meyers in Effective C++ book as below

Even when Rationl's constructor is not explicit, one compiles and one doesnot. Reason is given as below:

It turns out that parameters are eligible for implicit conversion "only if they are listed in the parameter list".

The implicit parameter corresponding to object on which member function is invoked -- the one  "this" points to -- is
 never eligible  for implicit conversions.  That's way first call compiles and the second one doesnot.

My question is what does author mean in above statment "only if they are listed in the parameter list" ? What is parameter list?

Body:
When you write an operator, try to think of it in terms of an explicit function call.

Rational oneHalf(1, 2);
Rational result = oneHalf.multiply(2); // Ok, can convert
Rational result = 2.multiply(oneHalf); // OWAIT, no such function on int.

Since there is no such operator on an int, the compiler doesn't know how to handle oneHalf to make the call work, and throws an error. The "Parameter list" in this case is the argument to the operator. You need to make a free function.


问:
Refreshing an access token (offline access) for Google Drive API in PHP
I am writing an app that performs routine updates to a database with data gathered from a single account's Google Drive using the Google Drive API and Google Sheets API.

Using the answer found in this How do I authorise an app (web or installed) without user intervention? (canonical ?) question, I have been able to create my own PHP function to get the access token.

```<code>function get_access_token() {
  $request_url = "https://www.googleapis.com/oauth2/v4/token";
  $refresh_token = "1/XgTqiwrGHJ3LOh-verververververv-q2qIF3Aq_ENrzhH6IQA4u4X";

  $params = [
            'client_id'     => "1073411048819-vergewrgergergewrgerwgewr.apps.googleusercontent.com",
            'client_secret' => "b8oPhmVrevervvreverviA37aipaB",
            'refresh_token' => $refresh_token,
            'grant_type'    => "refresh_token"
          ];

  $curl = curl_init($request_url);
  curl_setopt($curl, CURLOPT_HEADER, true);
  curl_setopt($curl, CURLINFO_HEADER_OUT, true);
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($curl, CURLOPT_POST, true);
  curl_setopt($curl, CURLOPT_HEADER,'Content-Type: application/x-www-form-urlencoded');

  $postData = "";

  //This is needed to properly form post the credentials object
  foreach($params as $k => $v) {
    $postData .= $k . '='.urlencode($v).'&';
  }
  $postData = rtrim($postData, '&');

  curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);

  $json_response = curl_exec($curl);
  $response = (array) json_decode( $json_response );

  $response["refresh_token"] = $refresh_token;
  $date = new DateTime();
  $response["created"] = $date->getTimestamp();
  return $response;
}
</code>```

Which works and produces an access token that looks like this:

```<code>array(5) {
  ["access_token"]=>
  string(129) "ya29.GlsEBWfC-cdO1F80MjNB_oNVp87fojEWILclEfbgbgbgbbgbgbgbgzXNFV3xSmMSI733HvdTrXd6wgbDB0u3ACLfRaNkitIQPOdF3T2jSH3NTjCEndH0fBYXy"
  ["token_type"]=>
  string(6) "Bearer"
  ["expires_in"]=>
  int(3600)
  ["refresh_token"]=>
  string(45) "1/XgTqiwrGHJ3LOh-verververververv-q2qIF3Aq_ENrzhH6IQA4u4X"
  ["created"]=>
  int(1510654966)
}
</code>```

I can use this access_token to make requests such as...

```<code>GET https://www.googleapis.com/drive/v3/files
Authorization: Bearer ya29.GlsEBWfC-cdO1F80MjNB_oNVp87fojEWILclEfbgbgbgbbgbgbgbgzXNFV3xSmMSI733HvdTrXd6wgbDB0u3ACLfRaNkitIQPOdF3T2jSH3NTjCEndH0fBYXy
</code>```

... so the function definitely produces a valid token.

However, I cannot figure out how to use the Google Drive API Client library with this.

Here is the PHP Quickstart for the Google Drive API.

And here is my broken code:

```<code>define('APPLICATION_NAME', 'My Plugin');
define('CREDENTIALS_PATH', '~/.credentials/drive-php-quickstart.json');
define('SCOPES', implode(' ', array(
  Google_Service_Drive::DRIVE_METADATA_READONLY)
));

/**
 * Returns an authorized API client.
 * @return Google_Client the authorized client object
 */
function getClient() {
  $client = new Google_Client();
  $client->setApplicationName(APPLICATION_NAME);
  $client->setScopes(SCOPES);
  $client->setAccessType('offline');

  // Load previously authorized credentials from a file.
  $credentialsPath = expandHomeDirectory(CREDENTIALS_PATH);
  if (file_exists($credentialsPath)) {
    $accessToken = json_decode(file_get_contents($credentialsPath), true);
  } else {
    $accessToken = get_access_token();

    // Store the credentials to disk.
    if(!file_exists(dirname($credentialsPath))) {
      mkdir(dirname($credentialsPath), 0700, true);
    }
    file_put_contents($credentialsPath, json_encode($accessToken));
    printf("Credentials saved to %s\n", $credentialsPath);
  }
  $client->setAccessToken($accessToken);

  if ($client->isAccessTokenExpired()) {
    $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
    file_put_contents($credentialsPath, json_encode(get_access_token()));
  }
  return $client;
}

/**
 * Expands the home directory alias '~' to the full path.
 * @param string $path the path to expand.
 * @return string the expanded path.
 */
function expandHomeDirectory($path) {
  $homeDirectory = getenv('HOME');
  if (empty($homeDirectory)) {
    $homeDirectory = getenv('HOMEDRIVE') . getenv('HOMEPATH');
  }
  return str_replace('~', realpath($homeDirectory), $path);
}

$client = getClient();
$driveService = new Google_Service_Drive($client);
</code>```

That produces:

```<code>$client = NULL;
$driveService = NULL;
</code>```

Is it possible to use this approach with the PHP library? If so, what is wrong with my example?

If not, how can I turn this:

```<code>$response = $driveService->changes->getStartPageToken();
</code>```

Into a HTTP/REST call (similar to GET https://www.googleapis.com/drive/v3/files)?

答:
```<code>   $token='access_token_here';
                        $url="https://www.googleapis.com/upload/drive/v3/files?uploadType=media";
                        $method='POST';
                    $filepath='file_to_upload_path.pdf'
    $data['name']='file_title_here.pdf';
                        $data['title']='file_title_here.pdf';
                        $p1=(object)[];
                        $p1->id='parent_folder_id_here';
                        $data['parents'][]=$p1;
                            $body=file_get_contents($filepath);
                            $timeout=30;
                            $verify_ssl   = false;
                            $headers = array(
                                            'Content-Type: application/pdf',
                                            'Cache-Control: no-cache',
                                            'Authorization: Bearer '.$token ,
                                            'Content-Length: '.strlen($body)
                                            );
                            $ch = curl_init();
                            curl_setopt($ch, CURLOPT_URL, $url);
                            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
                            curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
                            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $verify_ssl);
                            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
                            curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
                            curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
                            echo $result = curl_exec($ch);
                            //echo $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
                            curl_close($ch);
</code>```

ContentLicense: CC BY-SA 3.0

Body:
I am writing an app that performs routine updates to a database with data gathered from a single account's Google Drive using the Google Drive API and Google Sheets API.

Using the answer found in this How do I authorise an app (web or installed) without user intervention? (canonical ?) question, I have been able to create my own PHP function to get the access token.

function get_access_token() {
  $request_url = "https://www.googleapis.com/oauth2/v4/token";
  $refresh_token = "1/XgTqiwrGHJ3LOh-verververververv-q2qIF3Aq_ENrzhH6IQA4u4X";

  $params = [
            'client_id'     => "1073411048819-vergewrgergergewrgerwgewr.apps.googleusercontent.com",
            'client_secret' => "b8oPhmVrevervvreverviA37aipaB",
            'refresh_token' => $refresh_token,
            'grant_type'    => "refresh_token"
          ];

  $curl = curl_init($request_url);
  curl_setopt($curl, CURLOPT_HEADER, true);
  curl_setopt($curl, CURLINFO_HEADER_OUT, true);
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($curl, CURLOPT_POST, true);
  curl_setopt($curl, CURLOPT_HEADER,'Content-Type: application/x-www-form-urlencoded');

  $postData = "";

  //This is needed to properly form post the credentials object
  foreach($params as $k => $v) {
    $postData .= $k . '='.urlencode($v).'&';
  }
  $postData = rtrim($postData, '&');

  curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);

  $json_response = curl_exec($curl);
  $response = (array) json_decode( $json_response );

  $response["refresh_token"] = $refresh_token;
  $date = new DateTime();
  $response["created"] = $date->getTimestamp();
  return $response;
}

Which works and produces an access token that looks like this:

array(5) {
  ["access_token"]=>
  string(129) "ya29.GlsEBWfC-cdO1F80MjNB_oNVp87fojEWILclEfbgbgbgbbgbgbgbgzXNFV3xSmMSI733HvdTrXd6wgbDB0u3ACLfRaNkitIQPOdF3T2jSH3NTjCEndH0fBYXy"
  ["token_type"]=>
  string(6) "Bearer"
  ["expires_in"]=>
  int(3600)
  ["refresh_token"]=>
  string(45) "1/XgTqiwrGHJ3LOh-verververververv-q2qIF3Aq_ENrzhH6IQA4u4X"
  ["created"]=>
  int(1510654966)
}

I can use this access_token to make requests such as...

GET https://www.googleapis.com/drive/v3/files
Authorization: Bearer ya29.GlsEBWfC-cdO1F80MjNB_oNVp87fojEWILclEfbgbgbgbbgbgbgbgzXNFV3xSmMSI733HvdTrXd6wgbDB0u3ACLfRaNkitIQPOdF3T2jSH3NTjCEndH0fBYXy

... so the function definitely produces a valid token.

However, I cannot figure out how to use the Google Drive API Client library with this.

Here is the PHP Quickstart for the Google Drive API.

And here is my broken code:

define('APPLICATION_NAME', 'My Plugin');
define('CREDENTIALS_PATH', '~/.credentials/drive-php-quickstart.json');
define('SCOPES', implode(' ', array(
  Google_Service_Drive::DRIVE_METADATA_READONLY)
));

/**
 * Returns an authorized API client.
 * @return Google_Client the authorized client object
 */
function getClient() {
  $client = new Google_Client();
  $client->setApplicationName(APPLICATION_NAME);
  $client->setScopes(SCOPES);
  $client->setAccessType('offline');

  // Load previously authorized credentials from a file.
  $credentialsPath = expandHomeDirectory(CREDENTIALS_PATH);
  if (file_exists($credentialsPath)) {
    $accessToken = json_decode(file_get_contents($credentialsPath), true);
  } else {
    $accessToken = get_access_token();

    // Store the credentials to disk.
    if(!file_exists(dirname($credentialsPath))) {
      mkdir(dirname($credentialsPath), 0700, true);
    }
    file_put_contents($credentialsPath, json_encode($accessToken));
    printf("Credentials saved to %s\n", $credentialsPath);
  }
  $client->setAccessToken($accessToken);

  if ($client->isAccessTokenExpired()) {
    $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
    file_put_contents($credentialsPath, json_encode(get_access_token()));
  }
  return $client;
}

/**
 * Expands the home directory alias '~' to the full path.
 * @param string $path the path to expand.
 * @return string the expanded path.
 */
function expandHomeDirectory($path) {
  $homeDirectory = getenv('HOME');
  if (empty($homeDirectory)) {
    $homeDirectory = getenv('HOMEDRIVE') . getenv('HOMEPATH');
  }
  return str_replace('~', realpath($homeDirectory), $path);
}

$client = getClient();
$driveService = new Google_Service_Drive($client);

That produces:

$client = NULL;
$driveService = NULL;

Is it possible to use this approach with the PHP library? If so, what is wrong with my example?

If not, how can I turn this:

$response = $driveService->changes->getStartPageToken();

Into a HTTP/REST call (similar to GET https://www.googleapis.com/drive/v3/files)?


问:
Intellij : JDK Required: 'tools.jar' seems to be not in IDEA classpath Ubuntu 16.04
I looked over to a lot of answers here on SO, and followed them too, yet the error persists and I cannot start the Intellij for java.
Here is my java version

```<code>openjdk version "9-internal"
OpenJDK Runtime Environment (build 9-internal+0-2016-04-14-195246.buildd.src)
OpenJDK 64-Bit Server VM (build 9-internal+0-2016-04-14-195246.buildd.src, mixed mode)
</code>```

my javac version

javac 9-internal

my $JAVA_HOME

```<code>/usr/lib/jvm/java-8-openjdk-amd64
</code>```

When I cd into <ide_folder>/bin and run ./idea.sh

I get following error

```<code>JDK Required: 'tools.jar' seems to be not in IDEA classpath.
Please ensure JAVA_HOME points to `JDK` rather than `JRE`.
</code>```

and when I do sudo ./idea.sh I get following error

```<code>WARN: Unknown class loader: jdk.internal.loader.ClassLoaders$AppClassLoader
WARN: Unknown class loader: jdk.internal.loader.ClassLoaders$PlatformClassLoader
WARN: Unknown class loader: jdk.internal.loader.ClassLoaders$AppClassLoader
WARN: Unknown class loader: jdk.internal.loader.ClassLoaders$PlatformClassLoader

JDK Required: 'tools.jar' seems to be not in IDEA classpath.
Please ensure JAVA_HOME points to JDK rather than JRE.
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f5624a1e009, pid=15159, tid=15182
#
# JRE version: OpenJDK Runtime Environment (9.0) (build 9-internal+0-2016-04-14-195246.buildd.src)
# Java VM: OpenJDK 64-Bit Server VM (9-internal+0-2016-04-14-195246.buildd.src, mixed mode, tiered, compressed oops, concurrent mark sweep gc, linux-amd64)
# Problematic frame:
# C  [libjava.so+0x1d009]  JNU_GetEnv+0x19
#
# Core dump will be written. Default location: Core dumps may be processed with "/usr/share/apport/apport %p %s %c %P" (or dumping to /home/ekbana/softwares/idea-IC-171.4694.23/bin/core.15159)
#
# An error report file with more information is saved as:
# /home/ekbana/java_error_in_IDEA_15159.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
Aborted (core dumped)
</code>```

I have reached the point where I have no freaking idea what's happening.

答:
in my case, I needed to run both following commands : </p>

```<code>sudo apt-get install openjdk-8-jre
sudo apt-get install openjdk-8-jdk
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I looked over to a lot of answers here on SO, and followed them too, yet the error persists and I cannot start the Intellij for java.
Here is my java version

openjdk version "9-internal"
OpenJDK Runtime Environment (build 9-internal+0-2016-04-14-195246.buildd.src)
OpenJDK 64-Bit Server VM (build 9-internal+0-2016-04-14-195246.buildd.src, mixed mode)

my javac version

javac 9-internal

my $JAVA_HOME

/usr/lib/jvm/java-8-openjdk-amd64

When I cd into <ide_folder>/bin and run ./idea.sh

I get following error

JDK Required: 'tools.jar' seems to be not in IDEA classpath.
Please ensure JAVA_HOME points to `JDK` rather than `JRE`.

and when I do sudo ./idea.sh I get following error

WARN: Unknown class loader: jdk.internal.loader.ClassLoaders$AppClassLoader
WARN: Unknown class loader: jdk.internal.loader.ClassLoaders$PlatformClassLoader
WARN: Unknown class loader: jdk.internal.loader.ClassLoaders$AppClassLoader
WARN: Unknown class loader: jdk.internal.loader.ClassLoaders$PlatformClassLoader

JDK Required: 'tools.jar' seems to be not in IDEA classpath.
Please ensure JAVA_HOME points to JDK rather than JRE.
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f5624a1e009, pid=15159, tid=15182
#
# JRE version: OpenJDK Runtime Environment (9.0) (build 9-internal+0-2016-04-14-195246.buildd.src)
# Java VM: OpenJDK 64-Bit Server VM (9-internal+0-2016-04-14-195246.buildd.src, mixed mode, tiered, compressed oops, concurrent mark sweep gc, linux-amd64)
# Problematic frame:
# C  [libjava.so+0x1d009]  JNU_GetEnv+0x19
#
# Core dump will be written. Default location: Core dumps may be processed with "/usr/share/apport/apport %p %s %c %P" (or dumping to /home/ekbana/softwares/idea-IC-171.4694.23/bin/core.15159)
#
# An error report file with more information is saved as:
# /home/ekbana/java_error_in_IDEA_15159.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
Aborted (core dumped)

I have reached the point where I have no freaking idea what's happening.

Body:
in my case, I needed to run both following commands :

sudo apt-get install openjdk-8-jre
sudo apt-get install openjdk-8-jdk


问:
Spawn image at random position in canvas
I have a canvas and inside it a panel. I want to spawn different image UI object at random position inside my panel (on screen). I took x and y min and max  limits of the panel in order to generate a random position (withing these limts) but the problem is object are not instantiating at desired position. This is my code.

```<code>public class ImageSpawnerScreen : MonoBehaviour {
    public float waitTime = 2;
    public float cubeSpawnTotal = 10;
    public List<GameObject> cubePrefabList;

    float xPosMinLimit = -347;
    float xPosMaxLimit = 340;
    float yPosMinLimit = -458f;
    float yPosMaxLimit = 450f;

    public GameObject panel;
    void Start()
    {
        StartCoroutine(SpawnCube());
    }

    IEnumerator SpawnCube()
    {
        for (int i = 0; i < cubeSpawnTotal; i++)
        {
            GameObject prefabToSpawn = cubePrefabList[Random.Range(0, cubePrefabList.Count - 1)];
            //Vector3 spawnPosition = Camera.main.ScreenToViewportPoint(new Vector3(Random.Range(0,Screen.width),0,Random.Range(0,Screen.height)));  //Random.Range(xPosMinLimit, xPosMaxLimit);

            float xPos = Random.Range(xPosMinLimit, xPosMaxLimit);
            float yPos = Random.Range(yPosMinLimit, yPosMaxLimit);
            Vector3 spawnPosition = new Vector3(xPos, yPos, 0f);
            GameObject spwanObj = Instantiate(prefabToSpawn, spawnPosition, Quaternion.identity) as GameObject;
            spwanObj.transform.parent = panel.transform;
            spwanObj.transform.position = spawnPosition;
            yield return new WaitForSeconds(waitTime);
        }
    }
}
</code>```

I checked instantiated object positions are far away from the given random range position. What I am doing wrong? I think it is Rect Transform so i have to set its position differently.

答:
To manage Canvas object's position you should definitely use RectTransform instead of regular transform. In your case you have to do something like :

m_RectTransform = GetComponent<RectTransform>();

As for setting position - coordinates you see on the object inside Canvas is not .position but RectTransform.anchoredPosition, so you should use it in your code. Here is an official documentation on anchoredPosition.

Body:
I have a canvas and inside it a panel. I want to spawn different image UI object at random position inside my panel (on screen). I took x and y min and max  limits of the panel in order to generate a random position (withing these limts) but the problem is object are not instantiating at desired position. This is my code.

public class ImageSpawnerScreen : MonoBehaviour {
    public float waitTime = 2;
    public float cubeSpawnTotal = 10;
    public List<GameObject> cubePrefabList;

    float xPosMinLimit = -347;
    float xPosMaxLimit = 340;
    float yPosMinLimit = -458f;
    float yPosMaxLimit = 450f;

    public GameObject panel;
    void Start()
    {
        StartCoroutine(SpawnCube());
    }

    IEnumerator SpawnCube()
    {
        for (int i = 0; i < cubeSpawnTotal; i++)
        {
            GameObject prefabToSpawn = cubePrefabList[Random.Range(0, cubePrefabList.Count - 1)];
            //Vector3 spawnPosition = Camera.main.ScreenToViewportPoint(new Vector3(Random.Range(0,Screen.width),0,Random.Range(0,Screen.height)));  //Random.Range(xPosMinLimit, xPosMaxLimit);

            float xPos = Random.Range(xPosMinLimit, xPosMaxLimit);
            float yPos = Random.Range(yPosMinLimit, yPosMaxLimit);
            Vector3 spawnPosition = new Vector3(xPos, yPos, 0f);
            GameObject spwanObj = Instantiate(prefabToSpawn, spawnPosition, Quaternion.identity) as GameObject;
            spwanObj.transform.parent = panel.transform;
            spwanObj.transform.position = spawnPosition;
            yield return new WaitForSeconds(waitTime);
        }
    }
}

I checked instantiated object positions are far away from the given random range position. What I am doing wrong? I think it is Rect Transform so i have to set its position differently.


问:
Need to develop Protocol analyser for Abis?
Abis is the signals which are passed from BTS to BSC in mobile networks. The work they want to do is to collect the messages from BTS, analyse it to find some specific errors etc. So for doing these, I have to actually know how to do protocol analyser. the language which i am told is to use is c or CPP. </p>

答:
There are three main stages on analysing data for any protocol:

Capturing or generating the network traffic: For mobile networks, that generally involves very expensive receiver hardware - hardware that usually comes with its own analyser software that will be far better than anything you might code yourself. Base stations may allow for a way to monitor their operation and capture data. It is also theoretically possible to repurpose other hardware (e.g. a cell phone or a lab instrument), or to generate the data using a simulator.

Extracting the data of interest: You need to extract and isolate the data for the protocol that interests you. Depending on the encapsulation and encryption properties of the network, that might be impossible for data captured in the wild - in that case you'd need something that would act as a node in the network and provide access to its inner workings.

Analysing the protocol of interest: You need a piece of software that will not only implement the protocol, but that will provide far more extensive logging and error-recovery capabilities than any production implementations. That way it will be able to point out and handle misbehaving nodes.

If you intend to write a protocol analyser of your own, you need to aqcuire the protocol specification and code such an implementation. You should be warned that even the simplest protocols are in fact quite difficult to implement correctly.

Without more information on your development and target platforms, the source and format of the data and the resources that you have available, there is no way for us to provide more information.

PS: It would also help if your question contained an actual question that we could answer.


问:
Limiting an iOS app to installation on only one device
I have an iOS app written in Swift where I want to limit each account to one device only – what is a way that I could go about limiting this access? I'm using Firebase and have a login system but the login system is not linked to Firebase Auth.</p>

答:
After login the use generate the token and save them into dataBase. And send this token in header when you hit any other API. If new same use login on other device, update the token in data base .

Now you check this token is same or not if not then send repose code 401 and logout the user.


问:
Copy workbook name to a cell in another workbook
I want to search for an open file named "OTIF"[...].

When the macro finds the workbook, it should paste the file name into "sheet1" Cell A1 in another workbook (wb2).

```<code>Sub Filename()

Dim Wb1 As Workbook, wb2 As Workbook, wB As Workbook

For Each wB In Application.Workbooks
    If Left(wB.Name, 4) = "OTIF" Then
        Set Wb1 = wB
        Exit For
    End If
Next

If Not Wb1 Is Nothing Then
    Set wb2 = ThisWorkbook
End If

With wb2.Sheets("AAA")
    .Range("A1").Value = Dir(Wb1.FullName)
End With

Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic

MsgBox "DONE!"

End Sub
</code>```

答:
I looked at your code and it can be simplified like below.</p>

```<code>Sub Filename()
Dim wB As Workbook
For Each wB In Application.Workbooks
    If Left(wB.Name, 4) = "OTIF" Then
        ThisWorkbook.Sheets("AAA").Range("A1").Value = wB.FullName
        Exit For
    End If
Next
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
MsgBox "DONE!"
End Sub
</code>```

Body:
I want to search for an open file named "OTIF"[...].

When the macro finds the workbook, it should paste the file name into "sheet1" Cell A1 in another workbook (wb2).

Sub Filename()

Dim Wb1 As Workbook, wb2 As Workbook, wB As Workbook

For Each wB In Application.Workbooks
    If Left(wB.Name, 4) = "OTIF" Then
        Set Wb1 = wB
        Exit For
    End If
Next

If Not Wb1 Is Nothing Then
    Set wb2 = ThisWorkbook
End If

With wb2.Sheets("AAA")
    .Range("A1").Value = Dir(Wb1.FullName)
End With

Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic

MsgBox "DONE!"

End Sub

Body:
I looked at your code and it can be simplified like below.

Sub Filename()
Dim wB As Workbook
For Each wB In Application.Workbooks
    If Left(wB.Name, 4) = "OTIF" Then
        ThisWorkbook.Sheets("AAA").Range("A1").Value = wB.FullName
        Exit For
    End If
Next
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
MsgBox "DONE!"
End Sub


问:
October CMS Static Pages plugin - hide / show pages in the backend based on user roles?
How can I hide some static pages based on the user's role?

I defined the role of users with the name "blabla".
Now I want to hide all the pages from these users, except for the page "blabla" in the "Static Pages" backend.
How can i do this?

sorry for my English))

答:
yes of course you can do it but we need to write some code here.

we can utilize cms.object.listInTheme event

In your plugin within boot method you can add this event listener and filter static pages.

```<code>\Event::listen('cms.object.listInTheme', function ($cmsObject, $objectList) {

    // lets check if we are really running in static pages
    // you can also add more checks here based on controllers etc ..
    if ($cmsObject instanceof \RainLab\Pages\Classes\Page) {

        $user = \BackendAuth::getUser();
        // role code and role name are different things
        // we should use role code as it act as constant
        $hasRoleFromWhichIneedTohidePages = $user->role->code === 'blabla' ? true : false;

        // if user has that role then we start filtering
        if($hasRoleFromWhichIneedTohidePages) {
            foreach ($objectList as $index => $page) {

                // we can use different matching you can use one of them
                // to identify your page which you want to hide.
                // forgot method will hide that page

                // match against filename
                if ($page->fileName == 'hidethispage.htm') {
                    $objectList->forget($index);
                }

                // OR match against title
                if ($page->title == 'hidethispage') {
                    $objectList->forget($index);
                }

                // OR match against url
                if ($page->url == '/hidethispage') {
                    $objectList->forget($index);
                }
             }
         }
    }
});
</code>```

currently this code will check page-url / title / file-name and restrict user statically from showing page in list but you can put your own logic here and make things dynamic.

if you didn't get it or want dynamic solution then please comment , I will explain in more detail.

Body:
yes of course you can do it but we need to write some code here.

we can utilize cms.object.listInTheme event

In your plugin within boot method you can add this event listener and filter static pages.

\Event::listen('cms.object.listInTheme', function ($cmsObject, $objectList) {

    // lets check if we are really running in static pages
    // you can also add more checks here based on controllers etc ..
    if ($cmsObject instanceof \RainLab\Pages\Classes\Page) {

        $user = \BackendAuth::getUser();
        // role code and role name are different things
        // we should use role code as it act as constant
        $hasRoleFromWhichIneedTohidePages = $user->role->code === 'blabla' ? true : false;

        // if user has that role then we start filtering
        if($hasRoleFromWhichIneedTohidePages) {
            foreach ($objectList as $index => $page) {

                // we can use different matching you can use one of them
                // to identify your page which you want to hide.
                // forgot method will hide that page

                // match against filename
                if ($page->fileName == 'hidethispage.htm') {
                    $objectList->forget($index);
                }

                // OR match against title
                if ($page->title == 'hidethispage') {
                    $objectList->forget($index);
                }

                // OR match against url
                if ($page->url == '/hidethispage') {
                    $objectList->forget($index);
                }
             }
         }
    }
});

currently this code will check page-url / title / file-name and restrict user statically from showing page in list but you can put your own logic here and make things dynamic.

if you didn't get it or want dynamic solution then please comment , I will explain in more detail.


问:
AsyncStorage doesnt return anything
I want to store data via asyncstorage in my react-native app, But I have a problem. I using it like that:

```<code> async componentDidMount() {
 console.log("Flag1");
 await AsyncStorage.setItem('name', 'I like to save it.');
 console.log("Flag2");
 }
</code>```

But for some reason I cant reach "Flag2", And I am not getting an error or a data from the await call.
I also tried use try/catch, facing the same problem.

edit I noticed that AsyncStorage works for me only when I just open the emulator, after a couple of uses it stops working.

答:
setItem and getItem are asynchronous, you should send a callback as parameter to get the result. like</p>

```<code>componentDidMount(){
    AsyncStorage.setItem('name', 'I like to save it.', ()=>{
        console.log("set item success")
        AsyncStorage.getItem("name", (error, result)=>{
            console.log("get result " + result)
        })
    });
}
</code>```

Title: AsyncStorage doesnt return anything

Body:
I want to store data via asyncstorage in my react-native app, But I have a problem. I using it like that:

 async componentDidMount() {
 console.log("Flag1");
 await AsyncStorage.setItem('name', 'I like to save it.');
 console.log("Flag2");
 }

But for some reason I cant reach "Flag2", And I am not getting an error or a data from the await call.
I also tried use try/catch, facing the same problem.

edit I noticed that AsyncStorage works for me only when I just open the emulator, after a couple of uses it stops working.

Body:
setItem and getItem are asynchronous, you should send a callback as parameter to get the result. like

componentDidMount(){
    AsyncStorage.setItem('name', 'I like to save it.', ()=>{
        console.log("set item success")
        AsyncStorage.getItem("name", (error, result)=>{
            console.log("get result " + result)
        })
    });
}


问:
angular ui-grid filter when user presses enter key
I have implemented a ui-grid with server side filtering, sorting and pagination.

I use gridApi.core.on.filterChanged to detect filter change alongside $timeout to wait for user to finish typing. It's not bad idea to use $timeout, but I want to filter grid only on enter key, but filterChanged event watches the value of field and I think it doesn't have access to keypress nor keydown events to detect enter key.

How can I call ajax filter on enter key?

答:
Filter event of ui grid calls with watch of the modal,but watch method calls on keypress so we can change the keypress event to blur event of text box by adding the directive

```<code>directive('ngModelOnblur', function () {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, elm, attr, ngModelCtrl) {
            elm.unbind('input').unbind('keydown').unbind('blur');
            elm.bind('change', function () {
                scope.$apply(function () {
                    ngModelCtrl.$setViewValue(elm.val());
                });
            });
        }
    };
});
</code>```

add the directive in textbox of uigrid and ui grid filter.api called only on  change event of textbox or enter key.

Body:
Filter event of ui grid calls with watch of the modal,but watch method calls on keypress so we can change the keypress event to blur event of text box by adding the directive

directive('ngModelOnblur', function () {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, elm, attr, ngModelCtrl) {
            elm.unbind('input').unbind('keydown').unbind('blur');
            elm.bind('change', function () {
                scope.$apply(function () {
                    ngModelCtrl.$setViewValue(elm.val());
                });
            });
        }
    };
});

add the directive in textbox of uigrid and ui grid filter.api called only on  change event of textbox or enter key.


问:
How to show Results marks in round pie chart style in javascript quiz?
Hello friends i have a javascript quiz,
currently in my quiz results showing in this format
You Give 2 Correct Answer Out Of 10 (Percentage Is 20%)

it is the javascrit code

```<code>$('#question').addClass("sub-header").text("You give " + score + " correct answer out of " + quiz.questions.length + " (Percentage is " + percentageCorrect + "%)");
</code>```

but i dont know how show add result in pie chart like this.
easypiechart

答:
Have a look at this codepen.
Have modified example 1 for 20%

you have to make use of data-start,data-value which are HTML5 custom data attributes

```<code><div class="demo-wrapper">
<div class="csspie" data-start="0" data-value="20"></div>
<div class="csspie big" data-start="20" data-value="80"></div>
</div>
</code>```

Body:
Hello friends i have a javascript quiz,
currently in my quiz results showing in this format
You Give 2 Correct Answer Out Of 10 (Percentage Is 20%)

it is the javascrit code

$('#question').addClass("sub-header").text("You give " + score + " correct answer out of " + quiz.questions.length + " (Percentage is " + percentageCorrect + "%)");

but i dont know how show add result in pie chart like this.
easypiechart

Body:
Have a look at this codepen.
Have modified example 1 for 20%

you have to make use of data-start,data-value which are HTML5 custom data attributes

<div class="demo-wrapper">
<div class="csspie" data-start="0" data-value="20"></div>
<div class="csspie big" data-start="20" data-value="80"></div>
</div>


问:
Can I grab data from a datagrid row when the UserDeletedRow event is triggered
I have a datagridview that is populated from a dataset but not bound to I.
I would like to retain the user being able to delete rows in the datagrid and have these trigger the UserDeletedRow event for the grid, but I still need to capture some information from the Row so that I can run the SQL to remove it from the database.

My question is can you add any variables to the sub routine that allow you to pull out some information from the row being deleted (even one cell would be enough) or alternatively does anyone know if the UserDeletedRow event is triggered on the hit of the delete key but before the row is removed completely from Datagrid object; and so the row is still "selected" and accessible; or after the row has been removed.

Kind regards

Matt

答:
I have found a solution which I will leave here for others.
Within the subroutine there is a variable 'e' which holds information about the row triggering the event.

You can gather anything you like from the this row as it appears to have the same property options as a DataGridRow object.

Below is a sample of the code where you can pull out a single cell (in this case a rowID) and store the data for use before it is fully removed.

```<code>Private Sub dgvCalibration_UserDeletedRow(sender As System.Object, e As System.Windows.Forms.DataGridViewRowEventArgs) Handles dgvCalibration.UserDeletedRow

    Dim intDelRow As Integer
    intDelRow = e.Row.Cells(0).Value()
</code>```

Matt

Body:
I have found a solution which I will leave here for others.
Within the subroutine there is a variable 'e' which holds information about the row triggering the event.

You can gather anything you like from the this row as it appears to have the same property options as a DataGridRow object.

Below is a sample of the code where you can pull out a single cell (in this case a rowID) and store the data for use before it is fully removed.

Private Sub dgvCalibration_UserDeletedRow(sender As System.Object, e As System.Windows.Forms.DataGridViewRowEventArgs) Handles dgvCalibration.UserDeletedRow

    Dim intDelRow As Integer
    intDelRow = e.Row.Cells(0).Value()

Matt


问:
Import Error: cannot import pivot_simple
I am using Ubuntu system with python 2.7  and pandas version of 0.19.I have been trying to run a python file and this error keeps on showing up-

```<code>>>> import file.py as x
   Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
   File "file.py", line 4, in <module>
   import pandas as pd
   File "/home/user/.local/lib/python2.7/site-packages/pandas/__init__.py",      line 39, in <module>
   from pandas.core.api import *
   File "/home/user/.local/lib/python2.7/site-packages/pandas/core/api.py",  line 20, in <module>
   from pandas.core.reshape import (pivot_simple as pivot, get_dummies,
   ImportError: cannot import name pivot_simple
</code>```

Please help me in resolving the issue by telling the possible issues for this error and the way it can be removed.

Thanks!

答:
instead of using 'files.py'
please try 'import files as x'</p>

Body:
I am using Ubuntu system with python 2.7  and pandas version of 0.19.I have been trying to run a python file and this error keeps on showing up-

>>> import file.py as x
   Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
   File "file.py", line 4, in <module>
   import pandas as pd
   File "/home/user/.local/lib/python2.7/site-packages/pandas/__init__.py",      line 39, in <module>
   from pandas.core.api import *
   File "/home/user/.local/lib/python2.7/site-packages/pandas/core/api.py",  line 20, in <module>
   from pandas.core.reshape import (pivot_simple as pivot, get_dummies,
   ImportError: cannot import name pivot_simple

Please help me in resolving the issue by telling the possible issues for this error and the way it can be removed.

Thanks!


问:
Instagram: photo upload confirmation
I have created an android app for our upcoming event. We will allow attendees of the event to network with each other using this app. We will also encourage them to take pictures of the event and share them with a certain #hashtag. Each photo that the user uploads gives them a certain number of reward points. At the end of the event, the user with the maximum points gets a reward for their effort.
Now I have managed to create a share intent using the instagram documentation here -
Instagram Android Intent

However, there is an issue. From this intent I don't know if the user has successfully posted the photo on Instagram or just abandoned the photo share during the editing stage of Instagram.

What would be the best way to accurately establish whether the user has shared the photo on Instagram successfully?

Given that there is a cash reward for a person with maximum shares, we want to be careful in terms of accuracy of calculating the successful shares.

Appreciate any ideas or even workarounds, as long as they meet the end objective.

Also if you think this is impossible to do with relatively high degree of accuracy, please feel free to share your thoughts on why not? We can then at least abandon this approach and work on something else for meaningful sharing and rewarding.

答: Before doing the share intent I would ask the users their instagram username and save it in your server database. Then, at the end of the event I would use the Python Client for Instagram API to retrieve all photos containing your hashtag and photo owner username. Then make a simple sum of photos for each user to know the winner.</p>

Title: Instagram: photo upload confirmation


问:
why is it timing out like this?
I'm trying to build a TCP-proxy script that sends and receives data, i managed to get it to listen but it doesn't seem to be connecting properly...my code looks right to me and after checking python docs(i'm trying to run it in python 2.7 and 3.6) i get this timeout message:

Output:

```<code>anon@kali:~/Desktop/python scripts$ sudo python TCP\ proxy.py 127.0.0.1 21 ftp.target.ca 21 True
[*] Listening on 127.0.0.1:21d
[==>] Received incoming connection from 127.0.0.1:44806d
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/threading.py", line 754, in run
    self.__target(*self.__args, **self.__kwargs)
  File "TCP proxy.py", line 60, in proxy_handler
    remote_socket.connect((remote_host,remote_port))
  File "/usr/lib/python2.7/socket.py", line 228, in meth
    return getattr(self._sock,name)(*args)
error: [Errno 110] Connection timed out
</code>```

i looked into the file "/usr/lib/python2.7/socket.py" but couldn't really understand what i was looking for as it seemed right when i compared it to python docs and my script

my code:

```<code># import the modules
import sys
import socket
import threading

#define the server
def server_loop(local_host,local_port,remote_host,remote_port,receive_first):
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    try:
        server.bind((local_host, local_port))
        server.listen(5)
        print ("[*] Listening on %s:%sd" % (local_host, local_port))
    except:
        print("[!!] Failed to listen on %s:%sd" % (local_host,local_port))
        print ("[!!] Check for others listening sockets or correct permissions")
        sys.exit(0)

    while True:
        client_socket, addr = server.accept()

        #print out the local connection information
        print ("[==>] Received incoming connection from %s:%sd" % (addr[0],addr[1]))

        #start a thread to talk to the remote host
        proxy_thread = threading.Thread(target=proxy_handler,args=(client_socket,remote_host,remote_port,receive_first))

        proxy_thread.start()
    else:
        print ("something went wrong")

def main():
    #no fancy command-line parasing here
    if len(sys.argv[1:]) !=5:
        print ("Usage: ./TCP proxy.py [localhost] [localport] [remotehost] [remoteport] [receive_first]")
        print("Example: ./TCP proxy.py 127.0.0.1 9000 10.12.132.1 9000 True")

    #set up local listening parameters
    local_host = sys.argv[1]
    local_port = int(sys.argv[2])

    #set up remote target
    remote_host = sys.argv[3]
    remote_port = int(sys.argv[4])

    #this tells proxy to connect and receive data before sending to remote host
    receive_first = sys.argv[5]

    if "True" in receive_first:
        receive_first = True
    else:
        receive_first = False

    #now spin up our listening socket
    server_loop(local_host,local_port,remote_host,remote_port,receive_first)

def proxy_handler(client_socket, remote_host, remote_port, receive_first):
    #connect to the remote host
    remote_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    remote_socket.connect((remote_host,remote_port))

    #receive data from the remote end if necessary
    if receive_first:
        remote_buffer = receive_from(remote_socket)
        hexdump(remote_buffer)

        #send it to the repsonse handler
        remote_buffer = respsonse_handler(remote_buffer)

        #if data is able to be sent to local client, send it
        if len(remote_buffer):
            print ("[<==] Sending %d bytes to localhost." % len(remote_buffer))
            client_socket.send(remote_buffer)
    #now loop and read from local,sent to remote,send to local,rinse/wash/repeat
    while True:
        #read from local host
        local_buffer = receive_from(client_socket)

        if len(local_buffer):
            print ("[==>] Received %d bytes from localhost." % len(local_buffer))

            #send it to request handler
            local_buffer = request_handler(local_buffer)

            #send data to remote host
            remote_socket.send(local_buffer)
            print ("[==>] Sent to remote.")

        #receive back response
        remote_buffer = receive_from(remote_socket)
        if len(remote_buffer):
            print ("[<==] Received %d bytes from remote." % len(remote_buffer))
            hexdump(remote_buffer)

            #send response to handler
            remote_buffer = response_handler(remote_buffer)

            #send response to local socket
            client_socket.send(remote_buffer)

            print ("[<==] Sent to localhost.")

        #if no data left on either side, close connection
        if not len(local_buffer) or not len(remote_buffer):
            client_socket.close()
            remote_socket.close()
            print ("[*] No more data, closing connections.")

            break

#this is a pretty hex dumping function taken from the comments of http://code.activestate.com/recipes/142812-hex-dumper/
def hexdump(src, length=16):
    result = []
    digits = 4 if isinstance(src,unicode) else 2
    for i in xrange(0,len(src), length):
        s = src[i:i+length]
        hexa = b' '.join(["%0*X" % (digits, ord(x)) for x in s])
        text = b' '.join([x if 0x20 <= ord(x) < 0x7F else b'.' for x in s])
        result.append( b"%04X %-*s %s" % (i, length*(digits + 1), hexa, text) )
    print (b'/n'.join(result))

def receive_from(connection):
    buffer = ""

    #set a 2 second timeout; depending on your target this may need to be adjusted
    connection.settimeout(2)

    try:
        #keep reading the buffer until no more data is there or it times out
        while True:
            data = connection.recv(4096)

            if not data:
                break
            buffer += data
    except:
        pass
    return buffer

#modify any requested destined for the remote host
def request_handler(buffer):
    #perform packet modifications
    return buffer

#modify any responses destined for the local host
def response_handler(buffer):
    #perform packet modifications
    return buffer

main()
</code>```

i have tried different ftp servers/sites,etc but get the same result, where am i going wrong with my code? any input or direction would be greatly appreciated.

答:
okay so turns out my script is good just the ftp servers i was running weren't haha
this is the final output:</p>

```<code>anon@kali:~/Desktop/python scripts$ sudo python TCP\ proxy.py 127.0.0.1 21 ftp.uconn.edu 21 True
[*] Listening on 127.0.0.1:21d
[==>] Received incoming connection from 127.0.0.1:51532d
0000 32 32 30 20 50 72 6F 46 54 50 44 20 31 2E 32 2E  2 2 0   P r o F T P D   1 . 2 ./n0010 31 30 20 53 65 72 76 65 72 20 28 66 74 70 2E 75  1 0   S e r v e r   ( f t p . u/n0020 63 6F 6E 6E 2E 65 64 75 29 20 5B 31 33 37 2E 39  c o n n . e d u )   [ 1 3 7 . 9/n0030 39 2E 32 36 2E 35 32 5D 0D 0A                    9 . 2 6 . 5 2 ] . .
[<==] Sending 58 bytes to localhost.
[==>] Received 353 bytes from localhost.
[==>] Sent to remote.
[<==] Received 337 bytes from remote.
</code>```

Title: why is it timing out like this?

Body:
I'm trying to build a TCP-proxy script that sends and receives data, i managed to get it to listen but it doesn't seem to be connecting properly...my code looks right to me and after checking python docs(i'm trying to run it in python 2.7 and 3.6) i get this timeout message:

Output:

anon@kali:~/Desktop/python scripts$ sudo python TCP\ proxy.py 127.0.0.1 21 ftp.target.ca 21 True
[*] Listening on 127.0.0.1:21d
[==>] Received incoming connection from 127.0.0.1:44806d
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/threading.py", line 754, in run
    self.__target(*self.__args, **self.__kwargs)
  File "TCP proxy.py", line 60, in proxy_handler
    remote_socket.connect((remote_host,remote_port))
  File "/usr/lib/python2.7/socket.py", line 228, in meth
    return getattr(self._sock,name)(*args)
error: [Errno 110] Connection timed out

i looked into the file "/usr/lib/python2.7/socket.py" but couldn't really understand what i was looking for as it seemed right when i compared it to python docs and my script

my code:

# import the modules
import sys
import socket
import threading

#define the server
def server_loop(local_host,local_port,remote_host,remote_port,receive_first):
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    try:
        server.bind((local_host, local_port))
        server.listen(5)
        print ("[*] Listening on %s:%sd" % (local_host, local_port))
    except:
        print("[!!] Failed to listen on %s:%sd" % (local_host,local_port))
        print ("[!!] Check for others listening sockets or correct permissions")
        sys.exit(0)

    while True:
        client_socket, addr = server.accept()

        #print out the local connection information
        print ("[==>] Received incoming connection from %s:%sd" % (addr[0],addr[1]))

        #start a thread to talk to the remote host
        proxy_thread = threading.Thread(target=proxy_handler,args=(client_socket,remote_host,remote_port,receive_first))

        proxy_thread.start()
    else:
        print ("something went wrong")

def main():
    #no fancy command-line parasing here
    if len(sys.argv[1:]) !=5:
        print ("Usage: ./TCP proxy.py [localhost] [localport] [remotehost] [remoteport] [receive_first]")
        print("Example: ./TCP proxy.py 127.0.0.1 9000 10.12.132.1 9000 True")

    #set up local listening parameters
    local_host = sys.argv[1]
    local_port = int(sys.argv[2])

    #set up remote target
    remote_host = sys.argv[3]
    remote_port = int(sys.argv[4])

    #this tells proxy to connect and receive data before sending to remote host
    receive_first = sys.argv[5]

    if "True" in receive_first:
        receive_first = True
    else:
        receive_first = False

    #now spin up our listening socket
    server_loop(local_host,local_port,remote_host,remote_port,receive_first)

def proxy_handler(client_socket, remote_host, remote_port, receive_first):
    #connect to the remote host
    remote_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    remote_socket.connect((remote_host,remote_port))

    #receive data from the remote end if necessary
    if receive_first:
        remote_buffer = receive_from(remote_socket)
        hexdump(remote_buffer)

        #send it to the repsonse handler
        remote_buffer = respsonse_handler(remote_buffer)

        #if data is able to be sent to local client, send it
        if len(remote_buffer):
            print ("[<==] Sending %d bytes to localhost." % len(remote_buffer))
            client_socket.send(remote_buffer)
    #now loop and read from local,sent to remote,send to local,rinse/wash/repeat
    while True:
        #read from local host
        local_buffer = receive_from(client_socket)

        if len(local_buffer):
            print ("[==>] Received %d bytes from localhost." % len(local_buffer))

            #send it to request handler
            local_buffer = request_handler(local_buffer)

            #send data to remote host
            remote_socket.send(local_buffer)
            print ("[==>] Sent to remote.")

        #receive back response
        remote_buffer = receive_from(remote_socket)
        if len(remote_buffer):
            print ("[<==] Received %d bytes from remote." % len(remote_buffer))
            hexdump(remote_buffer)

            #send response to handler
            remote_buffer = response_handler(remote_buffer)

            #send response to local socket
            client_socket.send(remote_buffer)

            print ("[<==] Sent to localhost.")

        #if no data left on either side, close connection
        if not len(local_buffer) or not len(remote_buffer):
            client_socket.close()
            remote_socket.close()
            print ("[*] No more data, closing connections.")

            break

#this is a pretty hex dumping function taken from the comments of http://code.activestate.com/recipes/142812-hex-dumper/
def hexdump(src, length=16):
    result = []
    digits = 4 if isinstance(src,unicode) else 2
    for i in xrange(0,len(src), length):
        s = src[i:i+length]
        hexa = b' '.join(["%0*X" % (digits, ord(x)) for x in s])
        text = b' '.join([x if 0x20 <= ord(x) < 0x7F else b'.' for x in s])
        result.append( b"%04X %-*s %s" % (i, length*(digits + 1), hexa, text) )
    print (b'/n'.join(result))

def receive_from(connection):
    buffer = ""

    #set a 2 second timeout; depending on your target this may need to be adjusted
    connection.settimeout(2)

    try:
        #keep reading the buffer until no more data is there or it times out
        while True:
            data = connection.recv(4096)

            if not data:
                break
            buffer += data
    except:
        pass
    return buffer

#modify any requested destined for the remote host
def request_handler(buffer):
    #perform packet modifications
    return buffer

#modify any responses destined for the local host
def response_handler(buffer):
    #perform packet modifications
    return buffer

main()

i have tried different ftp servers/sites,etc but get the same result, where am i going wrong with my code? any input or direction would be greatly appreciated.

Body:
okay so turns out my script is good just the ftp servers i was running weren't haha
this is the final output:

anon@kali:~/Desktop/python scripts$ sudo python TCP\ proxy.py 127.0.0.1 21 ftp.uconn.edu 21 True
[*] Listening on 127.0.0.1:21d
[==>] Received incoming connection from 127.0.0.1:51532d
0000 32 32 30 20 50 72 6F 46 54 50 44 20 31 2E 32 2E  2 2 0   P r o F T P D   1 . 2 ./n0010 31 30 20 53 65 72 76 65 72 20 28 66 74 70 2E 75  1 0   S e r v e r   ( f t p . u/n0020 63 6F 6E 6E 2E 65 64 75 29 20 5B 31 33 37 2E 39  c o n n . e d u )   [ 1 3 7 . 9/n0030 39 2E 32 36 2E 35 32 5D 0D 0A                    9 . 2 6 . 5 2 ] . .
[<==] Sending 58 bytes to localhost.
[==>] Received 353 bytes from localhost.
[==>] Sent to remote.
[<==] Received 337 bytes from remote.


问:
Get Geometry of widgets with variable size
Situation

I have a pop_up widget (say a textbox), which I can place arbitrarily on the screen by setting the properties x and y accordingly.
On the other hand I use the prompt, which is located in the default wibar.

I would like to place the pop_up widget directly below the prompt

Problem

I was not yet able to gather any useful information about the geometry of the prompt. With geometry I mean its x and y values together with its height and width. I solved the y-positioning by using the height of the wibar itself.
But I am stuck with x-positioning.
Is there a way to get the width of the widgets within the toolbar?

Notice

I read something about forced_width, but in this situation it sounds like a hack to me. So I would prefer to avoid forcing any widths.

I'm currently running awesome WM 4.2 on Fedora 26

答:
Part of a problem is that "a" widget does not have a position and size since awesome allows widgets to be shown in multiple places at once. However, if we just ignore this problem, something like the following could work (to be honest: I did not test this):

```<code>function find_widget_in_wibox(wb, widget)
  local function find_widget_in_hierarchy(h, widget)
    if h:get_widget() == widget then
      return h
    end
    local result
    for _, ch in ipairs(h:get_children()) do
      result = result or find_widget_in_hierarchy(ch, widget)
    end
    return result
  end
  local h = wb._drawable._widget_hierarchy
  return h and find_widget_in_hierarchy(h, widget)
end
</code>```

However, I have to warn you that the above could break in newer versions of awesome since it access non-public API (the part with wb._drawable._widget_hierarchy). There is a way to work with just the public API using :find_widgets(), but I am too lazy for that for now.

The above function gets the wibox.hierarchy instance representing a widget which allows to get the geometry of the prompt via something like the following (in the default config of awesome 4.2):

```<code>local s = screen.primary -- Pick a screen to work with
local h = find_widget_in_wibox(s.mywibox, s.mypromptbox)
local x, y, width, height = h:get_matrix_to_device()
                             :transform_rectangle(0, 0, h:get_size())
local geo = s.mywibox:geometry()
x, y = x + geo.x, y + geo.y
print(string.format("The widget is inside of the rectangle (%d, %d, %d, %d) on the screen", x, y, width, height)
</code>```

Finally, note that the widget hierarchy is only updated during repaints. So, during startup the code above will fail to find the widget at all and right after something changed (e.g. you entered another character into the promptbox), the above will still "figure out" the old geometry.

Body:
Part of a problem is that "a" widget does not have a position and size since awesome allows widgets to be shown in multiple places at once. However, if we just ignore this problem, something like the following could work (to be honest: I did not test this):

function find_widget_in_wibox(wb, widget)
  local function find_widget_in_hierarchy(h, widget)
    if h:get_widget() == widget then
      return h
    end
    local result
    for _, ch in ipairs(h:get_children()) do
      result = result or find_widget_in_hierarchy(ch, widget)
    end
    return result
  end
  local h = wb._drawable._widget_hierarchy
  return h and find_widget_in_hierarchy(h, widget)
end

However, I have to warn you that the above could break in newer versions of awesome since it access non-public API (the part with wb._drawable._widget_hierarchy). There is a way to work with just the public API using :find_widgets(), but I am too lazy for that for now.

The above function gets the wibox.hierarchy instance representing a widget which allows to get the geometry of the prompt via something like the following (in the default config of awesome 4.2):

local s = screen.primary -- Pick a screen to work with
local h = find_widget_in_wibox(s.mywibox, s.mypromptbox)
local x, y, width, height = h:get_matrix_to_device()
                             :transform_rectangle(0, 0, h:get_size())
local geo = s.mywibox:geometry()
x, y = x + geo.x, y + geo.y
print(string.format("The widget is inside of the rectangle (%d, %d, %d, %d) on the screen", x, y, width, height)

Finally, note that the widget hierarchy is only updated during repaints. So, during startup the code above will fail to find the widget at all and right after something changed (e.g. you entered another character into the promptbox), the above will still "figure out" the old geometry.