[IronPython] ssl server mode issue
Dino Viehland
dinov at microsoft.com
Mon Apr 26 22:02:34 CEST 2010
That’s working for me as well. I went ahead and added a do_GET implementation to the ProxyHandler class:
def do_GET(self):
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
stdout = sys.stdout
self.wfile.write('<html><body>hi' + str(datetime.datetime.now()) + '</body></html>')
I generated the key by doing:
C:\OpenSSL\bin\openssl.exe req -new -x509 -days 365 -nodes -out cert.pem -keyout cert.pem
And I’m able to successfully able to make requests to both CPython and IronPython from IE and FireFox.
So I guess the next possible questions would be what version of Windows you’re running on and did you create the certificate on Windows (maybe there’s some difference in OpenSSL between the two platforms?) Also are you using the .NET 2 version or the .NET 4 version? Also does my end-to-end repro demonstrate the problem for you or are you doing something different?
From: users-bounces at lists.ironpython.com [mailto:users-bounces at lists.ironpython.com] On Behalf Of qiuyingbo at sohu.com
Sent: Thursday, April 22, 2010 5:40 PM
To: Discussion of IronPython
Subject: Re: [IronPython] ssl server mode issue
I generated certificate as the instruction of http://docs.python.org/library/ssl.html:
openssl req -new -x509 -days 365 -nodes -out cert.pem -keyout cert.pem
----- 原文 -----
发件人: Dino Viehland
主 题: Re: [IronPython] ssl server mode issue
时 间: 2010年4月23日 6:46:11
Ok, took me a while to get back to this, but I haven’t forgotten. So I’ve taken your code below and combined it with the code in test_ssl to have the full end to end test case. I’ve included that here. Let me know if there’s anything that’s significantly different.
First thing I tried w/ this was using the ‘keycert.pem’ which copes with the CPython test case and that seemed to behave similarly between IronPython and CPython. There does seem to be one difference which is with CPython the connection from the browser stays open and w/ IronPython it closes. This is after a GET request which we can’t respond to:
DINOV1.redmond.corp.microsoft.com - - [22/Apr/2010 15:38:16] code 501, message Unsupported method ('GET')
DINOV1.redmond.corp.microsoft.com - - [22/Apr/2010 15:38:16] "GET / HTTP/1.1" 501 –
That’s probably a bug but not the issue you’re running into but I’ve opened a bug here: http://ironpython.codeplex.com/WorkItem/View.aspx?WorkItemId=26852.
So then I generated a self-signed request as described here: http://sial.org/howto/openssl/self-signed/ with a .cnf file as described here: http://bugs.gentoo.org/show_bug.cgi?id=251047 but minus the x509_extensions line. With that I get the same result as I get with keycert.pem.
So my guess is that I’m not generating the self signed certificate in the same way that you are and that there’s something about your cert which doesn’t work. Does your generation differ from what I did?
import BaseHTTPServer
from BaseHTTPServer import HTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler
import threading
import socket
import sys
import traceback
import ssl
CERTFILE = 'host.pem'
HOST='localhost'
import time
class ProxyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_CONNECT(self):
print self.raw_requestline
# "CONNECT twitter.com:443 HTTP/1.1"
self.sslhost = self.raw_requestline.split()[1]
self.wfile.write(self.protocol_version + " 200 Connection established\r\n")
self.wfile.write("Proxy-agent: qiuyingbo\r\n\r\n")
self.rfile = pseudofile(ssl.wrap_socket(self.connection, None, CERTFILE, True))
self.wfile = self.rfile
self.handle_one_request()
class SocketServerHTTPSServer(threading.Thread):
class HTTPSServer(HTTPServer):
def __init__(self, server_address, RequestHandlerClass, certfile):
HTTPServer.__init__(self, server_address, RequestHandlerClass)
# we assume the certfile contains both private key and certificate
self.certfile = certfile
self.active = False
self.active_lock = threading.Lock()
self.allow_reuse_address = True
def __str__(self):
return ('<%s %s:%s>' %
(self.__class__.__name__,
self.server_name,
self.server_port))
def get_request (self):
# override this to wrap socket with SSL
sock, addr = self.socket.accept()
sslconn = ssl.wrap_socket(sock, server_side=True,
certfile=self.certfile)
return sslconn, addr
# The methods overridden below this are mainly so that we
# can run it in a thread and be able to stop it from another
# You probably wouldn't need them in other uses.
def server_activate(self):
# We want to run this in a thread for testing purposes,
# so we override this to set timeout, so that we get
# a chance to stop the server
self.socket.settimeout(0.5)
HTTPServer.server_activate(self)
def serve_forever(self):
# We want this to run in a thread, so we use a slightly
# modified version of "forever".
self.active = True
while 1:
try:
# We need to lock while handling the request.
# Another thread can close the socket after self.active
# has been checked and before the request is handled.
# This causes an exception when using the closed socket.
with self.active_lock:
if not self.active:
break
self.handle_request()
except socket.timeout:
pass
except KeyboardInterrupt:
self.server_close()
return
except:
sys.stdout.write(''.join(traceback.format_exception(*sys.exc_info())))
break
time.sleep(0.1)
def server_close(self):
# Again, we want this to run in a thread, so we need to override
# close to clear the "active" flag, so that serve_forever() will
# terminate.
with self.active_lock:
HTTPServer.server_close(self)
self.active = False
def __init__(self, certfile):
self.flag = None
self.active = False
self.port = 1234
self.server = self.HTTPSServer(
(HOST, self.port), ProxyHandler, certfile)
threading.Thread.__init__(self)
self.daemon = True
def __str__(self):
return "<%s %s>" % (self.__class__.__name__, self.server)
def start (self, flag=None):
self.flag = flag
threading.Thread.start(self)
def run (self):
self.active = True
if self.flag:
self.flag.set()
self.server.serve_forever()
self.active = False
def stop (self):
self.active = False
self.server.server_close()
class pseudofile():
''' SSL Pseudo File Object'''
def __init__(self, sslobj):
self.sslobj = sslobj
self.closed = 0
def read(self, size):
chunks = []
read = 0
while read < size:
data = self.sslobj.read(size-read)
read += len(data)
chunks.append(data)
return ''.join(chunks)
def readline(self):
line = []
while 1:
char = self.sslobj.read(1)
line.append(char)
if char == "\n": return ''.join(line)
def write(self, data):
bytes = len(data)
while bytes > 0:
sent = self.sslobj.write(data)
if sent == bytes:
break # avoid copy
data = data[sent:]
bytes = bytes - sent
def flush(self):
pass
close = flush
server=SocketServerHTTPSServer(CERTFILE)
flag = threading.Event()
server.start(flag)
# wait for it to start
flag.wait()
print 'started'
time.sleep(100000)
From: users-bounces at lists.ironpython.com [mailto:users-bounces at lists.ironpython.com] On Behalf Of qiuyingbo at sohu.com
Sent: Wednesday, April 14, 2010 5:41 PM
To: Discussion of IronPython
Subject: Re: [IronPython] ssl server mode issue
I'm doing a web browser to ironpython connection. It is difficult to explain what I am doing, I'm hacking a http proxy that inherit BaseHTTPServer.BaseHTTPRequestHandler. Next code snippets show how I support HTTPS proxy.. (Linux version run well)
class ProxyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_CONNECT(self):
# print self.raw_requestline
# "CONNECT twitter.com:443 HTTP/1.1"
self.sslhost = self.raw_requestline.split()[1]
self.wfile.write(self.protocol_version + " 200 Connection established\r\n")
self.wfile.write("Proxy-agent: qiuyingbo\r\n\r\n")
import ssl
self.rfile = pseudofile(ssl.wrap_socket(self.connection, None, CERTFILE, True))
self.wfile = self.rfile
self.handle_one_request()
class pseudofile():
''' SSL Pseudo File Object'''
def __init__(self, sslobj):
self.sslobj = sslobj
self.closed = 0
def read(self, size):
chunks = []
read = 0
while read < size:
data = self.sslobj.read(size-read)
read += len(data)
chunks.append(data)
return ''.join(chunks)
def readline(self):
line = []
while 1:
char = self.sslobj.read(1)
line.append(char)
if char == "\n": return ''.join(line)
def write(self, data):
bytes = len(data)
while bytes > 0:
sent = self.sslobj.write(data)
if sent == bytes:
break # avoid copy
data = data[sent:]
bytes = bytes - sent
def flush(self):
pass
close = flush
_______________________________________________
Users mailing list
Users at lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/ironpython-users/attachments/20100426/e2d5f970/attachment.html>
More information about the Ironpython-users
mailing list