couchbase / couchbase-lite-java-listener

Embedded web server to expose Couchbase Lite REST API on an http socket
Apache License 2.0
12 stars 32 forks source link

CBL Local server responds "cors":"rejected" on https/http mode. #78

Open NitzDKoder opened 7 years ago

NitzDKoder commented 7 years ago

Hi Folks,

1) Cordova based access to CBL using CBL listener. https://github.com/couchbaselabs/Couchbase-Lite-PhoneGap-Plugin

2)When applied HTTPS to local server as per below link https://developer.couchbase.com/documentation/mobile/1.2/develop/guides/couchbase-lite/tech-notes/p2p-replications-ssl/index.html

3) Any get request from Java-scripts is getting ""cors":"rejected""


    Line 1543: 12-23 17:06:46.901 24666-25270/? D/[HTML5LOG]: ReSTCBL ::: Request started::{"id":"2: GET https://username:password@localhost:portnumber/databasename"}
    Line 1554: 12-23 17:06:46.931 24666-25270/? D/[HTML5LOG]: ReSTCBL ::: Got response::{"id":"2: GET https://username:password@localhost:portnumber/databasename","status":0}
    Line 1556: 12-23 17:06:46.931 24666-25270/? D/[HTML5LOG]: ["cblPtxInterface.launchCBL()-> setupDb()-> Before db GET = ",{"cors":"rejected"},{"seq_id":2,"id":"2: GET https://username:password@localhost:portnumber/databasename","_id":"2: GET https://username:password@localhost:portnumber/databasename","timeoutTimer":23,"statusCode":0},null]
    Line 1556: 12-23 17:06:46.931 24666-25270/? D/[HTML5LOG]: ["cblPtxInterface.launchCBL()-> setupDb()-> Before db GET = ",{"cors":"rejected"},{"seq_id":2,"id":"2: GET https://username:password@localhost:portnumber/databasename","_id":"2: GET https://username:password@localhost:portnumber/databasename","timeoutTimer":23,"statusCode":0},null]
    Line 1558: 12-23 17:06:46.941 24666-25270/? D/[HTML5LOG]: ReSTCBL ::: Request started::{"id":"3: GET https://username:password@localhost:portnumber/databasename"}

4)Router code needs this change? Yet to do this change.

if ("OPTIONS".equals(request.getMethod())){
    response.setStatus(200);
    return true;
}

https://forums.couchbase.com/t/cannot-connect-to-db-lite-couchbase-on-ios-10/10318/6 https://github.com/couchbase/couchbase-lite-java-core/blob/8817e7976427824dcaea5e8687ce20b29cc6e94b/src/main/java/com/couchbase/lite/router/Router.java#L417

PS: Http mode works well.

Thanks Nithin

NitzDKoder commented 7 years ago

@hideki trying to achieve this below.. pls share your thoughts?

https://github.com/couchbase/couchbase-lite-java-listener/issues/48#issuecomment-260729093

hideki commented 7 years ago

Hi @NitzDKoder, I don't know what causes CORS issue. Can you investigate little further by yourself?

NitzDKoder commented 7 years ago

@hideki didnt find much on this.. on below use case we see cros issue.

NON- HTTPS CBL listener; 1)Cordova based application(Activity/Service) started and CBL listener is started.Sync works well. 2)Activity and application is stopped by unknown process. I am_kill : [0,27751,com.XXX.XXX,0,stop com.XXX.XXXs cause from pid 29040] 3) New session created and CBL listener is again started and we see cors error on get request.

@pasin pls share your thoughts on this..

NitzDKoder commented 7 years ago

@hideki thanks for the inputs..

"I believe you are using latest CBL v1.3.1 or build from the master branch which uses OkHttp. And you refer 1.2 documentation for SSL. CBL 1.2.x or earlier uses HttpClient. I verified 1.2.x works with SSL. So far, I have not verified if SSL works with 1.3.x or higher. "cors":"rejected" issue might be caused by OkHttp and tjws combination??"

We are using 1.3.1 CBL + okhttp + TJWS.. have not tried in 1.2.x

Thanks Nithin

NitzDKoder commented 7 years ago

@hideki we found the issue.. Basically its not cors issue here..

Problem:

1) Server was started and was in process of starting. 2) local URL was formed and get DB request was made, and server was not started yet. 3)All our requests are treated as is_crossDomain true https://github.com/couchbaselabs/TodoLite-PhoneGap/blob/master/js/modules.js#L1523

need to check the reason yet why true always.

4)As the server was not started and statusCode was 0. CORS was detected. https://github.com/couchbaselabs/TodoLite-PhoneGap/blob/master/js/modules.js#L1361

// Detect failed CORS requests.
    if(is_cors && xhr.statusCode == 0) {
      var cors_err = new Error('CORS request rejected: ' + options.uri)
      cors_err.cors = 'rejected'

      // Do not process this request further.
      did.loading = true
      did.end = true

      return options.callback(cors_err, xhr)
    }

Pls share your thoughts..

Solution: Make sure server is started and running and then make request.

Thanks Nithin

hideki commented 7 years ago

@NitzDKoder, JavaScript file is provided as a reference implementation. It might have an issue in the codes. I believe there is a bug in function is_crossDomain(url) method. Can you fix it to return false or throw the exception if the URL is not reachable??

NitzDKoder commented 7 years ago

@hideki pls ignore previous problem statement.. Sever gets up immediately after start.

New problem statement. Use case 1: 1) Server was started and running. 2) Https mode and android:debuggable="false" https://developer.couchbase.com/documentation/mobile/1.2/develop/guides/couchbase-lite/tech-notes/p2p-replications-ssl/index.html 3) parseRequest method, ServletInputStream returns -1. Socket getting exhausted.

 03-24 09:08:57.449 D/[HTML5LOG]( 3245): ReSTCBL ::hoax requestget
03-24 09:08:57.459 D/[HTML5LOG]( 3245): ReSTCBL ::: Request started::{"id":"1: GET https://:@localhost:33159/ptxdata"}
03-24 09:08:57.579 W/System.err( 3245): [03/24 09:08:57.589] [3] Sync: parseRequest called socketSocket[address=localhost/::1,port=52294,localPort=33159]
03-24 09:08:57.769 W/System.err( 3245): [03/24 09:08:57.774] [3] Sync: parseRequest readLine length :-1
03-24 09:08:57.789 D/[HTML5LOG]( 3245): ReSTCBL ::: Got response::{"id":"1: GET https://:@localhost:33159/ptxdata","status":0}

https://github.com/couchbase/couchbase-lite-java-listener/blob/master/vendor/tjws/src/java/Acme/Serve/Serve.java#L2173

4)All our requests are treated as is_crossDomain true https://github.com/couchbaselabs/TodoLite-PhoneGap/blob/master/js/modules.js#L1523.

With above 3 problem response statusCode was 0 , CORS was detected.

Use case 2: 1) Server was started and running. 2) Https mode and android:debuggable="true" https://developer.couchbase.com/documentation/mobile/1.2/develop/guides/couchbase-lite/tech-notes/p2p-replications-ssl/index.html

3)Server was able to parse the request and respond to 200 ok.

03-24 09:45:00.189 D/[HTML5LOG]( 3208): ReSTCBL ::: Request started::{"id":"1: GET https://:@localhost:58400/ptxdata"}
[03/24 09:45:05.354] [3] Sync: parseRequest called socketSocket[address=::1/::1,port=37885,localPort=58400]
 [03/24 09:45:05.390] [3] Sync: parseRequest readLine length :-1
 [03/24 09:45:05.458] [3] Sync: parseRequest called socketSocket[address=::1/::1,port=37888,localPort=58400]
[03/24 09:45:05.461] [3] Sync: parseRequest readLine length :23
 [03/24 09:45:05.504] [3] Sync: parseRequest runServlet start
 [03/24 09:45:05.637] [3] Sync: parseRequest runServlet end
-24 09:45:05.659 D/[HTML5LOG]( 3208): ReSTCBL ::: Got response::{"id":"1: GET https://:@localhost:58400/ptxdata","status":200}

android:debuggable="true" vs android:debuggable="false" is making server socket to behave differently.

Pls share your thoughts..

Thanks Nithin

hideki commented 7 years ago

Honestly, I don't know how android:debuggable configuration affects IO, socket, etc Android internally.

https://developer.android.com/guide/topics/manifest/application-element.html#debug

NitzDKoder commented 7 years ago

Found this.. https://forum.ionicframework.com/t/https-status-0-in-the-release-build/44512

NitzDKoder commented 7 years ago

@hideki this answere.. https://forum.ionicframework.com/t/https-connection-with-self-signed-certificate/12974/12 Need to find proper production hook.

hideki commented 7 years ago

Hi @NitzDKoder, Thank you for sharing links. This is really useful information. And I did not realize it till you shared. I wonder if any self-signed certificates don't work with a release build?

NitzDKoder commented 7 years ago

@hideki yes release android with cordova based app will not work with self singed certificate. TJWS will accept certificate by Valid CA.?https://github.com/drogatkin/TJWS2/issues/6 That will solve my problem.

Thanks Nithin

hideki commented 7 years ago

@NitzDKoder, I believe that certification verification should be provided by Android (JRE). And TJWS just uses it. Valid certificate should work fine.

https://developer.android.com/training/articles/security-ssl.html

NitzDKoder commented 7 years ago

@hideki But we have android webview throwing CN validation issue.(ERR_CERT_COMMON_NAME_INVALID )

Local server URL: https://localhost:18641/data Certificate CN=*.mycompany.com,

The common name represents the name protected by the SSL certificate. The certificate is valid only if the request hostname matches the certificate common name.

https://support.dnsimple.com/articles/what-is-common-name/

http://stackoverflow.com/questions/138705/security-implications-of-disabling-the-common-name-check-for-https

http://unix.stackexchange.com/questions/138700/is-validation-of-cn-hostname-verification-against-ssl-certificate-required-in-op

Pls share your thoughts... Is this couchbase-lite-java-listener is production ready?

Thanks Nithin

hideki commented 7 years ago

Hi @NitzDKoder, For P2P, you could ignore hostname verification by creating custom SSLFactory.

NitzDKoder commented 7 years ago

@hideki https://developer.couchbase.com/documentation/mobile/current/guides/couchbase-lite/index.html Provides Native APIs for iOS, Android and .NET. With the Native APIs, you can map database documents to your own native object model, work directly with JSON structures, or both. Additionally, apps built with web technologies, such as JavaScript, can use the Couchbase Lite REST APIs to develop hybrid mobile apps.

Here the browser is the client and doing ssl stuffs and throwing the error, so you are saying to add hook at cordova?

Thanks Nithin

hideki commented 7 years ago

@NitzDKoder, Sorry, I don't know other solutions to fix this without changing SSLFactory.

As the error occurs in the browser, so replacing SSLFactory in CBL does not solve the problem.

NitzDKoder commented 7 years ago

Ok thanks.. @pasin @jens pls share your thoughts here..

Design:

Cordoava based android app.

https://github.com/couchbase/couchbase-lite-ios/wiki/LiteServ-With-SSL

https://github.com/couchbaselabs/TodoLite-PhoneGap/blob/master/js/modules.js

Android Browser/JavaScript doing xhr https REST requests done to TJWS(java sever with official certificate applied ) and getting SSL error.

Thanks Nithin

NitzDKoder commented 7 years ago

@hideki tweaked cordova to ignore hostname verification. Things are ok now. Will update more soon.