Skip to content

Instantly share code, notes, and snippets.

@mthurman
Created April 3, 2014 21:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mthurman/9963741 to your computer and use it in GitHub Desktop.
Save mthurman/9963741 to your computer and use it in GitHub Desktop.
requests + urllib3 + pyopenssl ZeroReturnError
pip install ndg-httpsclient==0.3.2 pyasn1==0.1.7 pyOpenSSL==0.13.1 requests==2.2.1
# with a cert.pem file in the same directory as ssl_server.py
python ssl_server.py
# in another terminal with same virtualenv
python ssl_client.py
import OpenSSL
import requests
def make_request(label, host, port):
print label
print "============"
try:
resp = requests.get("https://%s:%s" % (host, port), verify=False)
print resp.status_code
except OpenSSL.SSL.ZeroReturnError:
print "ZeroReturnError"
import traceback, sys
traceback.print_exc(file=sys.stdout)
if __name__ == "__main__":
host = 'localhost'
port = 9999
make_request("With pyopenssl", host, port)
requests.pyopenssl.extract_from_urllib3()
make_request("\n\nNo pyopenssl", host, port)
# Based on from http://pastebin.com/1PDX3HRY
#!/usr/bin/env python
# Copyright (C) 2012 Biggie
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import socket
import SocketServer
import threading
import time
from OpenSSL import SSL
class MyRequestHandler(SocketServer.StreamRequestHandler):
"""The MyRequestHandler-class is used to handle a client in
its own thread"""
def setup(self):
"""setup is called to set up the new client connection."""
# ----
# Instead of using SocketServer.StreamRequestHandler.setup(self):
# self.connection = self.request
# self.rfile = self.connection.makefile('rb', self.rbufsize)
# self.wfile = self.connection.makefile('wb', self.wbufsize)
# Use the following (because of ssl-usage):
# ----
self.connection = self.request
self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
# The connection-lock is used to prevent closing the connection
# while data is written
self.connection_lock = threading.Lock()
self.connected = True
def finish(self):
"""finish is called if the connection to the client is closed."""
with self.connection_lock:
SocketServer.StreamRequestHandler.finish(self)
self.connected = False
def readline(self):
"""Read a new line from the client.socket.
Returns an empty string if an error occurred or the socket was
closed.
"""
line = ""
if self.connected and not self.rfile.closed:
try:
line = self.rfile.readline()
except socket.error, e:
print 'error occurred while reading:', e
except SSL.SysCallError, e:
pass
except SSL.Error, e:
pass # maybe client does not use ssl
return line
def write(self, data):
"""Write data to the client-socket.
data -- the data to send
"""
with self.connection_lock:
if self.connected:
if not self.wfile.closed:
try:
self.wfile.write(data)
except socket.error, e:
print 'error occurred while writing:', e
def handle(self):
"""handle is called to handle the new client."""
line = True
while line:
# self.rfile is a file-like object created by the handler
line = self.readline().strip()
# self.write('HTTP/1.0 200 OK\r\nContent-Length: 0\r\n\r\n')
return
class MyTCPServer(SocketServer.TCPServer):
"""The MyThreadedTCPServer is the TCP-server and handles each client in its
own thread."""
def __init__(self, certfile, server_address, RequestHandlerClass,
bind_and_activate=True):
"""Initialize the MyThreadedTCPServer.
certfile -- The cert-file which should be used for SSL
sockets. If None, no SSL-sockets will be used.
server_address, RequestHandlerClass, bind_and_activate
-- see SocketServer.TCPServer.__init__
"""
self.use_ssl = True
# Code taken from SocketServer.TCPServer.__init__
# and added ssl-support:
SocketServer.BaseServer.__init__(self, server_address,
RequestHandlerClass)
ctx = SSL.Context(SSL.SSLv23_METHOD)
# cert.pem-file containing the server private key and certificate
cert = certfile
ctx.use_privatekey_file(cert)
ctx.use_certificate_file(cert)
self.socket = SSL.Connection(ctx, socket.socket(self.address_family,
self.socket_type))
if bind_and_activate:
self.server_bind()
self.server_activate()
def shutdown_request(self,request):
request.shutdown()
if __name__ == "__main__":
try:
server = MyTCPServer('cert.pem', ('localhost', 9999), MyRequestHandler)
server.serve_forever()
while True: time.sleep(100)
except (KeyboardInterrupt, SystemExit):
server.shutdown()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment