Repository: kivy/python-for-android

Issue:
Websocket error: SSL not available 
Getting this error when attempting to open a secure websocket ('wss://') using websocket-client.

09-02 09:12:04.037 10328 10719 I python : [ERROR ] [MyApp] Websocket error: SSL not available.
09-02 09:12:04.037 10328 10719 I python : [INFO ] [MyApp] Websocket closed

Still happens after trying: 
* buildozer android clean 
* deleting the .buildozer directory and re-building
* issuing `buildozer android update` and `buildozer android clean` and update

buildozer requirements:

requirements = kivy==1.10.0, sqlite3, openssl, pyopenssl, pygments, websocket-client

Other notes:

* To get websocket-client to load I had to copy websocket-client source locally into my project as recommended here:  https://github.com/kivy/python-for-android/blob/master/pythonforandroid/recipes/websocket-client/__init__.py#L3

* I disabled the SSL check on websocket-client and found a lower level exception:

09-02 10:00:43.215 13478 13511 I python : [ERROR ] [MyApp] Websocket error: _ssl.c:331: No root certificates specified for verification of other-side certificates.

* SSL does work on my android build; elsewhere in our app we are successfully using https with urllib2. 





Discussion:
~~(strikethrough) update, I *can* run this example successfully~~

EDIT: I *cannot* get this example to run successfully in wss:// (secure) mode.
https://github.com/debauchery1st/example_kivy_websocket-recipe

~~Now digging into why mine works, first focusing on the buildozer spec differences. I see this example does not specify openssl or pyopenssl~~

To repro this problem, run the example here, and change the ws:// to wss:// to request secure mode.  
https://github.com/debauchery1st/example_kivy_websocket-recipe

CC @debauchery1st  - are you able to get SSL working with your websocket example?
Ok, a little bit more.  digging into the _ssl_compact.py in websocket-clinet, it looks like my python is being built without backports.ssl_match_hostname:

Getting this exception when it's trying to import backports:

No module named backports.ssl_match_hostname
I think I figured it out. 

Two things needed:
* backports.ssl-match-hostname in buildozer requirements
* needed ssl.CERT_NONE on cert_req parameter for the websocket run_forever: `ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})`

What's the next step? should py4a at least automatically include backports.ssl-match-hostname if SSL is included?
I'm not sure. I use ws4py and openssl module via requests. None of this is necessary. But thanks for the analysis
Thanks @tito  - I guess improving docs is the best solution, hopefully it's discoverable for the next person that runs across it

Resolving patch:
diff --git a/pythonforandroid/recipes/websocket-client/__init__.py b/pythonforandroid/recipes/websocket-client/__init__.py
--- a/pythonforandroid/recipes/websocket-client/__init__.py
+++ b/pythonforandroid/recipes/websocket-client/__init__.py
@@ -5,6 +5,12 @@
 #     copy the 'websocket' directory into your app directory to force inclusion.
 #
 # see my example at https://github.com/debauchery1st/example_kivy_websocket-recipe
+#
+# If you see errors relating to 'SSL not available' ensure you have the package backports.ssl-match-hostname
+# in the buildozer requirements, since Kivy targets python 2.7.x
+#
+# You may also need sslopt={"cert_reqs": ssl.CERT_NONE} as a parameter to ws.run_forever() if you get an error relating to
+# host verification
 
 
 class WebSocketClient(Recipe):


Test patch: