We have two type of client data handlers

1 - ApacheRequest_parse_multipart (handling "multipart/form-data")

2 - ApacheRequest_parse_urlencoded (handling every other case)

George hit a problem because ApacheRequest_parse_urlencoded itself checks for the Content-Type header and if it's neither "application/x-www-form-urlencoded" nor "text/xml" returns DENIED. For some reason I couldn't pin down Apache's framework in this case turns a DENIED into a HTTP_METHOD_NOT_ALLOWED (DENIED is simply returned when the handler refuses to handle a request, as Rivet_SendContent does)

There is still some redundancy in the code and there is still space for improvements. Notice that also ApacheRequest_parse_urlencoded rechecks the method making the whole process trivially subobtimal. I simplified the whole business removing the checks on the methods except for the POST method in order to detect a multipart/form-data message.

Would you please test the attached patch and let me know if it's ok for you?

 -- Massimo

On 05/18/2013 02:55 AM, Jeff Lawson wrote:
This is also part of the bug that I opened to allow the content-type to
be less restrictive:
https://issues.apache.org/bugzilla/show_bug.cgi?id=53661

I never actually had the chance to review your proposed patch, so I
don't know if or how that improved the situation.

In production we are still using a workaround of using mod_header and
mod_rewrite to convert objectionable requests into having the
content-type that is required by Rivet.


On Fri, May 17, 2013 at 6:09 PM, Massimo Manghi <[email protected]
<mailto:[email protected]>> wrote:

    After some debugging I found out mod_rivet turns down the offer to
    handle the request because it expects the Content-Type to be either
    'application/x-www-form-__urlencoded' or 'multipart/form-data'

    curl -i -H 'Content-Type: application/x-www-form-__urlencoded' -X
    DELETE http://localhost:8080/~manghi/__simple.tcl
    <http://localhost:8080/~manghi/simple.tcl>
    HTTP/1.1 200 OK
    Date: Fri, 17 May 2013 23:01:39 GMT
    Server: Apache/2.2.21 (Unix) Rivet/2.1.2
    Transfer-Encoding: chunked
    Content-Type: text/html

    DELETE

    The relevant code in in src/apache-2/apache_request.c

    This thread brings up the problem with the rather choosy attitude in
    mod_rivet's design as to the request handling. Maybe it's time for a
    general review and simplification of the code involved in the
    request selection.


      -- Massimo


    On 05/17/2013 11:34 AM, Georgios Petasis wrote:

        Στις 17/5/2013 12:12, ο/η Massimo Manghi έγραψε:

            Thanks George,

            no, I have no idea because there is no line of code in Rivet
            returning
            a 405 status, for what I can see.

            The output produced by curl the 'Allow' line is bothering
            me. Where
            Apache is getting the list of available methods from?


        I have no idea. What is also strange, is that it allows PUT,
        despite the
        fact that is not in the "Allow" list.

        George


            -- Massimo

            fismed44:~/rivetweb> curl -i -X DELETE -H 'Content-Type:
            application/x-rivet-tcl'
            http://localhost/~manghi/__index.rvt
            <http://localhost/~manghi/index.rvt>
            HTTP/1.1 405 Method Not Allowed
            Date: Fri, 17 May 2013 09:09:14 GMT
            Server: Apache/2.2.22 (Ubuntu)
            Allow: POST,OPTIONS,GET,HEAD
            Vary: Accept-Encoding
            Content-Length: 316
            Content-Type: text/html; charset=iso-8859-1

            <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
            <html><head>
            <title>405 Method Not Allowed</title>
            </head><body>
            <h1>Method Not Allowed</h1>
            <p>The requested method DELETE is not allowed for the URL
            /~manghi/index.rvt.</p>
            <hr>
            <address>Apache/2.2.22 (Ubuntu) Server at localhost Port
            80</address>
            </body></html>




            -- Massimo

            On 05/17/2013 10:24 AM, Georgios Petasis wrote:

                I am not sure this is a configuration problem. I have
                created the
                following php file (method.php), in the same directory
                as the rivet tcl
                script:

                <?php
                print_r($_SERVER);
                ?>

                Executing "curl -i -X DELETE
                http://localhost/webservices/__AnnotationTool/method.php
                <http://localhost/webservices/AnnotationTool/method.php>" (note
                that I
                haven't specified a content type, as rivet requires),
                returns:

                HTTP/1.1 200 OK
                Date: Fri, 17 May 2013 08:20:38 GMT
                Server: Apache/2.4.4 (Fedora) OpenSSL/1.0.1e-fips
                PHP/5.4.14 Rivet/2.1.2
                mod_perl/2.0.8-dev Perl/v5.16.3
                X-Powered-By: PHP/5.4.14
                Content-Length: 1134
                Content-Type: text/html; charset=UTF-8

                Array
                (
                [UNIQUE_ID] => UZXoVj4B1LMAAAdMQBkAAAAC
                [HTTP_USER_AGENT] => curl/7.27.0
                [HTTP_HOST] => localhost
                [HTTP_ACCEPT] => */*
                [PATH] =>
                /usr/local/sbin:/usr/local/__bin:/usr/sbin:/usr/bin
                [SERVER_SIGNATURE] =>
                [SERVER_SOFTWARE] => Apache/2.4.4 (Fedora)
                OpenSSL/1.0.1e-fips
                PHP/5.4.14 Rivet/2.1.2 mod_perl/2.0.8-dev Perl/v5.16.3
                [SERVER_NAME] => localhost
                [SERVER_ADDR] => ::1
                [SERVER_PORT] => 80
                [REMOTE_ADDR] => ::1
                [DOCUMENT_ROOT] => /var/www/html/intellitech
                [REQUEST_SCHEME] => http
                [CONTEXT_PREFIX] => /webservices
                [CONTEXT_DOCUMENT_ROOT] => /opt/WebServices
                [SERVER_ADMIN] => root@localhost
                [SCRIPT_FILENAME] =>
                /opt/WebServices/__AnnotationTool/method.php
                [REMOTE_PORT] => 50768
                [GATEWAY_INTERFACE] => CGI/1.1
                [SERVER_PROTOCOL] => HTTP/1.1
                [REQUEST_METHOD] => DELETE
                [QUERY_STRING] =>
                [REQUEST_URI] => /webservices/AnnotationTool/__method.php
                [SCRIPT_NAME] => /webservices/AnnotationTool/__method.php
                [PHP_SELF] => /webservices/AnnotationTool/__method.php
                [REQUEST_TIME_FLOAT] => 1368778838.542
                [REQUEST_TIME] => 1368778838
                )

                So, php in the same directory works, rivet returns a 405
                error.

                Any ideas?

                George


                Στις 17/5/2013 10:55, ο/η Georgios Petasis έγραψε:

                    I tried with this:

                    <Directory /opt/WebServices>
                    DirectoryIndex index.html index.htm index.shtml
                    index.cgi index.tcl
                    index.rvt

                    AllowOverride None
                    Order allow,deny
                    Allow from all
                    Require all granted
                    # Require method GET HEAD POST PUT DELETE OPTIONS TRACE
                    <Limit GET POST PUT DELETE>
                    Order allow,deny
                    Allow from all
                    </Limit>
                    <IfModule mod_security2.c>
                    SecRuleInheritance Off
                    </IfModule>
                    </Directory>

                    Again, 405 Method Not Allowed. GET, POST, PUT work
                    as usual.

                    George

                    Στις 17/5/2013 01:47, ο/η Jeff Lawson έγραψε:

                        Try adding something like this to the
                        appropriate scope in your
                        Apache config:

                        <Limit GET POST PUT DELETE>
                        Order allow,deny
                        Allow from all
                        </Limit>




                        On Thu, May 16, 2013 at 4:50 PM, Massimo Manghi
                        <[email protected] <mailto:[email protected]>
                        <mailto:[email protected]
                        <mailto:[email protected]>>> wrote:

                        likewise there is no 405 or
                        HTTP_METHOD_NOT_ALLOWED reference in
                        Rivet C code

                        -- Massimo


                        On 05/16/2013 11:26 PM, Georgios Petasis wrote:

                        If it is a configuration problem, what may be wrong?

                        There is not a single reference in all apache 2.4
                        configuration files
                        about the methods. Only one exception, the user
                        directories,
                        where the configuration is:

                        <IfModule mod_userdir.c>
                        UserDir disabled
                        </IfModule>

                        #
                        # Control access to UserDir directories. The
                        following is an
                        example
                        # for a site where these directories are
                        restricted to read-only.
                        #
                        <Directory "/home/*/public_html">
                        AllowOverride FileInfo AuthConfig Limit Indexes
                        Options MultiViews Indexes SymLinksIfOwnerMatch
                        IncludesNoExec
                        Require method GET POST OPTIONS
                        </Directory>

                        Is DELETE in apache 2.4 disabled by default? I
                        looked into
                        documentation
                        and some forums, but couldn't find anything useful.
                        Tomorrow I will test if php can accept a DELETE
                        request...

                        George


                        
------------------------------__------------------------------__---------
                        To unsubscribe, e-mail:
                        rivet-dev-unsubscribe@tcl.__apache.org
                        <mailto:[email protected]>
                        <mailto:rivet-dev-unsubscribe@__tcl.apache.org
                        <mailto:[email protected]>>
                        For additional commands, e-mail:
                        [email protected]
                        <mailto:[email protected]>
                        <mailto:rivet-dev-help@tcl.__apache.org
                        <mailto:[email protected]>>





        
------------------------------__------------------------------__---------
        To unsubscribe, e-mail: rivet-dev-unsubscribe@tcl.__apache.org
        <mailto:[email protected]>
        For additional commands, e-mail: [email protected]
        <mailto:[email protected]>



    ------------------------------__------------------------------__---------
    To unsubscribe, e-mail: rivet-dev-unsubscribe@tcl.__apache.org
    <mailto:[email protected]>
    For additional commands, e-mail: [email protected]
    <mailto:[email protected]>


Index: src/apache-2/apache_request.c
===================================================================
--- src/apache-2/apache_request.c	(revision 1483568)
+++ src/apache-2/apache_request.c	(working copy)
@@ -371,6 +371,7 @@
 int ApacheRequest___parse(ApacheRequest *req)
 {
     request_rec *r = req->r;
+    const char *ct = apr_table_get(r->headers_in, "Content-type");
     int result;
 
     if (r->args) {
@@ -378,25 +379,10 @@
         req->nargs = ((apr_array_header_t *)req->parms)->nelts;
     }
 
-    if (r->method_number == M_POST || r->method_number == M_PUT || r->method_number == M_DELETE) {
-        const char *ct = apr_table_get(r->headers_in, "Content-type");
-        if (ct)
-        {
-            ap_log_rerror(REQ_INFO, "content-type: `%s'", ct);
-            if (strncaseEQ(ct, MULTIPART_ENCTYPE, MULTIPART_ENCTYPE_LENGTH))
-            {
-                result = ApacheRequest_parse_multipart(req,ct);
-            }
-            else
-            {
-                result = ApacheRequest_parse_urlencoded(req);
-            }
-
-        } else {
-            ap_log_rerror(REQ_ERROR, "unknown content-type");
-            result = HTTP_INTERNAL_SERVER_ERROR;
-        }
-
+    if ((r->method_number == M_POST) && ct && strncaseEQ(ct, MULTIPART_ENCTYPE, MULTIPART_ENCTYPE_LENGTH)) 
+    {
+        ap_log_rerror(REQ_INFO, "content-type: `%s'", ct);
+        result = ApacheRequest_parse_multipart(req,ct);
     }
     else
     {
@@ -413,18 +399,22 @@
     int rc = OK;
 
     if (r->method_number == M_POST || r->method_number == M_PUT || r->method_number == M_DELETE) {
-    	const char *data = NULL, *type;
-    
+    	const char *data = NULL;
+
+    /*
+        const char *type;
     	type = apr_table_get(r->headers_in, "Content-Type");
     
     	if (!strncaseEQ(type, DEFAULT_ENCTYPE, DEFAULT_ENCTYPE_LENGTH) &&
     	    !strncaseEQ(type, TEXT_XML_ENCTYPE, TEXT_XML_ENCTYPE_LENGTH)) {
     	    return DECLINED;
     	}
+    */
 
     	if ((rc = util_read(req, &data)) != OK) {
     	    return rc;
     	}
+
     	if (data) {
     	    req->raw_post = (char*) data; /* Give people a way of getting at the raw data. */
     	    split_to_parms(req, data);

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to