views:

251

answers:

2

This may be the .NET version of this question.

I have an image script with the following:

...
Response.WriteFile(filename);
Response.End();

I am rewriting .jpg files using the following rewrite rule in web.config:

<rule name="Image Redirect" stopProcessing="true">
  <match url="^product-images/(.*).jpg" />
  <conditions>
    <add input="{REQUEST_URI}" pattern="\.(jp?g|JP?G)$" />
  </conditions>
  <action type="Rewrite" url="/product-images/ProductImage.aspx?path=product-images/{tolower:{R:1}}.jpg" />
</rule>

It basically just rewrites the image path into a query parameter.

The problem is that (intermittently of course) Mosso returns a new ASP Session cookie which breaks the whole world.

  • Directly accessing a static .jpg file does not cause this problem.
  • Directly accessing the image script does not cause it either.
  • Only rewriting a .jpg file to the .aspx script causes the session loss.

It's not a redirect loop - the image appears, but the cache server submits a new session cookie, which (because it's coming from my hostname) causes the session to reset.


Things I have tried

(From the Rackspace documentation How can I bypass the cache?)

I added Private cacheability to the image script itself:

Response.Cache.SetCacheability(HttpCacheability.Private);

I tried adding these cache-disabling nodes to web.config:

<staticContent>
  <clientCache cacheControlMode="DisableCache" />
</staticContent>

and

<httpProtocol>
  <customHeaders>
    <add name="Cache-Control private" value="Cache-Control private"
  </customHeaders>
</httpProtocol>

The Solution I need

The browser cache cannot be disabled. This means potential solutions involving Cache.SetNoStore() or HttpCacheability.NoCache will not work.

Alternately...

Please tell me why this is impossible to fix.

+1  A: 

Try using an httphandler instead of using URL rewrite. If it is the rewrite that is causing the problem on Rackspace Cloud, then this should fix the problem because it eliminates the use of rewrite:

Create an httphandler class in your App_Code folder:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
/// <summary>
/// Summary description for ProductImageHandler
/// </summary>
public class ProductImageHandler : IHttpHandler
{
    public ProductImageHandler()
    {

    }

    #region IHttpHandler Members

    public bool IsReusable
    {
        get { return true; }
    }

    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "image/jpg";

        // get path to image
        string pathString = Path.GetFileNameWithoutExtension(context.Request.RawUrl);

        // open file
        // ... insert your logic for manipulating pathString
        // so that it points to file you want to output
        // maybe something like pathString = "~/images/" + pathString + ".jpg";

        context.Response.WriteFile(pathString);
    }

    #endregion
}

And then setup entries in your web.config file so that this handler gets sent requests for JPEG files in the "/product-images/" folder:

<httpHandlers>
    <add verb="*" path="*/product-images/*.jpg" type="ProductImageHandler" validate="false"/>
</httpHandlers>

And also for integrated IIS mode:

<handlers>
    <add name="ProductImageHandler" preCondition="integratedMode" verb="*" path="*/product-images/*.jpg" type="ProductImageHandler"/>
</handlers>

One last thing - you will probably have to create a physical folder called "product-images" so that IIS doesn't return a 404 when it can't find the folder.

One other thing to note is that this is probably a better way to accomplish what you need to do because httphandlers don't have to go through the normal ASP.NET page life-cycle, which means this requires less memory and time to execute on the server.

Good luck dude!

Rafe
+1 This is the best answer by far - so good it made the others disappear! But I can't accept it because the button isn't there. Maybe this is part of making a bounty?
willoller
Yeah, maybe the bounty goes away after so many hours. No worries.
Rafe
A: 

It turns out that this is a limitation that Rackspace can't fix.

To solve the problem, I had to use a different subdomain to host the images (images.site.com). The subdomain was just an alias of the main site, but the hostname kept the Session from resetting on www.site.com.

I added some rewriting to point to my script handling the image retrieval to the Web.Config to keep the images returning from that subdomain, and to redirect back if the user browsed that subdomain directly.

Also, I suspect that Rafe's answer below would have solved the problem as well. If you run into this issue, that's the solution you should pursue!

willoller