Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Fix SSL timeout issue (issue 1307) #24

Merged
merged 4 commits into from

4 participants

@davidjb

Previously, the connection timeout was not respected on SSL connections -- it always defaulting back to the default of 15 seconds. This pull request solves the issue.

I've applied the patches from Sylvain Munaut @ http://code.google.com/p/cherokee/issues/detail?id=1307 and included QA tests to ensure this works against HTTP and HTTPS.

smunaut and others added some commits
@smunaut smunaut ssl: Restore the server default timeout_lapse once SSL negotiation is…
… done

The timeout_lapse was replaced by the SSL negotiation timeout during the
accept. We need to restore it to the proper value once the SSL stuff is
over with.

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
881bedd
@smunaut smunaut rule_list: Update the timeout when setting per-rule timeout_lapse
It's required or the new timeout_lapse might not be taken into
account since the connection expiration time that's in conn->timeout
has been computed with the previous timeout_lapse

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
2510045
@alobbs alobbs The QA bench was not working over SSL. 13012f9
@davidjb davidjb Adding tests for timeout against rules 541f26c
@skinkie skinkie merged commit 9864126 into cherokee:master
@skinkie
Collaborator

Thanks for following up. I know there are a lot of fixes also in my personal Cherokee repo which we can close a lot of bugs with.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 18, 2012
  1. @smunaut @davidjb

    ssl: Restore the server default timeout_lapse once SSL negotiation is…

    smunaut authored davidjb committed
    … done
    
    The timeout_lapse was replaced by the SSL negotiation timeout during the
    accept. We need to restore it to the proper value once the SSL stuff is
    over with.
    
    Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
  2. @smunaut @davidjb

    rule_list: Update the timeout when setting per-rule timeout_lapse

    smunaut authored davidjb committed
    It's required or the new timeout_lapse might not be taken into
    account since the connection expiration time that's in conn->timeout
    has been computed with the previous timeout_lapse
    
    Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
Commits on Jul 19, 2012
  1. @alobbs @davidjb

    The QA bench was not working over SSL.

    alobbs authored davidjb committed
  2. @davidjb
This page is out of date. Refresh to see the latest.
View
1  cherokee/rule_list.c
@@ -78,6 +78,7 @@ update_connection (cherokee_connection_t *conn,
if (! NULLI_IS_NULL(ret_config->timeout_lapse)) {
conn->timeout_lapse = ret_config->timeout_lapse;
conn->timeout_header = ret_config->timeout_header;
+ cherokee_connection_update_timeout (conn);
}
}
View
2  cherokee/thread.c
@@ -814,6 +814,8 @@ process_active_connections (cherokee_thread_t *thd)
/* Set mode and update timeout
*/
conn_set_mode (thd, conn, socket_reading);
+
+ conn->timeout_lapse = srv->timeout;
cherokee_connection_update_timeout (conn);
conn->phase = phase_reading_header;
View
95 qa/298-Timeout.py
@@ -0,0 +1,95 @@
+from base import *
+
+DIR = "298-Timeout"
+DIR_RULE = "%s-rule" % DIR
+CONTENT = "Tests to check whether timeout is applied."
+
+SERVER_TIMEOUT = 5
+RULE_TIMEOUT = 3
+
+CONF = """
+server!timeout = %(SERVER_TIMEOUT)i
+vserver!1!rule!2890!match = directory
+vserver!1!rule!2890!match!directory = /%(DIR)s
+vserver!1!rule!2890!handler = cgi
+
+vserver!1!rule!2891!match = directory
+vserver!1!rule!2891!match!directory = /%(DIR_RULE)s
+vserver!1!rule!2891!handler = cgi
+vserver!1!rule!2891!timeout = %(RULE_TIMEOUT)i
+
+""" %(globals())
+
+CGI_CODE = """#!/bin/sh
+
+echo "Content-Type: text/plain"
+echo
+sleep %(runtime)i
+echo "%(content)s"
+"""
+
+
+class TestEntry (TestBase):
+ """Test for timeout being applied.
+
+ If timeout expires, no content after `sleep` in the CGI will
+ be delivered.
+ """
+
+ def __init__ (self, dir, filename, runtime, content, expected_timeout):
+ TestBase.__init__ (self, __file__)
+ self.request = "GET /%s/%s HTTP/1.0\r\n" % (dir, filename) +\
+ "Connection: close\r\n"
+ self.expected_error = 200
+
+ if runtime < expected_timeout:
+ self.expected_content = content
+ else:
+ self.forbidden_content = content
+
+
+class Test (TestCollection):
+
+ def __init__ (self):
+ TestCollection.__init__ (self, __file__)
+
+ self.name = "Connection Timeouts Applied"
+ self.conf = CONF
+ self.proxy_suitable = True
+ self.filenames = {DIR: [],
+ DIR_RULE: []}
+
+ def Prepare (self, www):
+ self.local_dirs = {DIR: self.Mkdir (www, DIR),
+ DIR_RULE: self.Mkdir (www, DIR_RULE)}
+
+ def JustBefore (self, www):
+ # Create sub-request objects
+ self.Empty ()
+
+ # Create all tests with different runtime lengths
+ # Instant return and 1 second less than timeout should work,
+ # but past the timeout should return no content.
+ for dir, timeout in ((DIR, SERVER_TIMEOUT), (DIR_RULE, RULE_TIMEOUT)):
+ for script_runtime in (0, timeout-1, timeout+1):
+ # Write the new script files
+ filename = 'test-%i-seconds.cgi' % script_runtime
+ code = CGI_CODE % dict(runtime=script_runtime, content=CONTENT)
+ self.WriteFile (self.local_dirs[dir], filename, 0755, code)
+ self.filenames[dir].append(filename)
+
+ obj = self.Add (TestEntry (dir,
+ filename,
+ runtime=script_runtime,
+ content=CONTENT,
+ expected_timeout=timeout))
+
+
+ def JustAfter (self, www):
+ # Clean up the local files
+ for dir in self.local_dirs:
+ for filename in self.filenames[dir]:
+ fp = os.path.join (self.local_dirs[dir], filename)
+ os.unlink (fp)
+ self.filenames = {}
+
View
5 qa/conf.py.pre
@@ -17,9 +17,8 @@ LOGGER_ACCESS = "access.log"
LOGGER_ERROR = "error.log"
# TLS/SSL
-SSL_CERT_FILE = "/etc/cherokee/ssl/cherokee.pem"
-SSL_CERT_KEY_FILE = "/etc/cherokee/ssl/cherokee.pem"
-SSL_CA_FILE = "/etc/cherokee/ssl/cherokee.pem"
+SSL_CERT_FILE = "/etc/cherokee/ssl/cherokee.crt"
+SSL_CERT_KEY_FILE = "/etc/cherokee/ssl/cherokee.key"
# Misc options
SERVER_DELAY = 10
View
8 qa/run-tests.py
@@ -217,7 +217,6 @@
server!bind!1!interface = %(listen)s
server!bind!2!port = %(PORT_TLS)d
server!bind!2!tls = 1
-server!bind!2!interface = %(listen)s
server!keepalive = 1
server!panic_action = %(panic)s
server!pid_file = %(pid)s
@@ -260,10 +259,9 @@
if ssl:
CONF_BASE += """
server!tls = libssl
-vserver!1!ssl_certificate_file = %s
-vserver!1!ssl_certificate_key_file = %s
-vserver!1!ssl_ca_list_file = %s
-""" % (SSL_CERT_FILE, SSL_CERT_KEY_FILE, SSL_CA_FILE)
+vserver!1!ssl_certificate_file = %(SSL_CERT_FILE)s
+vserver!1!ssl_certificate_key_file = %(SSL_CERT_KEY_FILE)s
+""" % (globals())
if log:
CONF_BASE += """
Something went wrong with that request. Please try again.