Forum Discussion

Willy_82807's avatar
Willy_82807
Icon for Nimbostratus rankNimbostratus
Oct 05, 2010

Fileupload problem

I am new to BigIP. I am load balancing two servers both running java servlet / jsp applications. Some of the 3rd party modules are hosted in iframes and to get the content it uses a non relative url. The application as a whole needs to use https. So I created this irule.

 

 

when HTTP_REQUEST {

 

HTTP::redirect https://[HTTP::host][HTTP::uri]

 

}

 

 

But now I am getting the unintended consequence that fileuploads are working sometimes and not other times. It is not a file size issue. It happens in Firefox and IE8. This is the error message I am getting.HTTP Status 501 - Method 240776-- GET is not defined in RFC 2068 and is not supported by the Servlet API

type Status report

 

messageMethod 240776-- GET is not defined in RFC 2068 and is not supported by the Servlet API

 

descriptionThe server does not support the functionality needed to fulfill this request (Method 240776-- GET is not defined in RFC 2068 and is not supported by the Servlet API ).

 

Apache Tomcat/5.5.29

 

 

When I go directly to the Tomcat server (skip the load balancer) and upload the same file I do not get an error and it uploads quickly. This does not happen for every file. But I have not yet noticed the common denominator in the files that is causing the issue. Most files upload fine. I do have one that consistently throws this error that is useful for debugging.

 

 

These applications ran for a while before the BigIP appliance was installed and never had this issue. So I am concerned that the problem lies with my iRule. Any suggestions on how to go about solving this issue? A better way to do the https redirect for the iframe content or a way of logging these events so I can perhaps notice a pattern in what kind of files are causing the issue or a way to redirect file uploads so they will work.

 

 

15 Replies

  • It doesn't care if it's a binary stream or not - it was rewriting anything which passed through it in plaintext. By extending the URL which has to be matched, the number of collisions (changes) decreases drastically. Unfortunately, that's probably coming at something of a cost to the system processor - maybe not an issue now, but will be eventually. As well and as stated above (in my much mangled first post), any files which actually contain plaintext links to the site are still going to be rewritten (and this will happen as your actual servers on the backend are built around HTML documents), meaning that the appropriate solution is still to use content-type as causation for allowing the rewrite.
  • Well, this probably fixed the issue by changing some non-relative links in your browser-side Javascript handling AJAX calls to https instead of http.

     

     

    I've seen instances where AJAX calls reference items that themselves call non-relative links that are on a different protocol -- meaning it calls a method to retrieve content,

     

    store content, or update status but does so using a full URL instead of a relative path (e.g. http.open ("GET", "http://site.org/path/to/svc?"+params, true); ). It works

     

    fine so long as it doesn't get a 302 Redirect in response, but when it does it has no way to handle a redirect response unless it's been specifically written to do so (data.redirect).

     

     

    See, AJAX is interesting on the client side in that it will assign "success" to any non-error response coming back to it -- that includes a 302 Redirect. If the coder has not taken into

     

    account the possibility of a redirect, it may fall through the error handling -- or, worse, it may call abort().

     

     

    In your case, I think the situation is a little different; I can't say for sure without digging into your code, but I suspect that your application is doing an AJAX call to a method on

     

    a regular basis (the bf8ee-presence call, maybe) that is not configured to know how to respond to a 302 and instead calls abort(). You upload some files and get successes because

     

    your POST upload completes before the other AJAX call takes place, but get failed transfers because when abort() is called for an unrecognized response on the bf8ee-presence call

     

    it aborts the AJAX call for the transfer too. Thus, some transfers complete, some never do.

     

     

    Unsure why you're getting the error message; it could be that the behavior of a failed POST is to try again with GET... or that the browser has by then gotten another 302 and turns

     

    the POST attempt into a GET (that's what redirects tend to do to POSTs).

     

     

    Glad the stream profile fixed it for you. If you really want to see what is going on here, you should turn off the stream profile, capture an HTTPwatch of the transaction, then turn the

     

    stream profile back on and compare the delivered files. I'd be willing to bet you're going to see some changes to downloaded Javascripts.

     

     

  • The above posters are also correct. Your ultimate solution here is to identify which specific files need the stream changes and write an iRule to apply the stream filter

     

    to just those files or maybe some specific content-types. Otherwise you risk .doc files being modified if they contain the http:// bare link -- stream doesn't discriminate

     

    when used the way you're using it.
  • Thanks to everyone for the help!

    So I would want to accomplish this like so

    when HTTP_REQUEST{
        if{ [HTTP::header Content-Type] contains "text/html;charset=UTF-8" or "text/javascript;charset=UTF-8"or "text/css;charset=UTF-8"} {
            STREAM::expression {"@http://learning.usuhs.mil@https://learning.usuhs.mil@"}
        }
    } 

    This would perform the rewriting on all html, javascript and css?
  • Hey Willy,

    I believe this will do exactly that. You might want to consider, however, using a data group and matchclass for this, though. This will make it a lot easier to change the list of content-types in the future without actually changing anything in the rule.

    It would probably look something like this:

    
     when HTTP_REQUEST {
         if { [matchclass $::content-type contains [HTTP::header "Content-Type"]] } {
             STREAM::expression {"@http://learning.usuhs.mil@https://learning.usuhs.mil@"}
        }
    }

    Be sure to read the notes about using the partial match operators here, though: http://devcentral.f5.com/wiki/default.aspx/iRules/matchclass.html

    \\ Ben