Redirection between HTTP URL and HTTPS URL is not followed.

Symptoms

When running applet in browser using Sun JVM, if the applet
makes HTTP
requests to a server which redirects to a HTTPS URL, the
redirection
would fail. It fails also in the case of making HTTPS requested
to a
server which redirects to a HTTP URL.

The same applet runs properly in Microsoft VM.


Cause

The issue is caused by the HTTP/HTTPS redirection policy
implemented in
Sun JVM; because of serious security consequences, redirection
between
HTTP and HTTPS is not automatically followed.

HTTP/HTTPS redirection is followed in MSVM, given a security
warning
dialog prompts the users everytime before the redirection is
followed.


Resolution

To workaround the problem, it is the application responsibility
to check
the response code and recognize it as a redirect. The Location
header
field value can be checked for the redirect information, and
then the
application must decide whether or not to follow the redirect
using the
new protocol. For example,

public void makeConnection(URL url)
{
    URLConnection conn = url.openConnection();
    InputStream is = conn.getInputStream();
    ....        
    is.close();
}


The code should be changed to
                
private InputStream openConnectionCheckRedirects(URLConnection
c)
        
                  throws IOException
    
{
        
    boolean redir;
        
    int redirects = 0;
        
    InputStream in = null;

        

    do 
    {
            
        if (c instanceof HttpURLConnection) {
                
            ((HttpURLConnection)
c).setInstanceFollowRedirects(false);
        }
 
            

        // We want to open the input stream before
            
        // getting headers, because getHeaderField()
            
        // et al swallow IOExceptions.
            
        in = c.getInputStream();
            
        redir = false;
 
            
        
        if (c instanceof HttpURLConnection) {
                
            HttpURLConnection http = (HttpURLConnection) c;
                
            int stat = http.getResponseCode();
                
        
            if (stat >= 300 && stat <= 307 && stat != 306 &&
                        
                stat != HttpURLConnection.HTTP_NOT_MODIFIED) {
                    
                URL base = http.getURL();
                    
                
                String loc = http.getHeaderField("Location");
                    
                URL target = null;
                    
                if (loc != null) {
                        
                    target = new URL(base, loc);
                    
                }
                    
                http.disconnect();
         

                // Redirection should be allowed only for HTTP 
                // and HTTPS, and should be limited to 5 
                // redirections at most.
                //           
                if (target == null
                        
                   || !(target.getProtocol().equals("http")
                        ||
target.getProtocol().equals("https"))
                   || redirects >= 5)
                    {
                {

                     throw new SecurityException("illegal URL
redirect");
                                }

                redir = true;
                    
                c = target.openConnection();
                    
                redirects++;
                
            }
            
        }
        
    } while (redir);
        
        
    return in;
    
}
        
public void makeConnection(URL url)
{
    URLConnection conn = url.openConnection();
    InputStream is = openConnectionCheckRedirects(conn);
    ....        
    is.close();
}


Related Information