Archive

Posts Tagged ‘URL’

HowTo: URL rewrite to redirect HTTP to HTTPS for non-local address

Below is an answer on how to redirect from HTTP to HTTPS using the URL Rewrite module for IIS, but ignoring local addresses used when debugging one’s app. Just contributed at https://stackoverflow.com/a/75898224/903783.

Needed it for an ASP.net MVC app I’m maintaining, since due to updated policy that the authenticating organisation had decided for the SSO (Apereo CAS) configuration, we couldn’t redirect anymore back to a non-HTTPs URL (had the user used plain HTTP to access our app that is), after signing in succesfully via the SSO.

Combined URL Rewrite based answers from How to redirect HTTP to HTTPS in MVC application (IIS7.5) and from the question’s page on StackOverflow, and added "127.0.0.1" apart from “localhost” for the ignored sites.

Note that the URL Rewrite approach is by far the simplest one to add and should kick in at the web server level before the web app has any chance to process the request.

I also see {REQUEST_URI} being used instead of {R:1} and pattern="^OFF$" instead of pattern="off".

At pattern added the ignoreCase="true" too, though it might be the default (same goes for enabled="true" for the rule, handy to have there if you want to turn some rule off when debugging some rule chain)

However, wondering based on https://serverfault.com/questions/224039/iis-url-rewrite-http-to-https-with-port/418530#418530 if one needs to use SERVER_NAME instead of HTTP_HOST in the pattern if non-default ports are used and specify the port in the Redirect url too

  <system.webServer>

  <!-- … -->

    <rewrite>
        <rules>

            <rule name="HTTP to HTTPS redirect (excluding localhost)" enabled="true" 
stopProcessing="true"> <match url="(.*)" /> <conditions> <add input="{HTTPS}" pattern="off" ignoreCase="true" /> <add input="{HTTP_HOST}" pattern="localhost" negate="true" /> <add input="{HTTP_HOST}" pattern="127.0.0.1" negate="true" /> </conditions> <action type="Redirect" redirectType="Permanent"
url="https://{HTTP_HOST}/{R:1}" /> </rule> </rules> </rewrite> <!-- … --> </system.webServer>
Categories: Posts Tags: , , , , , , , , ,

HowTo: Reset browser cache of CSS files upon ASP.net MVC app publish

On an ASP.net MVC webapp I’m maintaining, I had the issue that due to caching of older CSS (stylesheet) files in the browser, if the user didn’t press F5/refresh, it wasn’t showing you some message (since I had added the class .center-horiz-vert in the CSS that didn’t exist in the older cached css the browser had).

Instead of changing web.config to stop cachine of CSS files (in which case it would bring the CSS on every page load which is an overkill), I expanded on an idea mentioned by Maxim Kornilov on SO (https://stackoverflow.com/a/12992813/903783), on making the CSS URLs webapp version specific.

I added a fake version parameter to the URLs with the build number as value so that till I publish a new build the browser caches the CSS, but when I upload a new build it brings the new one since it cache with the url as a key (that now includes the build number as a dummy url parameter that the webserver will ignore and just fetch the CSS file when requested)

Maxim’s example was in ASP/ASP.net WebForms syntax instead of MVC’s and Razor Pages’ newer Razor syntax), so I contributed my solution for the case of an ASP.net MVC webapp that wants to serve a fresh copy of CSS files on every new build that you publish (will do this whether the CSS file has changed or not) so that browsers don’t use older cached copies of the file. Obviously this expands to any kind of files you link/load into your webpages via a URL.

1) Added to the webapp’s main class (was called MvcApplication) in Global.asax.cs

#region Versioning

public static string Version => 
typeof(MvcApplication).Assembly.GetName().Version.ToString();
//note: syntax requires C# version >=6 public static DateTime LastUpdated =>
File.GetLastWriteTime(typeof(MvcApplication).Assembly.Location); #endregion

the someProperty => someReadOnlyExpression syntax is just shorthand for someProperty { get { return … ;} } possible since C# 6

2) in its Content/_Layout.cshtml file I used to have the following to show build number and build datetime (based on the webapp’s main assembly) on the page footer:

Version @ViewContext.Controller.GetType().Assembly.GetName().Version 
(@string.Format("{0:yyyy/MM/dd-HH:mm:ss}",
@File.GetLastWriteTime(ViewContext.Controller.GetType().Assembly.Location)))

which I changed to the simpler:

Version @somewebappname.MvcApplication.Version
(@string.Format("{0:yyyy/MM/dd-HH:mm:ss}",
somewebappname.MvcApplication.LastUpdated))

3) it was loading the CSS via hardcoded link in _Layout.cshtml (still refactoring it) which I changed to:

<link href='@Url.Content("~/Content/Site.css?version=" + 
somewebappname.MvcApplication.Version)' rel="stylesheet" type="text/css" />

so if one right-clicks in the webpage and they do view source they see:

<link href='/Content/Site.css?version=2.1.5435.22633' 
rel="stylesheet" type="text/css" />

that is the CSS url is version specific thanks to the dummy parameter version

If a random number was used instead it would fetch the CSS at every page load which is usually undesired, especially if you are already pushing a new webapp build instead of individual page changes to the web server (so that you do have access to a build number that you can inject into URLs).

Note that to achieve auto-incrementing of build number, at Properties/AssemblyInfo.cs I have (see How to have an auto incrementing version number (Visual Studio)?):

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Revision 
// and Build Numbers by using the '*' as shown below: [assembly: AssemblyVersion("1.0.*")] //[assembly: AssemblyFileVersion("1.0.*")]
// don't use boh AssemblyVersion and AssemblyFileVersion with auto-increment

HowTo: Use WordPress Permalinks on IIS

at http://zachis.it/blog/7-dangers-of-using-windows-server-on-a-wordpress-installation/

the thing that guy says about Permalinks isn’t accurate at all (not that the other things that he says are any accurate that is). WordPress Codex have documentation on how to configure URL rewriting in web.config that is necessery for Permalinks to work in IIS.

e.g. at http://ClipFlair.net, if you press the "about" icon you’re taken to a WordPress site that runs on IIS and uses permalinks fine and hides the index.php too from the URL

in its web.config I have the following:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>

        <httpErrors>
            <remove statusCode="404" subStatusCode="-1" />
            <error statusCode="404" prefixLanguageFilePath="" path="/index.php?error=404" responseMode="ExecuteURL" />
        </httpErrors>

        <!– Needed for WordPress Permalinks –>
        <rewrite>
            <rules>

                <rule name="Main Rule" stopProcessing="true">
                    <match url=".*" />
                    <conditions logicalGrouping="MatchAll">
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
                    </conditions>
                    <!– <action type="Rewrite" url="index.php/{R:0}" /> –>
                    <action type="Rewrite" url="index.php" />
                </rule>

            </rules>
        </rewrite>

        <defaultDocument>
            <files>
                <clear />
                <add value="index.html" />
                <add value="index.php" />
                <add value="default.aspx" />
            </files>
        </defaultDocument>

    </system.webServer>
</configuration>

Gotcha: JS replace on document.location fails, use document location.href

This is my contribution to:
http://stackoverflow.com/questions/2652816/what-is-the-difference-between-document-location-href-and-document-location

Here is an example of the practical significance of the difference and how it can bite you if you don’t realize it (document.location being an object and document.location.href being a string):

We use MonoX Social CMS (http://mono-software.com) free version at http://social.ClipFlair.net and we wanted to add the language bar WebPart at some pages to localize them, but at some others (e.g. at discussions) we didn’t want to use localization. So we made two master pages to use at all our .aspx (ASP.net) pages, in the first one we had the language bar WebPart and the other one had the following script to remove the /lng/el-GR etc. from the URLs and show the default (English in our case) language instead for those pages

<script>
  var curAddr = document.location; //MISTAKE
  var newAddr = curAddr.replace(new RegExp("/lng/[a-z]{2}-[A-Z]{2}", "gi"), "");
  if (curAddr != newAddr)
    document.location = newAddr;
</script>

But this code isn’t working, replace function just returns Undefined (no exception thrown) so it tries to navigate to say x/lng/el-GR/undefined instead of going to url x. Checking it out with Mozilla Firefox’s debugger (F12 key) and moving the cursor over the curAddr variable it was showing lots of info instead of some simple string value for the URL. Selecting Watch from that popup you could see in the watch pane it was writing "Location -> …" instead of "…" for the url. That made me realize it was an object

One would have expected replace to throw an exception or something, but now that I think of it the problem was that it was trying to call some non-existent "replace" method on the URL object which seems to just give back "undefined" in Javascript.

The correct code in that case is:

<script>
  var curAddr = document.location.href; //CORRECT
  var newAddr = curAddr.replace(new RegExp("/lng/[a-z]{2}-[A-Z]{2}", "gi"), "");
  if (curAddr != newAddr)
    document.location = newAddr;
</script>
Categories: Posts Tags: , , , , , , ,

Gotcha: Image component not loading remote URLs during debugging

At ClipFlair’s Image component I use the following XAML to make it show an image from a URL that its ViewModel holds at a property named “Source”, of type Uri (URI = Uniform or Universal Resource Identifier in W3C parlance, something like a superset of the old classic URLs).

<Image Name="imgContent"
       HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
       Source="{Binding Source, Mode=OneWay}"
       Stretch="{Binding Stretch, Mode=OneWay}"
       >

I’ve had issues in the past with that component not loading an image, a tricky issue was when I had used Mode=TwoWay when data-binding to Source property – that was disastrous, since the Source property expects an ImageSource and just “plays it clever” internally, also accepting a conversion from a Uri. So when doing reverse binding too, you’d end up getting a null value at respective the ViewModel property.

So when it recently started not showing the test image (from a remote URL) that I had been using, I started wondering if it was some regression of that older bug, but couldn’t find some change in the respective code, plus in the Visual Studio XAML designer the component would load and display the remote image fine.

It turned out to be an issue with Silverlight’s security policy regarding cross-site access. The Image control is supposed to be able to load images from any remote URL (without the remote web server needing to have a ClientAccessPolicy.xml file for example to allow it, as is the case with the WebClient class), however I had recently found out that if at your Silverlight project you have selected at the “Debug”  tab the “Dynamically generate a test page” option, the Image control wouldn’t load remote images.

What I didn’t know was that even the “Out-of-browser application option there won’t let the Image control load remote images if you don’t select the web project that goes with your Silverlight project (supposing you have them in the same Visual Studio solution), but you happen to select your Silverlight project instead from the dropdown list.

I had changed that option without thinking it might cause an issue while doing other changes in the project. That’s why one should try to do a minimal set of related changes only and test again thoroughly each time (if only they had the time available to do it), so that they can spot such issues early and be able to relate newly introduced bugs to the recent small set of changes, helping to track down the exact change that caused the unwanted behaviour.

image

HowTo: Tell AddThis to not append tracking suffix on addressbar

ClipFlair’s project description website is based on WordPress (a quite extensible blogging platform based on PHP). The other day we had an issue with the AddThis Plugin for WordPress, which was adding tracking suffices (in the form #.UAxxxxx) to the end of our URLs on the browser address bar.

Moreover this wasn’t occuring in Internet Explorer, since it doesn’t support the History API – probably for more security against Phishing scams – that the AddThis plugin uses for its Address Bar Shares tracking feature.

At first I didn’t spot that setting at the Settings/AddThis menu in WordPress dashboard and was looking into configuring it manually (it’s “addthis_addressbar” boolean setting, probably kept in wp_config.php), but eventually our designer spotted it at the “Advanced” tab there (wonder how I missed that 2nd tab altogether in the first place).

addthis-settings-screen

Collection of Smooth Streaming Video URLs

Here are some Smooth Streaming URLs I found on the Internet that you could use during development to test your smooth streaming players (like those based on SMF).

If you haven’t yet started building your SMF-based player you can try the following URLs here: http://www.smoothhd.com/livetestplayer/

Update: you can also try Smooth Stream URLs at ClipFlair Studio Silverlight-based application, turning over its Clip component (using the “Wrench” button on its titlebar) and pasting the Media URL there. Alternatively, you can launch it directly using a URL of the form http://studio.clipflair.net?video=http://smoothstreamer.doit.wisc.edu/doit-nms/BBB_carbon/BBB.ism/Manifest

http://smoothstreamer.doit.wisc.edu/doit-nms/BBB_carbon/BBB.ism/Manifest

http://streams.smooth.vertigo.com/BigBuckBunny_30sec/bigbuck.ism/manifest

http://streams.smooth.vertigo.com/elephantsdream/Elephants_Dream_1024-h264-st-aac.ism/manifest (this one also features multiple audio streams, director’s comments in english and also english and spanish dialogs)

http://playready.directtaps.net/smoothstreaming/TTLSS720VC1/To_The_Limit_720.ism/Manifest

http://playready.directtaps.net/smoothstreaming/SSWSS720H264/ SuperSpeedway_720.ism/Manifest

At the same test server one can also find two audio-only smooth streams:

http://playready.directtaps.net/smoothstreaming/ISMAAACLC/Taxi3_AACLC.ism/Manifest

http://playready.directtaps.net/smoothstreaming/ISMAAACHE/Taxi3_AACHE.ism/Manifest

http://mediadl.microsoft.com/mediadl/iisnet/smoothmedia/Experience/ BigBuckBunny_720p.ism/Manifest

http://ecn.channel9.msdn.com/o9/content/smf/smoothcontent/bbbwp7/big%20buck%20bunny.ism/manifest

http://ecn.channel9.msdn.com/o9/content/smf/smoothcontent/elephantsdream/ Elephants_Dream_1024-h264-st-aac.ism/manifest

http://video3.smoothhd.com.edgesuite.net/ondemand/Big%20Buck%20Bunny%20Adaptive.ism/Manifest

http://video3.smoothhd.com/ondemand/Turner_Sports_PGA.ism/Manifest

http://video3.smoothhd.com/ondemand/Turner_Sports_NASCAR.ism/Manifest

http://video3.smoothhd.com/ondemand/Turner_Sports_MLB.ism/Manifest

http://video3.smoothhd.com/ondemand/Akamai_ASP_Cutdown.ism/Manifest

http://video3.smoothhd.com/ondemand/mix1/mix1.ism/Manifest

http://video3.smoothhd.com/ondemand/mix2/mix2.ism/Manifest

http://video3.smoothhd.com/ondemand/Big%20Buck%20Bunny%20Adaptive.ism/Manifest

http://video3.smoothhd.com/ondemand/ElephantsDream.ism/Manifest

http://video3.smoothhd.com/ondemand/Got_Imagination_(Indo).ism/Manifest

http://video3.smoothhd.com/ondemand/Got_Imagination_(California).ism/Manifest

http://video3.smoothhd.com/ondemand/Coral_Reefs.ism/Manifest

http://video3.smoothhd.com/ondemand/eHow_Wakeboard.ism/Manifest

http://video3.smoothhd.com/ondemand/eHow_Baseball.ism/Manifest

http://video3.smoothhd.com/ondemand/eHow_Alligator.ism/Manifest

http://video3.smoothhd.com/ondemand/NBA.ism/Manifest

http://video3.smoothhd.com/ondemand/Changeling.ism/Manifest

http://video3.smoothhd.com/ondemand/Livestrong_ThyroidCancer.ism/Manifest

http://video3.smoothhd.com/ondemand/Livestrong_BeginnerGuideExercising.ism/Manifest

http://video3.smoothhd.com/ondemand/Livestrong_Autism.ism/Manifest

Also found some (probably) Bollywood movie:

http://az280594.vo.msecnd.net/athadu/athadu480.ism/Manifest

You can use the following search query to search for “.ism/Manifest”:
http://www.google.com/?q=%22http%22+%22.ism%2FManifest%22&oq=%22http%22+%22.ism%2FManifest%22

A good source found is http://www.smoothhd.com/content/smoothhd/smoothhd.xml

which seems to be from http://wwwns.akamai.com/hdnetwork/demo/silverlight/default.html

Some more URLs (use the unencrypted ones that write CLEAR) are found at:

http://playready.directtaps.net/smoothstreaming/

Gotcha: Silverlight’s Uri class constructor eats up part after last slash

Via trial and error, I recently found out that when creating a Uri combining another Uri and a suffix part (tried at Silverlight, but I guess it’s a .NET issue in general), it eats up the last part of the (first) Uri if it doesn’t end with "/".

That is, if you combine http://test.com/a with b.doc you get http://test.com/b.doc instead of http://test.com/a/b.doc that one might expect having used the Path.Combine of .NET on the local filesystem before (if hope I do remember well how that one behaves). So you have to make sure the first part of the path you combine has / at the end (e.g. http://test.com/a/ in the case above).

Personally I feel this is a bug at Uri class (since it breaks the least surprise principle [for developers with desktop experience at least]), but it may have been made so to follow some W3C suggestions or Javascript standard behaviour or whatever.

Example:

The following code will eat up part after last / (that is Uploads) instead of appending / (as Path would do on Windows).

const string STORAGE_URL = "http://test.com/Uploads"; //error: need "/" at end
Uri fileUri = new Uri(new Uri(STORAGE_URL), fileName + ".wav");

So, one can use instead:

const string STORAGE_URL = "http://test.com/Uploads";
Uri fileUri = new Uri(STORAGE_URL + "/" + fileName + ".wav");

Else fix the STORAGE_URL at the first sample to have "/" at the end (but this can break easily by changing the URL in the future and forgetting to add the trailing / or reading it from some configuration file and having the user enter a URL without a trailing / which can easily occur)

more IE9 RC issues – Tale of two Internet shortcuts

Can you spot any difference at the following two Internet shortcuts on my desktop?

image

I can’t either. Note that the two files have the same “name”, but different file extension (invisible when using default Windows Explorer folder view settings). The one uses “.url” (classic Internet Explorer webpage shortcut), while the other one, created by Internet Explorer 9 RC when I drag-dropped a page’s icon from the address bar onto my desktop, uses the file extension “.website”. That’s why although they seem to the user to have the same name, they can still co-exist on the same folder (the desktop).

However, there are important differences on how these two Internet shortcuts behave. If you open the .url one with IE9 RC you get the window at the 1st image shown below, whereas if you open the “.website” one, you get the window at the 2nd image shown below. Notice the difference on the address bar? The Back and Forward buttons now have a different color (they get their color from the page icon somehow, maybe calculating the dominant color or something from there) and there’s also the page icon showing up at the start of the address bar (can click on it to go back to this page if you’ve navigated away from it).

Note that when you drag-drop the webpage icon from IE9 RC address bar onto the desktop you also do notice a different behaviour (than you were used to) from IE9, in that it closes that page and opens it up in a new window, with that modified address bar, 2nd image as shown below.

imageimage

Right-clicking each of those two files (the .url and the .website ones), and selecting “Properties”, you get the displays shown below on the left and right sides respectively. You’ll notice that the “.url” file is called an “Internet Shortcut”, whereas the “.website” one is called a “Pinned Site Shortcut”.

image

Note that the “.url” file’s “Properties” action takes you directly to a tab other than the “General” one, called “Web Document” (a custom property page) with more info on the URL, a tab that is missing (I’d consider this a bug) from the “.website” file properties dialog. That way you can’t edit the URL from the properties dialog, neither can you set a “Shortcut key” for launching the shortcut using the keyboard.

image

Right-clicking the “.url” file and selecting “Send to > Notepad” (assuming you have installed “SendTo tools” or similar utility, or created a shortcut to “Notepad.exe” at your SendTo folder), you see the following contents:

[InternetShortcut]
URL=http://www.guardian.co.uk/commentisfree/cifamerica/2011/feb/14/useconomy-usemployment
IconFile=http://www.guardian.co.uk/favicon.ico
IconIndex=1

Right-clicking the “.website” file and selecting “Send to > Notepad” (assuming you have installed Send To tools or created a Notepad shortcut at your SendTo folder), you see the following contents:

[{000214A0-0000-0000-C000-000000000046}]
Prop4=31,The revenge of trickle-down economics | Richard Wolff | Comment is free | guardian.co.uk
Prop3=19,2
[InternetShortcut]
URL=http://www.guardian.co.uk/commentisfree/cifamerica/2011/feb/14/useconomy-usemployment
IDList=
IconFile=http://www.guardian.co.uk/favicon.ico
IconIndex=1
[{9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}]
Prop5=8,Microsoft.Website.CF19EB85.7C0F63A3
[{A7AF692E-098D-4C08-A225-D433CA835ED0}]
Prop5=3,0
Prop2=65,2C0000000000000001000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30000005900000085030000D4010000C6
Prop6=3,1

I find the new IE9 RC behaviour non-intuitive, esp. the action of closing old tab and popping up a new window when you drag-drop the page icon from the address bar onto the desktop. This violates the UI design principle of “least surprise” for the user.

Moreover it refreshes the page when doing that (which can result in loss of data if you were filling-in something online and hadn’t submitted yet – hope it does at least respect webpages that use closing event handler to warn the user they haven’t saved and allow them to cancel the page closing).

You can see more info on Pinned Site Shortcuts at http://msdn.microsoft.com/en-us/ie/dd797411 (as a reader of my previous blog post pointed out).

Categories: Posts Tags: , , , , ,