Skip to content
Browse files

Merge pull request #547 from evanj/master

Detect SSL option errors at start up
  • Loading branch information...
2 parents ff12f29 + 73d26a4 commit a240c7680f0e87b36121e93007de31a579ec9813 @bdarnell bdarnell committed
Showing with 48 additions and 0 deletions.
  1. +17 −0 tornado/netutil.py
  2. +31 −0 tornado/test/httpserver_test.py
View
17 tornado/netutil.py
@@ -92,6 +92,23 @@ def __init__(self, io_loop=None, ssl_options=None):
self._pending_sockets = []
self._started = False
+ # Verify the SSL options. Otherwise we don't get errors until clients
+ # connect. This doesn't verify that the keys are legitimate, but
+ # the SSL module doesn't do that until there is a connected socket
+ # which seems like too much work
+ if self.ssl_options is not None:
+ # Only certfile is required: it can contain both keys
+ if 'certfile' not in self.ssl_options:
+ raise KeyError('missing key "certfile" in ssl_options')
+
+ if not os.path.exists(self.ssl_options['certfile']):
+ raise ValueError('certfile "%s" does not exist' %
+ self.ssl_options['certfile'])
+ if ('keyfile' in self.ssl_options and
+ not os.path.exists(self.ssl_options['keyfile'])):
+ raise ValueError('keyfile "%s" does not exist' %
+ self.ssl_options['keyfile'])
+
def listen(self, port, address=""):
"""Starts accepting connections on the given port.
View
31 tornado/test/httpserver_test.py
@@ -6,6 +6,7 @@
from tornado.escape import json_decode, utf8, _unicode, recursive_unicode, native_str
from tornado.httpserver import HTTPServer
from tornado.httputil import HTTPHeaders
+from tornado.ioloop import IOLoop
from tornado.iostream import IOStream
from tornado.simple_httpclient import SimpleAsyncHTTPClient
from tornado.testing import AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, LogTrapTestCase
@@ -16,6 +17,7 @@
import socket
import sys
import tempfile
+import unittest
try:
import ssl
@@ -101,6 +103,35 @@ def get_ssl_version(self):
return ssl.PROTOCOL_TLSv1
+class BadSSLOptionsTest(unittest.TestCase):
+ def test_missing_arguments(self):
+ application = Application()
+ self.assertRaises(KeyError, HTTPServer, application, ssl_options={
+ "keyfile": "/__missing__.crt",
+ })
+
+ def test_missing_key(self):
+ '''A missing SSL key should cause an immediate exception.'''
+
+ application = Application()
+ module_dir = os.path.dirname(__file__)
+ existing_certificate = os.path.join(module_dir, 'test.crt')
+
+ self.assertRaises(ValueError, HTTPServer, application, ssl_options={
+ "certfile": "/__mising__.crt",
+ })
+ self.assertRaises(ValueError, HTTPServer, application, ssl_options={
+ "certfile": existing_certificate,
+ "keyfile": "/__missing__.key"
+ })
+
+ # This actually works because both files exist
+ server = HTTPServer(application, ssl_options={
+ "certfile": existing_certificate,
+ "keyfile": existing_certificate
+ })
+
+
if ssl is None:
del BaseSSLTest
del SSLv23Test

0 comments on commit a240c76

Please sign in to comment.
Something went wrong with that request. Please try again.