Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Ensuring that HTTP methods accept request bodies in accordance with v…

…arious RFCs (RFC2518, RFC2616, RFC3253, RFC5789). Included QA test for all methods.
  • Loading branch information...
commit e6d7fa953822f7f7747c3a1324301f17dba7219a 1 parent e8255e2
@davidjb davidjb authored
View
2  cherokee/handler_cgi.c
@@ -367,7 +367,7 @@ add_environment (cherokee_handler_cgi_t *cgi,
/* CONTENT_LENGTH
*/
- if (http_method_with_input (conn->header.method)) {
+ if (conn->post.has_info) {
cherokee_buffer_clean (tmp);
cherokee_buffer_add_ullong10 (tmp, conn->post.len);
set_env (cgi_base, "CONTENT_LENGTH", tmp->buf, tmp->len);
View
4 cherokee/handler_fcgi.c
@@ -404,7 +404,7 @@ add_extra_fcgi_env (cherokee_handler_fcgi_t *hdl, cuint_t *last_header_offset)
/* POST management
*/
- if (http_method_with_input (conn->header.method)) {
+ if (conn->post.has_info) {
if (conn->post.encoding == post_enc_regular) {
cherokee_buffer_add_ullong10 (&buffer, conn->post.len);
set_env (cgi_base, "CONTENT_LENGTH", buffer.buf, buffer.len);
@@ -516,7 +516,7 @@ build_header (cherokee_handler_fcgi_t *hdl, cherokee_buffer_t *buffer)
/* No POST?
*/
- if ((! http_method_with_input (conn->header.method)) || (! conn->post.has_info) || (! conn->post.len)) {
+ if ((! conn->post.has_info) || (! conn->post.len)) {
TRACE (ENTRIES",post", "Post: %s\n", "has no post");
add_empty_packet (hdl, FCGI_STDIN);
}
View
22 cherokee/http.h
@@ -224,18 +224,32 @@ typedef enum { /* Protocol RFC Section */
#define http_method_with_body(m) ((m) != http_head)
+/* RFC 2518, RFC 2616, RFC3253, RFC 5789 */
#define http_method_with_input(m) ((m == http_post) || \
(m == http_put) || \
- (m == http_mkcol) || \
(m == http_merge) || \
(m == http_search) || \
(m == http_report) || \
- (m == http_checkout) || \
+ (m == http_patch) || \
(m == http_propfind) || \
(m == http_proppatch) || \
- (m == http_mkactivity))
+ (m == http_update) || \
+ (m == http_label))
-#define http_method_with_optional_input(m) (m == http_options)
+#define http_method_with_optional_input(m) ((m == http_options) || \
+ (m == http_delete) || \
+ (m == http_mkcol) || \
+ (m == http_copy) || \
+ (m == http_move) || \
+ (m == http_lock) || \
+ (m == http_unlock) || \
+ (m == http_version_control) || \
+ (m == http_checkout) || \
+ (m == http_uncheckout) || \
+ (m == http_checkin) || \
+ (m == http_mkworkspace) || \
+ (m == http_mkactivity) || \
+ (m == http_baseline_control))
/* RFC 2616: Section 4.3 */
View
117 qa/299-MethodsRequestBodyHandling.py
@@ -0,0 +1,117 @@
+from base import *
+
+DIR = "299-MethodsRequestBodyHandling"
+MAGIC = "Report bugs to http://bugs.cherokee-project.com"
+
+METHODS = {
+ 'required': [
+ 'POST',
+ 'PUT',
+ 'MERGE',
+ 'SEARCH',
+ 'REPORT',
+ 'PATCH',
+ 'PROPFIND',
+ 'PROPPATCH',
+ 'UPDATE',
+ 'LABEL',
+ ],
+ 'optional': [
+ 'OPTIONS',
+ 'DELETE',
+ 'MKCOL',
+ 'COPY',
+ 'MOVE',
+ 'LOCK',
+ 'UNLOCK',
+ 'VERSION-CONTROL',
+ 'CHECKOUT',
+ 'UNCHECKOUT',
+ 'CHECKIN',
+ 'MKWORKSPACE',
+ 'MKACTIVITY',
+ 'BASELINE-CONTROL',
+ ]
+}
+
+CONF = """
+vserver!1!rule!1280!match = directory
+vserver!1!rule!1280!match!directory = /%s
+vserver!1!rule!1280!handler = common
+""" % (DIR)
+
+
+class TestEntry (TestBase):
+ """Test for HTTP methods with required and optional request bodies being
+ received and processed correctly by Cherokee.
+ """
+
+ def __init__ (self, method, send_input, input_required):
+ TestBase.__init__ (self, __file__)
+ self.request = "%s /%s/ HTTP/1.0\r\n" % (method, DIR) +\
+ "Content-type: text/xml\r\n"
+ self.expected_content = []
+
+ if input_required and not send_input:
+ self.expected_error = 411
+ else:
+ self.expected_error = 200
+ self.expected_content.append("Method: %s" % method)
+
+ if send_input:
+ self.request += "Content-length: %d\r\n" % (len(MAGIC))
+ self.post = MAGIC
+ self.expected_content.append("Body: %s" % MAGIC)
+ else:
+ self.forbidden_content = 'Body:'
+
+
+class Test (TestCollection):
+
+ def __init__ (self):
+ TestCollection.__init__ (self, __file__)
+
+ self.name = "Method Request Body Handling"
+ self.conf = CONF
+ self.proxy_suitable = True
+
+ def Prepare (self, www):
+ d = self.Mkdir (www, DIR)
+ f = self.WriteFile (d, "test_index.php", 0444,
+ """
+<?php echo 'Method: '.$_SERVER['REQUEST_METHOD']; ?>
+
+<?php
+ $body = @file_get_contents('php://input');
+ if (strlen($body) > 0):
+ echo "Body: $body";
+ endif;
+?>
+ """)
+
+ def JustBefore (self, www):
+ # Create sub-request objects
+ self.Empty ()
+
+ # Create all tests with different methods - all methods
+ # should only work with request bodies. With no request
+ # body a 411 Length Required should result.
+ for method in METHODS['required']:
+ self.Add (TestEntry (method=method,
+ send_input=True,
+ input_required=True))
+ self.Add (TestEntry (method=method,
+ send_input=False,
+ input_required=True))
+
+ # Create all tests with different methods - all methods
+ # should work with and without request bodies.
+ for method in METHODS['optional']:
+ #Test method when for when sending a request body
+ self.Add (TestEntry (method=method,
+ send_input=True,
+ input_required=False))
+ #Test method when not sending a request body
+ self.Add (TestEntry (method=method,
+ send_input=False,
+ input_required=False))
Please sign in to comment.
Something went wrong with that request. Please try again.