Commit c34f476e authored by Lucas Carvalho's avatar Lucas Carvalho

Added new classes and methods to run HTTPS server.

Actually, the NetworkcacheClient must be able to fetch the
certificate files under a HTTPS server.

So, these classes and methods are going to be used to setup the
environment to test this feature.
parent f849bb74
...@@ -12,8 +12,22 @@ ...@@ -12,8 +12,22 @@
# #
############################################################################## ##############################################################################
import tempfile import tempfile
import unittest import unittest
import socket
import os
import threading
import shutil
import subprocess
import random
import httplib
import time
import errno
from SocketServer import BaseServer
from BaseHTTPServer import HTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler
from OpenSSL import SSL
from slapos.signature import parseArgument, \ from slapos.signature import parseArgument, \
createPrivateKeyAndCertificateFile createPrivateKeyAndCertificateFile
...@@ -43,3 +57,132 @@ class LibNetworkCacheMixin(unittest.TestCase): ...@@ -43,3 +57,132 @@ class LibNetworkCacheMixin(unittest.TestCase):
""" Remove the files which have been created during the test. """ """ Remove the files which have been created during the test. """
self.priv_file_descritor.close() self.priv_file_descritor.close()
self.pub_file_descriptor.close() self.pub_file_descriptor.close()
class SecureHTTPServer(HTTPServer):
def __init__(self, server_address, HandlerClass, file_pem):
BaseServer.__init__(self, server_address, HandlerClass)
self.file_pem = file_pem
ctx = SSL.Context(SSL.SSLv23_METHOD)
ctx.use_privatekey_file (file_pem)
ctx.use_certificate_file(file_pem)
self.socket = SSL.Connection(ctx, socket.socket(self.address_family,
self.socket_type))
self.server_bind()
self.server_activate()
def shutdown_request(self, request):
shutil.remove(self.file_pem)
request.shutdown()
class SecureHTTPRequestHandler(SimpleHTTPRequestHandler):
def setup(self):
self.connection = self.request
self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
def do_GET(self):
if '__stop__' in self.path:
raise SystemExit
try:
f = open(self.path, 'rb')
except IOError:
self.send_error(404, "File not found")
return None
try:
self.send_response(200)
fs = os.fstat(f.fileno())
self.send_header("Content-Length", str(fs[6]))
self.end_headers()
shutil.copyfileobj(f, self.wfile)
finally:
f.close()
self.setup()
return None
# def log_request(self, code):
# pass
def create_pem_file():
file_pem = tempfile.mktemp()
command_list = ['openssl', 'req', '-new', '-x509', '-keyout', file_pem,
'-out', file_pem, '-days', '365', '-nodes', '-batch']
popen = subprocess.Popen(command_list, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
result = popen.communicate(input)[0]
if popen.returncode is None:
popen.kill()
if popen.returncode != 0:
raise ValueError('Issue during calling %r, result was:\n%s' % \
(command_list, result))
return file_pem
def get_port():
for i in range(10):
port = random.randrange(20000, 30000)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
try:
s.connect(('localhost', port))
except socket.error:
return port
finally:
s.close()
raise RuntimeError, "Can't find port"
def _run_server(address, port, file_pem):
httpd = SecureHTTPServer((address, port), SecureHTTPRequestHandler, file_pem)
httpd.serve_forever()
def start_server():
file_pem = create_pem_file()
assert os.path.exists(file_pem)
port = get_port()
thread = threading.Thread(target=_run_server, args=('', port, file_pem), name='')
thread.setDaemon(True)
thread.start()
# Maybe we should wait for the server...
wait(port, True)
return port, thread, file_pem
def stop_server(server_url, thread=None):
try:
conn = httplib.HTTPSConnection(server_url.split('/')[-1])
conn.request("GET", "/__stop__")
conn.getresponse()
except Exception:
pass
if thread is not None:
thread.join(0)
def wait(port, up):
addr = 'localhost', port
for i in range(120):
time.sleep(0.25)
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(addr)
s.close()
if up:
break
except socket.error, e:
if e[0] not in (errno.ECONNREFUSED, errno.ECONNRESET):
raise
s.close()
if not up:
break
else:
if up:
raise
else:
raise SystemError("Couln't stop server")
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment