Forum Discussion

Ian_Upton_39258's avatar
Ian_Upton_39258
Icon for Nimbostratus rankNimbostratus
Aug 27, 2008

Modifying HTTP Version

We have just implemented a F5 based solution and have encountered a problem where SSL based transactions via a proxy just hung. Tracked down to IE 6 (HTTPM settings) HTTP version 1.0, something odd in the combination of proprietary web server, squid proxy and the F5.

 

 

Difficult to fix as we cannot control the state of IE 6 on customer PCs and cannot modify the proprietary web server.

 

 

I have managed to get around it with an iRule in the F5 as follows:

 

 

Any incoming HTTP 1.0 GET set the HTTP version to 1.1.

 

Any outgoing HTTP 1.1 set the HTTP version to 1.0.

 

 

It works but I am concerned about the following:

 

 

The following iRule snippet re-writes the HTTP version in the GET passed to the web server BUT also deletes any other data (language, cookie, etc).

 

 

if { [HTTP::version] eq "1.0" }

 

{

 

HTTP::cookie "1.1"

 

}

 

On out going traffic I do the reverse, set the HTTP version to 1.0.

 

 

The question/s are:

 

Is does this also modify the data from the web server????

 

 

As we are using cookie persistence (insert method) do I clobber the "inserted" cookie and lose persistence???

 

 

On input can I modify the HTTP version without losing the remainder of the data????

 

 

Any help appreciated, Ian
  • hoolio's avatar
    hoolio
    Icon for Cirrostratus rankCirrostratus
    Hi Ian,

    Can you try using HTTP::version "1.0" (Click here) to modify the version? Something like this...?

     
     when HTTP_REQUEST { 
         Reset the variable tracking whether to update the HTTP version to 1.0 
        set update_version 0 
      
         If client request is 1.0, update the LTM to server version to 1.1  
           and track that we need reset the clientside response to 1.0 
        if { [HTTP::version] eq "1.0" }{ 
           set update_version 1 
           HTTP::version 1.1 
        } 
     } 
     when HTTP_RESPONSE { 
      
         Check if the request was 1.0 and reset the response to 1.0 
        if { $update_version }{ 
           HTTP::version 1.0 
        } 
     } 
     

    You might also need to account for the Connection header in responses as it's not valid for HTTP 1.0. I imagine you could just remove the Connection header (HTTP::header remove Connection), but this is something you should ideally test.

    Aaron
  • Thanks for the response.

     

     

    A little research however indicates that a HTTP version 1.0 GET only consists of the GET, the URI and the HTTP version, no cookies or anything else. Therfore why all my version 1.1 GET/header content header dissapeared.

     

     

    Not good, Need to keep that cookie for perstence purposes. Looks like it may be case of fiddling the content of the version 1.1 GET until the server likes it.

     

     

    Ian
  • hoolio's avatar
    hoolio
    Icon for Cirrostratus rankCirrostratus
    Hi Ian,

    The HTTP 1.0 RFC didn't detail the use of cookies, but there wasn't anything within the spec that prohibited them from being used. In terms of the 1.0 version of the protocol, cookies are just a header in requests and responses. Are you saying that when you test the example iRule I posted, which changes the version from 1.1 to 1.0, that the Cookie header (or others?) is removed by LTM? I wouldn't expect this to happen.

    Or are you saying that somewhere between LTM and the end server, the cookie header is removed? If it's the former, can you test with this rule and reply with the log output from /var/log/ltm?

      
      when HTTP_REQUEST {   
        
          Log request headers  
         foreach a_header [HTTP::header names] {  
            log local0. "Pre:  $a_header: [HTTP::header value $a_header]"  
         }  
        
          Reset the variable tracking whether to update the HTTP version to 1.0   
         set update_version 0   
         
          If client request is 1.0, update the LTM to server version to 1.1    
            and track that we need reset the clientside response to 1.0   
         if { [HTTP::version] eq "1.0" }{   
            set update_version 1   
            HTTP::version 1.1   
         }  
          Log request headers  
         foreach a_header [HTTP::header names] {  
            log local0. "Post: $a_header: [HTTP::header value $a_header]"  
         }  
      }   
      when HTTP_RESPONSE {   
        
          Log response headers  
         foreach a_header [HTTP::header names] {  
            log local0. "Pre:  $a_header: [HTTP::header value $a_header]"  
         }  
        
          Check if the request was 1.0 and reset the response to 1.0   
         if { $update_version }{   
            HTTP::version 1.0   
         }   
          Log response headers  
         foreach a_header [HTTP::header names] {  
            log local0. "Post: $a_header: [HTTP::header value $a_header]"  
         }  
      }  
      

    Thanks,

    Aaron
  • Some more agonising over iRules, lots of packet dumps and debug log entries it would appear that I was looking in the wrong places when I thought that re-writing the HTTP version deleted a lot of data in the HTTP GET/POST/etc.

     

     

    Due to the SSL I cannot see the inserted cookie being sent to the client PC but some tools down there show it gets there. Post packets from the F5 to the server also contain the inserted cookie and log traces of the HTTP-RESPONSE show only one server is utilised (Cookie persistence).

     

     

    So it all seems to work. Tidied things up and handed it off to the application support types for testing, more testing........

     

     

    Thanks for the interest, Ian
  • hoolio's avatar
    hoolio
    Icon for Cirrostratus rankCirrostratus
    Good to hear you figured it out. You can use browser plugins to view the unencrypted HTTP headers and data (like LiveHttpHeaders for Firefox, Fiddler or HttpWatch for IE, or an interception proxy like BURP (portswigger.net) for any client that can be configured to use a proxy.

     

     

    Aaron