Blank page on 301 and 302 redirects from Varnish

Events happening in the community are now at Drupal community events on www.drupal.org.
dmclark84's picture

Using the latest version of Pressflow 5.x. For pages that function as a 301/302 redirect I get a white page of death and the following response headers.

 HTTP/1.1 200 OK
  Server: Apache/2.2.3 (CentOS)
  X-Powered-By: PHP/5.1.6
  X-Drupal-Cache: HIT
  Etag: "1296751270-0"
  Cache-Control: public, max-age=21600
  Last-Modified: Thu, 03 Feb 2011 16:41:10 GMT
  Expires: Sun, 19 Nov 1978 05:00:00 GMT
  Vary: Cookie,Accept-Encoding
  Content-Type: text/html; charset=utf-8
  X-Cacheable: YES
  Content-Length: 0
  Date: Thu, 03 Feb 2011 17:40:58 GMT
  X-Varnish: 1896158831
  Age: 0
  Via: 1.1 varnish
  Connection: keep-alive
  X-Cache: MISS

So varnish is caching the pages and giving a 200 and no location header. When I remove varnish from in front I get the normal 301 or 302 and the location header and it works correctly.

So my problem is with trying to get Varnish not to cache those pages. I'm including my VCL file below. I've made several different attempts to try and get 301 and 302 pages not to cache, but thus far it has not been successful. We are currently running Varnish 2.1.5.

I've tried adding things as this under vcl_fetch just to try and get the redirect to work, but thus far have had no success:

if (beresp.status == 301 || beresp.status == 302) 
    { 
       set beresp.http.X-Cacheable = "NO: beresp.status";
       set beresp.http.X-Cacheable-status = beresp.status;
       return (pass);
    }

.vcl file:

backend default {
    .host = "qa2.test.org";
    .port = "7900";
#     .connect_timeout = 600s;
#     .first_byte_timeout = 600s;
#     .between_bytes_timeout = 600s;
#     .max_connections = 25000;
}


sub vcl_recv {
    set req.backend = default;

    set req.grace = 5m;

    remove req.http.X-Forwarded-For;
    set req.http.X-Forwarded-For = client.ip;

    # Properly handle different encoding types
    if (req.http.Accept-Encoding) {
        if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {
            # No point in compressing these
            remove req.http.Accept-Encoding;
        } elsif (req.http.Accept-Encoding ~ "gzip") {
            set req.http.Accept-Encoding = "gzip";
        } elsif (req.http.Accept-Encoding ~ "deflate") {
            set req.http.Accept-Encoding = "deflate";
        } else {
            # unkown algorithm
            remove req.http.Accept-Encoding;
        }
    }

    # Force lookup if the request is a no-cache request from the client
    if (req.http.Cache-Control ~ "no-cache") {
        return (pass);
    }

    ## Default request checks
    if (req.request != "GET" &&
        req.request != "HEAD" &&
        req.request != "PUT" &&
        req.request != "POST" &&
        req.request != "TRACE" &&
        req.request != "OPTIONS" &&
        req.request != "DELETE") {
            # Non-RFC2616 or CONNECT which is weird.
            return (pipe);
    }
    if (req.request != "GET" && req.request != "HEAD") {
        # We only deal with GET and HEAD by default
        return (pass);
    }
    if (req.request != "GET" && req.request != "HEAD") {
        # We only deal with GET and HEAD by default
        return (pass);
    }

    ## Modified from default to allow caching if cookies are set, but not http auth
    if (req.http.Authorization) {
        /* Not cacheable by default */
        return (pass);
    }

    ## Remove has_js and Google Analytics cookies.
    set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(__[a-z]+|has_js)=[^;]*", "");
    ## Remove a ";" prefix, if present.
    set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");
    ## Remove empty cookies.
    if (req.http.Cookie ~ "^\s*$") {
        unset req.http.Cookie;
    }
    ## Catch Drupal theme files  - THIS BREAKS UPDATE.PHP DO NOT USE
    #if (req.url ~ "^/sites/") {
    #    unset req.http.Cookie;
    #}
    # Catch Drupal misc files (like drupal.js and jquery.js)
    #if (req.url ~ "^/misc/") {
    #    unset req.http.Cookie;
    #}
    # Drupal js/css doesn't need cookies, cache them
    if (req.url ~ "^/modules/.*\.(js|css)\?") {
        unset req.http.Cookie;
    }

    ## Pass cron jobs and server-status
    if (req.url ~ "cron.php") {
       return (pass);
    }
    ## Don't cache install
    if (req.url ~ "install.php") {
        return (pass);
    }

    # if (req.url ~ "index.php") {
    #   unset req.http.Cookie;
    # }

    # This is for Global Redirect.
    if (req.url ~ "node\?page=[0-9]+$") {
             set req.url = regsub(req.url, "node(\?page=[0-9]+$)", "\1");
             return (lookup);
    }
    
    ## Don't cache Drupal logged-in user sessions
    if (req.http.Cookie ~ "(VARNISH|DRUPAL_UID)") {
        return (pass);
    }

    return (lookup);
}

# Per-session cache
sub vcl_hash { if (req.http.Cookie) { set req.hash += req.http.Cookie; } }

sub vcl_fetch {
    
    # These status codes should always pass through and never cache.
    if (beresp.status == 404 || beresp.status == 503 || beresp.status == 500) {
       set beresp.http.X-Cacheable = "NO: beresp.status";
       set beresp.http.X-Cacheable-status = beresp.status;
       return (pass);
    }

    # Grace to allow varnish to serve content if backend is lagged
    set beresp.grace = 5m;

    if (!beresp.cacheable) {
        set beresp.http.X-Cacheable = "NO: !beresp.cacheable";
        return (pass);
    }
    
    # All tests passed, therefore item is cacheable
    set beresp.http.X-Cacheable = "YES";
    return (deliver);
}
#
sub vcl_deliver {
   # return (deliver);
   # add cache hit data
   if (obj.hits > 0) {
     #if hit add hit count
     set resp.http.X-Cache = "HIT";
     set resp.http.X-Cache-Hits = obj.hits;
   } else {
     set resp.http.X-Cache = "MISS";
   }
}

sub vcl_error {
    if (obj.status == 503 && req.restarts < 5) {
        set obj.http.X-Restarts = req.restarts;
        restart;
    }
}

Comments

Hi, same problem on pressflow

xdemocle's picture

Hi,
same problem on pressflow 6.28
I think is a problem of varnish configuration.

My redirects working, but I receive the pages only for external website URL.

Sunday strange :((

Gentoo lover, web developer, Drupal specialist, LAMP and web administrator linux oriented.

in my case was the directive:

xdemocle's picture

in my case was the directive: obj.http.Location

that was written like: set obj.http.comation = obj.response;

Cause a fault replacing of text. sob

Gentoo lover, web developer, Drupal specialist, LAMP and web administrator linux oriented.

High performance

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds:

Hot content this week