RequestReduce
RequestReduce copied to clipboard
Supporting https & http on Appharbor
Hi,
Forgive me for asking about such a unique scenario, unfortunately, this issue resulted in me temporarily disabling request reduce until I had time to look into it (Hence my tardy reply to your other post).
Basically, AppHarbor use Forwarding headers on requests past their load balancers. This allows my app to know whether the request was a http, or https request.
Now, when using https, my users need to either have RequestReduce disabled, or use a URL Transformer to replace "http" with "https" in my resulting css. This works fine, but I can only get it to work if applied to ALL requests. Unfortunately, AppHarbor uses SNI-SSL, which throws errors on some browsers. This means I can't have an https-everywhere site.
My solution to this was to only do URL transformations if it's a HTTPS request, and was along the lines of:
RequestReduce.Api.Registry.UrlTransformer =
(context, x, y) =>
( IsSecureConnection(context.Request) : false)
? y.Replace("http://www.mysite.co", "https://www.mysite.co") : y;
Unfortunately, the context.Request paramater is always null.
I'm also thinking, that as the resulting css is saved, I would need multiple versions unless RR treats http and https as seperate requests and serves seperate css?
Is there a working solution for this scenario?
Thanks again, Daz.
Hi Daz,
Unfortunately there is no other solution to this other than globally turning on https. While the context parameter of the UrlTransformer should only be null for sprite url transforming (not js or css urls), it has to be null when generating sprites because that is done in the background where there is no access to the request context.
Thanks for the response!
I'm seeing non-null context values even though I have image sprite processing set to off, is this also what you would expect?
The code I posted causes no minified js/css to be stored by RR - because the context is always null, all minification attempts bomb out. I'm guessing there will be other issues with this set up, in that RR will serve up the same js/css regardless of whether it is http or https traffic? Hence, it needs to look at the whether ssl is enabled or not, and serve the relevant files. With appharbor, this is even more awkward due to their forwarding headers I mentioned previously.
I will hopefully find time to take a look at your source and propose some changes to allow for https/http differentiation, unfortunately I've not been able to find the time in the past couple of weeks.
Thanks again for the response! Daz.
Is there a way to disable (using config or code) the insertion of the host URL into the CSS? i.e. only change the URL of background images in CSS to absolute paths starting with "/".
In a similar situation where we have http and https version of the site, but https is only up to the firewall so the server is always operating in http. Since the URL of the background image is http this causes a warning message (some content is not being served over a secure connection) in some versions of IE.
If we could get rid of the URL insertion then a single merged CSS file would work for both connections. I am unable to force the URL to https using the "contentHost" config attribute because we are running in a CMS environment hosting multiple sites.
Yes. Use the urltransformer delegate discussed in the rr API wiki page and simply return the third input param removing the scheme and host if it ends in .css.
Thanks! This looks like good workaround for me as well.
Would you be able to point me in the right direction to making this work fully with js and images? FYI - I've added the following.
RequestReduce.Api.Registry.UrlTransformer =
(context, x, y) =>
y.Replace("http://", "//");
RequestReduce.Api.Registry.UrlTransformer =
(context, x, y) =>
y.Replace("https://", "//");
Unfortunately, this doesn't have an affect on:
- background-image's set in css
- where the value is set to url("//egregreah") - it gets turned into http://egregreah.
- external js, where the js itself contains references to http://
This pretty close to a fully working workaround though!
I just tried this myself and it did work for the css background images. It will not currently work for URLs embedded in javascript. This is a known limitation of RequestReduce.
One thing to note is that you do not want to have your http and https replacements in separate calls to the UrlTransformer property since that sets a single property and does not add a new transformer. So the second call will overwrite the first.
Perfect, thanks for the response. Will just do this for now:
RequestReduce.Api.Registry.UrlTransformer =
(context, x, y) =>
y.Replace("http://", "//").Replace("https://", "//");
Seems to make everything work - just need to be careful with which external js files I process.
Thanks!
Great, I will also implement this.
I still think this needs to be implemented out of the box though and there should be a config switch to NOT add domain names (better still, it should not do it by default unless CDN is specified).
Doing this will also will also save a few bytes in file size, and seeing as the whole point of RR....
The problem with schema-less URIs is that IE 7 and IE 8 will download the css referenced bu these URIs twice. Eventually (the sooner the better), this will be a small edge case and I'd be happy to make it the default but they just represent too large of a market share right now.
Having an option to keep the URLs relative is very fair.
I am reopening this since I plan to rework the absolute URL logic for.next weeks release. Essentially unless you are using the contenthost setting, rr generated URLs will be relative to the host.
Does anyone see any issues here?
Thanks matt.
Just to clarify - does that mean you will treat https and http traffic differently and thus serve up two different sets of files for each?
Also - note that on Appharbor for example, traffic appears to be http due to the load balancer.
I've been re-writing the urls such that they are schema-less as suggested previously and that approach works best for me. I know IE7&IE8 users suffer due to css being downloaded twice, but that's a browser bug I'm happy not to work around for now.
Cheers, Daz.
That's great, I think that is the expected behaviour from my point of view... Didn't know that about the http/https in Ie7/8 and agree that thing needs to die!
Look forward to the release.
@dazbradbury yeah. if it was just my own site I was coding for, I'd let the IE 7/8 users suffer :) In fact, IE 7/8 users may just get a big page with links to chrome/FF/IE 9 asking them to install a modern browser for "today's web" but I dont feel right making that decision for site owners since I know for some (like my own employer and probably biggest RR user - MS) this is a sensitive topic.
I won't create separate resources for http/https. At least not now. Since now most urls will be relative it wont matter. If you use the content host for a CDN or cookieless domain, you can always use the schema less url in the config too.
OK - thanks matt. I totally understand your reasoning - especially as MS are your employers! I used to have to support IE6 - but thankfully no longer!
I do use a CDN and schema less url in the config for most of my requests now - so I don't see this affecting me I guess. I was pretty happy with the previous workaround anyway!
Thanks again for taking the time to cover all the edge cases.
Cheers, Daz.
On Fri, Jun 1, 2012 at 4:37 PM, Matt Wrock < [email protected]
wrote:
@dazbradbury yeah. if it was just my own site I was coding for, I'd let the IE 7/8 users suffer :) In fact, IE 7/8 users may just get a big page with links to chrome/FF/IE 9 asking them to install a modern browser for "today's web" but I dont feel right making that decision for site owners since I know for some (like my own employer and probably biggest RR user - MS) this is a sensitive topic.
I won't create separate resources for http/https. At least not now. Since now most urls will be relative it wont matter. If you use the content host for a CDN or cookieless domain, you can always use the schema less url in the config too.
Reply to this email directly or view it on GitHub: https://github.com/mwrock/RequestReduce/issues/177#issuecomment-6063384
Darius Bradbury
Hi Matt,
Any more updates on this? I downloaded the latest package but it is still the same behaviour... is there a change log somewhere so we know what updates are in each release?
thanks
Hi, I'm not seeing the UrlTransformer called against resources inside CSS files. When I add logging I only see it called for the top level CSS and JS bundle urls.
I need to strip the host name from the urls. I was able to work around this by defining my own minifier and running a regex against the content.
I have not been able to get to this yet.Ramping up on a new job is unfortunately making it difficult to devote cycles here.
Fair enough and understandable. Keep us informed when you finally get a bit time to implement this.
thanks.
Understandable. Thanks for your efforts!
On Tue, Jun 26, 2012 at 11:34 AM, Matt Wrock < [email protected]
wrote:
I have not been able to get to this yet.Ramping up on a new job is unfortunately making it difficult to devote cycles here.
Reply to this email directly or view it on GitHub: https://github.com/mwrock/RequestReduce/issues/177#issuecomment-6579035
Wanted to follow up on this. We currently have a case where we have an htc file included in a stylesheet from a common shared content site that is included via a virtual directory. The style sheet entry ends up looking like
img.pngfix,div.pngfix img{behavior:url(/_common/htc/iepngfix.htc)
ReduceRequest is changing this to the full domain path.
img.pngfix,div.pngfix img{behavior:url([http://domain]/_common/htc/iepngfix.htc)
IE doesn't like this throwing a permission denied error which I'd expect. I thought that adding the following to our app startup would resolve this.
RequestReduce.Api.Registry.UrlTransformer =
(context, x, y) =>
y.Replace("[http://domain]", "");
But it doesn't seem to have any effect.
Is this issue the correct one to address this on? I'd like in general for the paths to not be modified at all if that is possible.
Yes, this is the same issue. I've used a different framework which doesn't touch the URL's, but personally I find this one better otherwise you end up having to put in longer, absolute paths in your source.
I couldn't get the above to work fro global.asax, so I put it in Page_Load of Masterpage, that did the trick but it doesn't seem quite right... I'm hoping the fix will be out soon...
Hello,
It appears I am also experiencing similar issue while using RequestReduce. It works fine locally(on my PC with http://) but once elevation to DEV environment done where "load balancing" will be applied. My portal works fine(I can use all my portal functionality) however RR could not process any of css ,javascript and background images as RR converted relative urls to fully qualified urls with "http://" where it supposed to be "https://" in DEV that causing below error...
: There were errors reducing http://computing-dev.exdev.net/Content/themes/base/reset.css::http://computing-dev.exdev.net/Content/themes/base/jquery-ui-1.8.14.custom.css::http://computing-dev.exdev.net/Content/themes/base/typography.css::http://computing-dev.exdev.net/Content/themes/base/eynav.css::http://computing-dev.exdev.net/Content/themes/base/structure-fluid.css::http://computing-dev.exdev.net/Content/themes/base/ey.css::http://computing-dev.exdev.net/Content/themes/base/Site.css:: Exception #2: RequestReduce had problems accessing http://computing-dev.exdev.net/Content/themes/base/reset.css. Error Message from WebClient is: The underlying connection was closed: An unexpected error occurred on a receive.
As soon as I change maually url from http://computing-dev.exdev.net/Content/themes/base/reset.css to https://computing-dev.exdev.net/Content/themes/base/reset.css,it works perfectly fine.
I tried with below code but does not help
RequestReduce.Api.Registry.UrlTransformer = (context, x, y) => y.Replace("http://", "//").Replace("https://", "//");
Wondering could anyone route me correct direction here?
Thanks, Ramani
You have to replace default Minifier with next one:
public class SchemaLessUrlReplacer : RequestReduce.Utilities.IMinifier
{
private readonly Minifier minifier = new Minifier();
public string Minify<T>(string unMinifiedContent) where T : RequestReduce.ResourceTypes.IResourceType
{
string content = minifier.Minify<T>(unMinifiedContent);
if (typeof(T) == typeof(RequestReduce.ResourceTypes.CssResource))
{
content = new StringBuilder(content).Replace("http://", "//").Replace("https://", "//").ToString();
}
return content;
}
}
Then register new one inside Application_Start() of global.asax:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
...
RequestReduce.Api.Registry.RegisterMinifier<SchemaLessUrlReplacer>();
...
}
}