Re: PyOpenSSL empty socket property

Glyph <[email protected]> Sun, 8 Sep 2019 20:32:19 -0700
Newsgroups gmane.comp.python.twisted
Message-ID <[email protected]>
--===============5705995186937567742==
Content-Type: multipart/alternative;
	boundary="Apple-Mail=_85FD3470-399C-4483-BD25-5D47DBFC9434"


--Apple-Mail=_85FD3470-399C-4483-BD25-5D47DBFC9434
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
	charset=us-ascii

Indeed, in Twisted, the SSL.Connection is constructed with a memory BIO. =
And in fact there may not be a socket in the loop at all!

What are you trying to do with `getpeername()`?  Hopefully there's a =
similar Twisted API that you could work with.

-glyph

> On Sep 5, 2019, at 11:07 PM, Sean DiZazzo <[email protected]> =
wrote:
>=20
> Perhaps this line from OpenSSL.SSL.Connection is a clue.
>=20
> "socket may be None; in this case, the Connection is created with a =
memory BIO: see the bio_read(), bio_write(), and bio_shutdown() =
methods."
> =
https://www.pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.Connection =
<https://www.pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.Connection>
>=20
> On Wed, Sep 4, 2019 at 1:38 AM Arn Vollebregt =
<[email protected] <mailto:[email protected]>> =
wrote:
> Hi,
>=20
> I noticed that PyOpenSSL SNI callbacks (set with =
ctx.set_tlsext_servername_callback) receive a OpenSSL.SSL.Connection =
object within Twisted that have an empty _socket property, while this =
property is actually set when using PyOpenSSL directly. For my use-case =
this is a problem as I want to call conn._socket.getpeername() to =
determine the peer's IP address. So I am wondering: why is this =
behaviour different? And how do I get the peer IP address?
>=20
> ---console---
> user:~$ sudo python testTwisted.py &
> [3] 32842
> user:~$ curl -s --insecure --key clientPrivateKey.pem --cert =
clientCertificate.pem https://127.0.0.1 <https://127.0.0.1/> > /dev/null
> 'sniCallback' called.
>         conn._socket: None
> 'verifyCallback' called for result 0
>         conn._socket: None
> 'verifyCallback' called for result 1
>         conn._socket: None
> user:~$ sudo python testPyOpenSSL.py &
> [1] 33270
> user:~$ curl -s --insecure --key clientPrivateKey.pem --cert =
clientCertificate.pem https://127.0.0.1 <https://127.0.0.1/> > /dev/null
> 'sniCallback' called.
>         conn._socket: <socket._socketobject object at 0x7f34c5bd3130>
> <class 'OpenSSL.SSL.Connection'>
> 'verifyCallback' called for result 0
>         conn._socket: <socket._socketobject object at 0x7f34c5bd3130>
> 'verifyCallback' called for result 1
>         conn._socket: <socket._socketobject object at 0x7f34c5bd3130>
> 127.0.0.1 - - [29/Aug/2019 11:45:47] "GET / HTTP/1.1" 200 -
> ------
>=20
> ---testTwisted.py---
> ### Generate server key material ###
> # openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout =
serverPrivateKey.pem -out serverCertificate.pem -subj =
"/C=3D''/O=3D''/OU=3D''/CN=3Dserver"
> ### Generate client key material ###
> # openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout =
clientPrivateKey.pem -out clientCertificate.pem -subj =
"/C=3D''/O=3D''/OU=3D''/CN=3Dclient"
> from __future__ import print_function
> #https://twistedmatrix.com/documents/12.0.0/core/howto/ssl.html =
<https://twistedmatrix.com/documents/12.0.0/core/howto/ssl.html>
> from OpenSSL import SSL
> from twisted.internet import ssl, reactor
> from twisted.web import server, resource
> from twisted.internet.protocol import Factory, Protocol
>=20
> def verifyCallback(conn, cert, errno, depth, result):
>     print('\'verifyCallback\' called for result ' + str(result))
>     print('\tconn._socket: ' + str(conn._socket))
>     return True
>=20
> def sniCallback(conn):
>     print('\'sniCallback\' called.')
>     print('\tconn._socket: ' + str(conn._socket))
>=20
> class MainResource(resource.Resource):
>     isLeaf =3D True
>=20
>     def render_GET(self, request):
>         request.responseHeaders.addRawHeader("Content-Type", =
"text/html; charset=3Dutf-8")
>         return b"<html><body>Hello World</body></html>"
>=20
> if __name__ =3D=3D '__main__':
>     myContextFactory =3D ssl.DefaultOpenSSLContextFactory(
>         'serverPrivateKey.pem',
>         'serverCertificate.pem'
>     )
>     ctx =3D myContextFactory.getContext()
>     # =
https://www.pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.Context.set_v=
erify =
<https://www.pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.Context.set_=
verify>
>     ctx.set_verify(SSL.VERIFY_PEER, verifyCallback)
>     # =
https://pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.Context.set_tlsex=
t_servername_callback =
<https://pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.Context.set_tlse=
xt_servername_callback>
>     ctx.set_tlsext_servername_callback(sniCallback)
>=20
>     site =3D server.Site(MainResource())
>     reactor.listenSSL(443, site, myContextFactory)
>     reactor.run()
> ------
>=20
> ---testPyOpenSSL.py---
> ### Generate server key material ###
> # openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout =
serverPrivateKey.pem -out serverCertificate.pem -subj =
"/C=3D''/O=3D''/OU=3D''/CN=3Dserver"
> ### Generate client key material ###
> # openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout =
clientPrivateKey.pem -out clientCertificate.pem -subj =
"/C=3D''/O=3D''/OU=3D''/CN=3Dclient"
> from __future__ import print_function
> import socket, sys, os
> from SocketServer import BaseServer
> from BaseHTTPServer import HTTPServer
> from SimpleHTTPServer import SimpleHTTPRequestHandler
> from OpenSSL import SSL
>=20
> def verifyCallback(conn, cert, errno, depth, result):
>     print('\'verifyCallback\' called for result ' + str(result))
>     print('\tconn._socket: ' + str(conn._socket))
>     return True
>=20
> def sniCallback(conn):
>     print('\'sniCallback\' called.')
>     print('\tconn._socket: ' + str(conn._socket))
>     print(type(conn))
>=20
> class SecureHTTPServer(HTTPServer):
>     def __init__(self, server_address, HandlerClass):
>         BaseServer.__init__(self, server_address, HandlerClass)
>         ctx =3D SSL.Context(SSL.TLSv1_2_METHOD)
>         ctx.use_privatekey_file('serverPrivateKey.pem')
>         ctx.use_certificate_file('serverCertificate.pem')
>         # =
https://www.pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.Context.set_v=
erify =
<https://www.pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.Context.set_=
verify>
>         ctx.set_verify(SSL.VERIFY_PEER, verifyCallback)
>         # =
https://pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.Context.set_tlsex=
t_servername_callback =
<https://pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.Context.set_tlse=
xt_servername_callback>
>         ctx.set_tlsext_servername_callback(sniCallback)
>         self.socket =3D SSL.Connection(ctx, =
socket.socket(self.address_family,self.socket_type))
>         self.server_bind()
>         self.server_activate()
>    =20
>     def shutdown_request(self,request):
>         request.shutdown()
>=20
> class SecureHTTPRequestHandler(SimpleHTTPRequestHandler):
>     def setup(self):
>         self.connection =3D self.request
>         self.rfile =3D socket._fileobject(self.request, "rb", =
self.rbufsize)
>         self.wfile =3D socket._fileobject(self.request, "wb", =
self.wbufsize)
>    =20
>     def do_GET(self):
>         self.send_response(200)
>         SimpleHTTPRequestHandler.end_headers(self)
>         self.wfile.write('<html><body>Hello World</body></html>')
>=20
> if __name__ =3D=3D '__main__':
>     ip,port =3D ('0.0.0.0', 443)
>     httpd =3D SecureHTTPServer((ip, port), SecureHTTPRequestHandler)
>     httpd.serve_forever()
> ------
>=20
> (Please note that even though these examples are for Python2 (due to =
other quirks) I am aiming to implement this in Python3.)
>=20
> Regards,
>=20
> Arn
> _______________________________________________
> Twisted-Python mailing list
> [email protected] =
<mailto:[email protected]>
> https://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python =
<https://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python>
> _______________________________________________
> Twisted-Python mailing list
> [email protected]
> https://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python


--Apple-Mail=_85FD3470-399C-4483-BD25-5D47DBFC9434
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html;
	charset=us-ascii

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html; =
charset=3Dus-ascii"></head><body style=3D"word-wrap: break-word; =
-webkit-nbsp-mode: space; line-break: after-white-space;" =
class=3D"">Indeed, in Twisted, the SSL.Connection is constructed with a =
memory BIO. And in fact there may not be a socket in the loop at =
all!<div class=3D""><br class=3D""></div><div class=3D"">What are you =
trying to do with `getpeername()`? &nbsp;Hopefully there's a similar =
Twisted API that you could work with.<br class=3D""><div class=3D""><br =
class=3D""></div><div class=3D"">-glyph<br class=3D""><div><br =
class=3D""><blockquote type=3D"cite" class=3D""><div class=3D"">On Sep =
5, 2019, at 11:07 PM, Sean DiZazzo &lt;<a =
href=3D"mailto:[email protected]" =
class=3D"">[email protected]</a>&gt; wrote:</div><br =
class=3D"Apple-interchange-newline"><div class=3D""><div dir=3D"ltr" =
class=3D""><div dir=3D"ltr" class=3D"">Perhaps this line from =
OpenSSL.SSL.Connection is a clue.<div class=3D""><br class=3D""></div><div=
 class=3D"">"socket may be None; in this case, the Connection is created =
with a memory BIO: see the bio_read(), bio_write(), and bio_shutdown() =
methods."<div class=3D""><a =
href=3D"https://www.pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.Conne=
ction" =
class=3D"">https://www.pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.Co=
nnection</a><span =
style=3D"color:rgb(64,64,64);font-family:Lato,proxima-nova,&quot;Helvetica=
 =
Neue&quot;,Arial,sans-serif;font-size:16px;background-color:rgb(252,252,25=
2)" class=3D""><br class=3D""></span></div></div><input =
name=3D"virtru-metadata" type=3D"hidden" =
value=3D"{&quot;email-policy&quot;:{&quot;state&quot;:&quot;closed&quot;,&=
quot;expirationUnit&quot;:&quot;days&quot;,&quot;disableCopyPaste&quot;:fa=
lse,&quot;disablePrint&quot;:false,&quot;disableForwarding&quot;:false,&qu=
ot;enableNoauth&quot;:false,&quot;persistentProtection&quot;:false,&quot;e=
xpandedWatermarking&quot;:false,&quot;expires&quot;:false,&quot;isManaged&=
quot;:false},&quot;attachments&quot;:{},&quot;compose-id&quot;:&quot;1&quo=
t;,&quot;compose-window&quot;:{&quot;secure&quot;:false}}" =
class=3D""></div><br class=3D""><div class=3D"gmail_quote" style=3D""><div=
 dir=3D"ltr" class=3D"gmail_attr">On Wed, Sep 4, 2019 at 1:38 AM Arn =
Vollebregt &lt;<a href=3D"mailto:[email protected]" =
class=3D"">[email protected]</a>&gt; wrote:<br =
class=3D""></div><blockquote class=3D"gmail_quote" style=3D"margin:0px =
0px 0px 0.8ex;border-left:1px solid =
rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr" class=3D""><div =
class=3D"">Hi,</div><div class=3D""><br class=3D""></div><div class=3D"">I=
 noticed that PyOpenSSL SNI callbacks (set with <i =
class=3D"">ctx.set_tlsext_servername_callback</i>) receive a <i =
class=3D"">OpenSSL.SSL.Connection</i> object within Twisted that have an =
empty <i class=3D"">_socket</i> property, while this property <u =
class=3D"">is</u> actually set when using <i class=3D"">PyOpenSSL</i> =
directly. For my use-case this is a problem as I want to call <i =
class=3D"">conn._socket.getpeername()</i> to determine the peer's IP =
address. So I am wondering: why is this behaviour different? And how do =
I get the peer IP address?</div><div class=3D""><br class=3D""></div><div =
class=3D"">---console---</div><div class=3D"">user:~$ sudo python =
testTwisted.py &amp;</div><div class=3D"">[3] 32842</div><div =
class=3D"">user:~$ curl -s --insecure --key clientPrivateKey.pem --cert =
clientCertificate.pem <a href=3D"https://127.0.0.1/" target=3D"_blank" =
class=3D"">https://127.0.0.1</a> &gt; /dev/null<br =
class=3D"">'sniCallback' called.<br class=3D"">&nbsp; &nbsp; &nbsp; =
&nbsp; conn._socket: None<br class=3D"">'verifyCallback' called for =
result 0<br class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; conn._socket: None<br =
class=3D"">'verifyCallback' called for result 1<br class=3D"">&nbsp; =
&nbsp; &nbsp; &nbsp; conn._socket: None</div><div class=3D"">user:~$ =
sudo python testPyOpenSSL.py &amp;<br class=3D"">[1] 33270</div><div =
class=3D"">user:~$ curl -s --insecure --key clientPrivateKey.pem --cert =
clientCertificate.pem <a href=3D"https://127.0.0.1/" target=3D"_blank" =
class=3D"">https://127.0.0.1</a> &gt; /dev/null<br =
class=3D"">'sniCallback' called.<br class=3D"">&nbsp; &nbsp; &nbsp; =
&nbsp; conn._socket: &lt;socket._socketobject object at =
0x7f34c5bd3130&gt;<br class=3D"">&lt;class =
'OpenSSL.SSL.Connection'&gt;<br class=3D"">'verifyCallback' called for =
result 0<br class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; conn._socket: =
&lt;socket._socketobject object at 0x7f34c5bd3130&gt;<br =
class=3D"">'verifyCallback' called for result 1<br class=3D"">&nbsp; =
&nbsp; &nbsp; &nbsp; conn._socket: &lt;socket._socketobject object at =
0x7f34c5bd3130&gt;<br class=3D"">127.0.0.1 - - [29/Aug/2019 11:45:47] =
"GET / HTTP/1.1" 200 -</div><div class=3D"">------<br =
class=3D""></div><div class=3D""><br class=3D""></div><div =
class=3D"">---testTwisted.py---</div><div class=3D"">### Generate server =
key material ###<br class=3D"">#
 openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout=20
serverPrivateKey.pem -out serverCertificate.pem -subj=20
"/C=3D''/O=3D''/OU=3D''/CN=3Dserver"<br class=3D"">### Generate client =
key material ###<br class=3D"">#
 openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout=20
clientPrivateKey.pem -out clientCertificate.pem -subj=20
"/C=3D''/O=3D''/OU=3D''/CN=3Dclient"<br class=3D"">from __future__ =
import print_function<br class=3D"">#<a =
href=3D"https://twistedmatrix.com/documents/12.0.0/core/howto/ssl.html" =
target=3D"_blank" =
class=3D"">https://twistedmatrix.com/documents/12.0.0/core/howto/ssl.html<=
/a><br class=3D"">from OpenSSL import SSL<br class=3D"">from =
twisted.internet import ssl, reactor<br class=3D"">from twisted.web =
import server, resource<br class=3D"">from twisted.internet.protocol =
import Factory, Protocol<br class=3D""><br class=3D"">def =
verifyCallback(conn, cert, errno, depth, result):<br class=3D"">&nbsp; =
&nbsp; print('\'verifyCallback\' called for result ' + str(result))<br =
class=3D"">&nbsp; &nbsp; print('\tconn._socket: ' + =
str(conn._socket))<br class=3D"">&nbsp; &nbsp; return True<br =
class=3D""><br class=3D"">def sniCallback(conn):<br class=3D"">&nbsp; =
&nbsp; print('\'sniCallback\' called.')<br class=3D"">&nbsp; &nbsp; =
print('\tconn._socket: ' + str(conn._socket))<br class=3D""><br =
class=3D"">class MainResource(resource.Resource):<br class=3D"">&nbsp; =
&nbsp; isLeaf =3D True<br class=3D""><br class=3D"">&nbsp; &nbsp; def =
render_GET(self, request):<br class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; =
request.responseHeaders.addRawHeader("Content-Type", "text/html; =
charset=3Dutf-8")<br class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; return =
b"&lt;html&gt;&lt;body&gt;Hello World&lt;/body&gt;&lt;/html&gt;"<br =
class=3D""><br class=3D"">if __name__ =3D=3D '__main__':<br =
class=3D"">&nbsp; &nbsp; myContextFactory =3D =
ssl.DefaultOpenSSLContextFactory(<br class=3D"">&nbsp; &nbsp; &nbsp; =
&nbsp; 'serverPrivateKey.pem',<br class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; =
'serverCertificate.pem'<br class=3D"">&nbsp; &nbsp; )<br class=3D"">&nbsp;=
 &nbsp; ctx =3D myContextFactory.getContext()<br class=3D"">&nbsp; =
&nbsp; # <a =
href=3D"https://www.pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.Conte=
xt.set_verify" target=3D"_blank" =
class=3D"">https://www.pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.Co=
ntext.set_verify</a><br class=3D"">&nbsp; &nbsp; =
ctx.set_verify(SSL.VERIFY_PEER, verifyCallback)<br class=3D"">&nbsp; =
&nbsp; # <a =
href=3D"https://pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.Context.s=
et_tlsext_servername_callback" target=3D"_blank" =
class=3D"">https://pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.Contex=
t.set_tlsext_servername_callback</a><br class=3D"">&nbsp; &nbsp; =
ctx.set_tlsext_servername_callback(sniCallback)<br class=3D""><br =
class=3D"">&nbsp; &nbsp; site =3D server.Site(MainResource())<br =
class=3D"">&nbsp; &nbsp; reactor.listenSSL(443, site, =
myContextFactory)<br class=3D"">&nbsp; &nbsp; reactor.run()</div><div =
class=3D"">------</div><div class=3D""><br class=3D""></div><div =
class=3D"">---testPyOpenSSL.py---</div><div class=3D"">### Generate =
server key material ###<br class=3D"">#
 openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout=20
serverPrivateKey.pem -out serverCertificate.pem -subj=20
"/C=3D''/O=3D''/OU=3D''/CN=3Dserver"<br class=3D"">### Generate client =
key material ###<br class=3D"">#
 openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout=20
clientPrivateKey.pem -out clientCertificate.pem -subj=20
"/C=3D''/O=3D''/OU=3D''/CN=3Dclient"<br class=3D"">from __future__ =
import print_function<br class=3D"">import socket, sys, os<br =
class=3D"">from SocketServer import BaseServer<br class=3D"">from =
BaseHTTPServer import HTTPServer<br class=3D"">from SimpleHTTPServer =
import SimpleHTTPRequestHandler<br class=3D"">from OpenSSL import SSL<br =
class=3D""><br class=3D"">def verifyCallback(conn, cert, errno, depth, =
result):<br class=3D"">&nbsp; &nbsp; print('\'verifyCallback\' called =
for result ' + str(result))<br class=3D"">&nbsp; &nbsp; =
print('\tconn._socket: ' + str(conn._socket))<br class=3D"">&nbsp; =
&nbsp; return True<br class=3D""><br class=3D"">def =
sniCallback(conn):<br class=3D"">&nbsp; &nbsp; print('\'sniCallback\' =
called.')<br class=3D"">&nbsp; &nbsp; print('\tconn._socket: ' + =
str(conn._socket))<br class=3D"">&nbsp; &nbsp; print(type(conn))<br =
class=3D""><br class=3D"">class SecureHTTPServer(HTTPServer):<br =
class=3D"">&nbsp; &nbsp; def __init__(self, server_address, =
HandlerClass):<br class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; =
BaseServer.__init__(self, server_address, HandlerClass)<br =
class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; ctx =3D =
SSL.Context(SSL.TLSv1_2_METHOD)<br class=3D"">&nbsp; &nbsp; &nbsp; =
&nbsp; ctx.use_privatekey_file('serverPrivateKey.pem')<br =
class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; =
ctx.use_certificate_file('serverCertificate.pem')<br class=3D"">&nbsp; =
&nbsp; &nbsp; &nbsp; # <a =
href=3D"https://www.pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.Conte=
xt.set_verify" target=3D"_blank" =
class=3D"">https://www.pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.Co=
ntext.set_verify</a><br class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; =
ctx.set_verify(SSL.VERIFY_PEER, verifyCallback)<br class=3D"">&nbsp; =
&nbsp; &nbsp; &nbsp; # <a =
href=3D"https://pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.Context.s=
et_tlsext_servername_callback" target=3D"_blank" =
class=3D"">https://pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.Contex=
t.set_tlsext_servername_callback</a><br class=3D"">&nbsp; &nbsp; &nbsp; =
&nbsp; ctx.set_tlsext_servername_callback(sniCallback)<br =
class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; self.socket =3D =
SSL.Connection(ctx, =
socket.socket(self.address_family,self.socket_type))<br class=3D"">&nbsp; =
&nbsp; &nbsp; &nbsp; self.server_bind()<br class=3D"">&nbsp; &nbsp; =
&nbsp; &nbsp; self.server_activate()<br class=3D"">&nbsp; &nbsp; <br =
class=3D"">&nbsp; &nbsp; def shutdown_request(self,request):<br =
class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; request.shutdown()<br =
class=3D""><br class=3D"">class =
SecureHTTPRequestHandler(SimpleHTTPRequestHandler):<br class=3D"">&nbsp; =
&nbsp; def setup(self):<br class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; =
self.connection =3D self.request<br class=3D"">&nbsp; &nbsp; &nbsp; =
&nbsp; self.rfile =3D socket._fileobject(self.request, "rb", =
self.rbufsize)<br class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; self.wfile =3D =
socket._fileobject(self.request, "wb", self.wbufsize)<br class=3D"">&nbsp;=
 &nbsp; <br class=3D"">&nbsp; &nbsp; def do_GET(self):<br =
class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; self.send_response(200)<br =
class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; =
SimpleHTTPRequestHandler.end_headers(self)<br class=3D"">&nbsp; &nbsp; =
&nbsp; &nbsp; self.wfile.write('&lt;html&gt;&lt;body&gt;Hello =
World&lt;/body&gt;&lt;/html&gt;')<br class=3D""><br class=3D"">if =
__name__ =3D=3D '__main__':<br class=3D"">&nbsp; &nbsp; ip,port =3D =
('0.0.0.0', 443)<br class=3D"">&nbsp; &nbsp; httpd =3D =
SecureHTTPServer((ip, port), SecureHTTPRequestHandler)<br =
class=3D"">&nbsp; &nbsp; httpd.serve_forever()</div><div =
class=3D"">------</div><div class=3D""><br class=3D""></div><div =
class=3D"">(Please note that even though these examples are for Python2 =
(due to other quirks) I am aiming to implement this in Python3.)<br =
class=3D""></div><div class=3D""><br class=3D""></div><div =
class=3D"">Regards,</div><div class=3D""><br class=3D""></div><div =
class=3D"">Arn</div></div>
_______________________________________________<br class=3D"">
Twisted-Python mailing list<br class=3D"">
<a href=3D"mailto:[email protected]" target=3D"_blank" =
class=3D"">[email protected]</a><br class=3D"">
<a =
href=3D"https://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python"=
 rel=3D"noreferrer" target=3D"_blank" =
class=3D"">https://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-pyth=
on</a><br class=3D"">
</blockquote></div></div>
_______________________________________________<br =
class=3D"">Twisted-Python mailing list<br class=3D""><a =
href=3D"mailto:[email protected]" =
class=3D"">[email protected]</a><br =
class=3D"">https://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-pyth=
on<br class=3D""></div></blockquote></div><br =
class=3D""></div></div></body></html>=

--Apple-Mail=_85FD3470-399C-4483-BD25-5D47DBFC9434--


--===============5705995186937567742==
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Content-Disposition: inline

X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KVHdpc3RlZC1Q
eXRob24gbWFpbGluZyBsaXN0ClR3aXN0ZWQtUHl0aG9uQHR3aXN0ZWRtYXRyaXguY29tCmh0dHBz
Oi8vdHdpc3RlZG1hdHJpeC5jb20vY2dpLWJpbi9tYWlsbWFuL2xpc3RpbmZvL3R3aXN0ZWQtcHl0
aG9uCg==

--===============5705995186937567742==--