Rewrite.NET -- A URL Rewriting Engine for .NET

By Robert Chartier

This article examines how to take advantage of HttpModules to create a URL rewriting engine in .NET. This tool has been described as the Swiss Army Knife of URL manipulation. If you don't have a fundamental understanding of what HttpModules are and how to create and use them, review Mansoor Ahmed Siddiqui's article "HTTP Handlers and HTTP Modules in ASP.NET".

Section 1: The Engine and a Simple Rule

This section shows how easy it is to create the rewrite engine as an HttpModule and to create a simple rule. The next section dives into creating a more complex rule. Read over Section 1 only to learn about the underlying implementation of the rules engine and its rules. To see how to add or modify the existing rules, skim through this section and then skip to Section 2.

Keep in mind that when referring to the "engine" itself, I'm referring to the portion of the application that is responsible for loading and executing the "rules". "Rules" refers to those portions of the application that actually process the rules set by the administrator. Rules are any class that implements the "IRules" interface (see below).

Step 1: Creating the HttpModule

The first step in creating any HttpModule is creating the class that implements the IHttpModule interfaces. Start up Visual Studio .NET, create a new C# Web application ("Rewrite.Test"), and then add a new C# Class library named "Rewrite.NET" to the same solution. Create the new Web application first so that we can use that application to test the HttpModule and not break any other portion of the site.

I have renamed the default "Class1" to "Rewrite". Figure 1.1 below is its full source. (Don't forget to add the reference to System.Web in the class library).

Figure 1.1.1 Rewrite.cs Source Listing

using System;

 

namespace Rewrite.NET {

public class Rewrite : System.Web.IHttpModule {

 

/// <summary>

/// Init is required from the IHttpModule interface

/// </summary>

/// <param name="Appl"></param>

public void Init(System.Web.HttpApplication Appl) {

//make sure to wire up to BeginRequest

Appl.BeginRequest+=new System.EventHandler(Rewrite_BeginRequest);

}

 

/// <summary>

/// Dispose is required from the IHttpModule interface

/// </summary>

public void Dispose() {

//make sure you clean up after yourself

}

 

/// <summary>

/// To handle the starting of the incoming request

/// </summary>

/// <param name="sender"></param>

/// <param name="args"></param>

public void Rewrite_BeginRequest(object sender, System.EventArgs args) {

//process rules here

}

 

}

}

There really isn't anything new in this block of code. Note, however, that I have trapped only the BeginRequest within the Init() method. The Rewrite_BeginRequest is where we will implement our rules engine.

At this step, take time to make the necessary modifications to the Web.config file so ASP.NET will know about the new handler. Figure 1.1.2 below shows the changes made to the Web.config file in the "Rewrite.Test" application.

Figure 1.1.2 Web.config Changes

<system.web>

<httpModules>

<add type="Rewrite.NET.Rewrite,Rewrite.NET" name="Rewrite.NET" />

</httpModules>

</system.web>

Keep in mind that once you add the handler to Web.config, ASP.NET will require that the DLL actually be placed into that application's /bin folder. To help with this, set the Output Path for the Rewrite.NET project's properties to the "/bin" folder (C:\Inetpub\wwwroot\Rewrite.Net\bin\). Now, all that remains is to rebuild the solution and refresh any page within that application.

Step 2: A Simple Rewrite Rule

In this section a very simple rule is created that allows the Web site administrator to easily add and remove rules from the rule set. The easiest rule simply maps one URL to another. Let's say that you recently changed the location of some folders within your organization's site and want all of the links to stay valid. Well, we can write a very simple rule to handle this. Here are some examples:

Old URLNew URL
foo.com/aboutus.htmlfoo.com/aboutus.aspx
foo.com/help/foo.com/docs/help/

Obviously, there are many instances when something this simple would come in handy, such as when mapping a file or directory request to another file or directory request, for example. In order to accomplish this, there are three tasks to complete:

  1. Create the configuration section in the Web.config file (add new items)
  2. Load the configuration file in at runtime
  3. Process request, and rewrite the URL (redirect the browser).

Creating the configuration section in the Web.config file is very easy to do. (To review the <configSections> element, review the documentation at http://msdn.microsoft.com/library/en-us/cpgenref/html/gngrfconfigsectionselementcontainertag.asp, http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpcondeclaringcustomconfigurationsections.asp, http://msdn.microsoft.com/library/en-us/cpguide/html/cpcondeclaringsectiongroups.asp.)

Here are the additions to the Web.config file:

Figure 1.2.1 Web.config Additions

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

<configSections>

<sectionGroup name="Rewrite.NET">

<section name="SimpleSettings" type="System.Configuration.NameValueSectionHandler,System" />

</sectionGroup>

</configSections>

<Rewrite.NET>

<SimpleSettings>

<add key="/rewrite.net/webform1.aspx" value="/rewrite.net/finalpage.aspx" />

</SimpleSettings>

</Rewrite.NET>

And then the new Rewrite_BeginRequest event handler is captured:

Figure 1.2.2

public void Rewrite_BeginRequest(object sender, System.EventArgs args) {

//process rules here

 

//cast the sender to an HttpApplication object

System.Web.HttpApplication Appl=(System.Web.HttpApplication)sender;

 

//load the settings in

System.Collections.Specialized.NameValueCollection SimpleSettings = (System.Collections.Specialized.NameValueCollection)System.Configuration.ConfigurationSettings.GetConfig("Rewrite.NET/SimpleSettings");

 

//see if we have a match

for(int x=0;x<SimpleSettings.Count;x++) {

string source=SimpleSettings.GetKey(x);

string dest = SimpleSettings.Get(x);

if(Appl.Request.Path.ToLower() == source.ToLower()) {

SendToNewUrl(dest, Appl);

break;

}

}

}

 

public void SendToNewUrl(string url, System.Web.HttpApplication Appl) {

Appl.Context.RewritePath(url);

}

Notice how we are simply scanning the new configuration section for the source URL, and if it matches, the request is redirected to the new URL that was also specified in the config file.

Step 3: Adding Extensibility

In this step we will add some flexibility to our solution by creating an extensible rules engine. Take time now to add a new C# Class library to this solution named "RulesEngine". Within this new project, an interface, "IRules", will be defined, which all of our rules need to implement. We then will implement the actual engine, which will process these rules based on that interface and in turn redirect the user to the appropriate destination. Finally we will modify our Rewrite_BeginRequest method to use the engine to add new rules and to execute them.

The Interface

Our interface is very simple. It only has one method, "Execute", which will take the HttpApplication, the current path, and the settings section (from the Web.config file) as parameters. This will give each rule access to all of the HttpApplication's members, including the current path (either actual path or some transformed path along with the query string). We are also specifying the settings section so that we can have more than one rule set using the same object. That is, we can specify more than one set of rules for the same rule definition (object that implements the IRules interface). For example, we wanted to use a simple rule, but still be able to apply different rules on later dates. This will be made clearer later. Figure 1.3.1 below has the complete listing.

Figure 1.3.1 IRules Interface Source Listing

using System;

 

namespace RulesEngine {

public interface IRules {

string Execute(System.Web.HttpApplication Appl, string Path, string SettingsSection);

}

}

The Engine

The concept of a rules-engine based on an interface is not a new one. It merely will loop for each item in the list and call the Execute method. In this case, the goal was to be able to add rules on top of other rules, or execution of the rule processing will break when the app discovers any matching or duplicate rules.

For example, if you had to apply a set of rules to an application because of some path changes, and then you needed to apply more rules on top of those (since over time, things change), this method would be a good choice for a cumulative rule set. Alternatively, you could simply allow the application to break out of the rules loop, and redirect as soon as a path is found in any set of rules. Notice I have an enum declared for this within the engine. Figure 1.3.2 below is the listing for the rules engine:

Figure 1.3.2 The Rules Engine

public string Execute() {

string r="";

string newresult="";

//tear off the keylist for easy access

string[] keylist = new string[rules.Keys.Count];

rules.Keys.CopyTo(keylist,0);

RulesEngine.IRules rule=null;

if(rules!=null && rules.Count>0) {

//let s process the first off of the top, in case we only have one item

rule = (RulesEngine.IRules)rules[keylist[0]];

if(rule!=null) {

//execute it, and return if we need to

r = rule.Execute(appl, Getpath(appl), (string)keylist[0]);

if(engineType==EngineTypes.BreakOnFirst && r!="")

return r;

else {

for(int x=1;x<rules.Count;x++) {

//each rule will simply take the Application and modify the path

//it will return the new path to be used for successive rules

//this allows you to chain together successive rules

rule = (RulesEngine.IRules)rules[keylist[x]];

//if r is "" then let s set it back to the path again.

//each rule can optionally use its value, but it is needed for the simple rule

//it is merely used to carry forward the last transformation that was done to the path

if(r=="") r=Getpath(appl);

newresult = rule.Execute(appl, r, (string)keylist[x]);

//should we return because we want to break on the first item?

if(engineType==EngineTypes.BreakOnFirst && newresult!="") {

r = newresult;

break;

}

//make sure r has the most recent value

r=(newresult=="")?r:newresult;

}

}

} else {

return r;

}

}

return r;

}

Changes to Our Simple Rule

Our simple rule consists of the majority of the code that we placed into the Rewrite_BeginRequest method above, with the small exception of returning the new URL, if found, instead of automatically redirecting. How and when redirection will occur will be controlled by the engine. Figure 3.3 below is the first implementation of our IRules interface for the engine with the Simple Rule set.

Figure 1.3.3 Simple Rule

using System;

 

namespace RulesEngine {

/// <summary>

/// Summary description for SimpleRule.

/// </summary>

public class SimpleRule : IRules {

public string Execute(System.Web.HttpApplication Appl, string Path, string SettingsSection){

//load the settings in

System.Collections.Specialized.NameValueCollection SimpleSettings = (System.Collections.Specialized.NameValueCollection)System.Configuration.ConfigurationSettings.GetConfig(SettingsSection);

 

//see if we have a match

for(int x=0;x<SimpleSettings.Count;x++) {

string source=SimpleSettings.GetKey(x);

string dest = SimpleSettings.Get(x);

if(Path.ToLower() == source.ToLower()) return dest;

}

return "";

}

}

}

Lastly we need to bring it all together. The Rewrite_BeginRequest method will need to be modified to use the engine and to execute the rules in order. Don't forget to add the Project Reference to the new project in our solution. Figure 1.3.4 shows the new Rewrite_BeginRequest method and Figure 1.3.5 shows the relevant section of the Web.config file.

Figure 1.3.4 The New Rewrite_BeginRequest

public void Rewrite_BeginRequest(object sender, System.EventArgs args) {

//process rules here

 

//cast the sender to an HttpApplication object

System.Web.HttpApplication Appl=(System.Web.HttpApplication)sender;

 

RulesEngine.Engine e = new RulesEngine.Engine();

RulesEngine.SimpleRule simple = new RulesEngine.SimpleRule();

e.AddRule("Rewrite.NET/SimpleSettingsMay1", simple);

e.EngineType=RulesEngine.Engine.EngineTypes.Cumulative;

string r = e.Execute(Appl);

//only redirect if we have to

if(r!="" && r.ToLower()!=Appl.Request.Path.ToLower()) SendToNewUrl(r, Appl);

<configSections>

<sectionGroup name="Rewrite.NET">

<section name="SimpleSettingsMay1" type="System.Configuration.NameValueSectionHandler,System" />

<section name="SimpleSettingsMay10" type="System.Configuration.NameValueSectionHandler,System" />

</sectionGroup>

</configSections>

 

<Rewrite.NET>

<SimpleSettingsMay1>

<add key="/rewrite.net/webform1.aspx" value="/rewrite/index.aspx" />

</SimpleSettingsMay1>

</Rewrite.NET>

In the next section we will make one more final change to the Rewrite_BeginRequest method where we load the individual rules from the Web.config file. This will allow us to add on more rules by simply modifying the Web.config file and require no more recompiling of the actual HttpModule. We will only need to make the changes to the Web.config and restart the application iireset.exe.

Dynamic Rule Loading

Dynamic rule loading will allow our HttpModule to pull out the desired rules from the Web.config file at runtime. There are two important steps to accomplishing this task:

  1. Reading the new Index section in the Web.config
  2. Reading each item in the Index and loading the new rule
Remember that since the name for each section will be defined later, we will never know its actual name during design time. So in order to accommodate for this and to be able to indicate the assembly and class name each section will use, we will create a new section within our Rewrite.NET section group named "Index". This new Index section will be used to list each section and the assembly information that each section will use. Keep in mind that each section is really a rule. We have a file (assembly), and within that file we are expecting a class which implements the IRules interface, so we need to specify the file and then the class. The assembly information provides simply the name of the DLL and the class to use in the DLL that implements our IRules interface.

Figure 1.3.6 lists the new and final Rewrite_BeginRequest method, Figure 1.3.7 lists the new Web.config sections, and Figure 1.3.8 is a listing of the new overloaded constructor for our engine where we load the individual rules that are found in the Web.config file.

Figure 1.3.6 Final Rewrite_BeginRequest

public void Rewrite_BeginRequest(object sender, System.EventArgs args) {

//process rules here

 

//cast the sender to an HttpApplication object

System.Web.HttpApplication Appl=(System.Web.HttpApplication)sender;

 

//load up the rules engine

RulesEngine.Engine e = new RulesEngine.Engine(Appl);

string r = e.Execute();

 

//only redirect if we have to

if(r!="" && r.ToLower()!=RulesEngine.Engine.Getpath(Appl).ToLower()) SendToNewUrl(r, Appl);

 

 

}

Figure 1.3.7 New Web.config Details

<configSections>

<sectionGroup name="Rewrite.NET">

<!--index entry is required-->

<section name="Index" type="System.Configuration.NameValueSectionHandler,System" />

<!--each optional section name needs to be defined for each rule/section you want-->

<!--you can have more than one section, with the same rule (SimpleRule, etc..)-->

<section name="SimpleSettingsMay1" type="System.Configuration.NameValueSectionHandler,System" />

</sectionGroup>

</configSections>

 

<Rewrite.NET>

<Index>

<!--

Format:

<add key="SECTION NAME" value="NAMESPACE.CLASSNAME,ASSEMBLY NAME" />

Example:

<add key="SimpleSettingsMay1" value="RulesEngine.SimpleRule,RulesEngine" />

-->

<add key="SimpleSettingsMay1" value="RulesEngine.SimpleRule,RulesEngine" />

</Index>

<!--the actual settings for the rule set for the section-->

<SimpleSettingsMay1>

<add key="/rewrite.net/webform1.aspx" value="/someplace/" />

</SimpleSettingsMay1>

</Rewrite.NET>

Figure 1.3.8 Overloaded Engine Constructor

public Engine(System.Web.HttpApplication Appl) {

appl=Appl;

//load up rules from web.config

System.Collections.Specialized.NameValueCollection SectionIndex =

(System.Collections.Specialized.NameValueCollection)

System.Configuration.ConfigurationSettings.GetConfig("Rewrite.NET/Index");

 

if(SectionIndex!=null) {

for(int x=0;x<SectionIndex.Count;x++) {

string sectionname = "Rewrite.NET/" + SectionIndex.Keys[x];

string sectiondata = SectionIndex[x];

string[] asmdata = sectiondata.Split(',');

if(asmdata.Length==2) {

string progid = asmdata[0].Trim();

string asmname = asmdata[1].Trim();

string filePath = Appl.Request.PhysicalApplicationPath + @"bin\" + asmname + ".dll";

if(progid !="" && asmname!="" && System.IO.File.Exists(filePath)) {

System.Reflection.Assembly asm = System.Reflection.Assembly.LoadFrom(filePath);

if(asm!=null) {

RulesEngine.IRules rule = (RulesEngine.IRules)asm.CreateInstance(progid, true);

if(rule!=null) {

this.AddRule(sectionname, rule);

}

}

}

}

}

}

 

}

Once compiled, our HttpModule can handle dynamically added rules and rule sets for incoming requests.

Section 2: Adding More Rules

This step examines how to create a more complex rule using regular expressions and add it to the engine via the Web.config file.

In order to add new rules to our engine we simply need to create the new class. This class is derived from the IRules interface. For this section we will start with a completely new solution in VS .NET. We will add a new rule to our application to handle regular expression search and the replacing of the URL. Here are the steps to set up our environment for this or any other rule you wish to create:

  1. Load up a new C# Class Library named "RegExpRule" in VS .NET.
  2. Rename the class and the file name to "RegExp".
  3. Right click the project, choose Properties, and set the "Output Path" to the same "\bin" folder of the application where the HttpModule is installed. For example, mine is located at "C:\Inetpub\wwwroot\Rewrite.NET\bin\".
  4. Right click the project, Add Reference, add in the .NET reference to our "RulesEngine.dll". Again, mine is located at "C:\Inetpub\wwwroot\Rewrite.NET\bin\RulesEngine.dll". Also add the reference to System.Web.
  5. Implement the IRules Interface for the RegExp class. See Figure 2.1.

Figure 2.1 The RegExp Class

using System;

 

namespace RexExpRule {

public class RegExp : RulesEngine.IRules {

public RegExp() {

}

public string Execute(System.Web.HttpApplication Appl, string Path, string SettingsSection){

return "";

}

}

}

The actual logic for our Regular Expression Rule now needs to be implemented. This rule will load up all of the regular expression strings out of the Web.config file and apply them to the path variable of the incoming request for matching and transforming the path. If you are unfamiliar with regular expressions, use the URLs in this article's References section.

The key to this rule is .NET Framework's System.Text.RegularExpressions.Regexp.Replace(String, String, String) Method (http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemTextRegularExpressionsRegexClassReplaceTopic6.asp). This method allows us to specify the input text (the path and query string), a pattern to match, and a replacement for that pattern. For example, if we had the path "/corp/home.aspx" and we wanted to redirect all of the incoming requests for the "/corp/" path to the new "/about/" folder, we could easily set up the parameters:

Input = "/about/home.aspx"
Pattern = "^/corp/(.*)"  
Replacement = "/about/$1"
In order to do this, we simply add the Replace() method to our Execute() Method, as show in Figure 2.2 below.

Figure 2.2 The New Execute() Method

public string Execute(System.Web.HttpApplication Appl, string Path, string SettingsSection){

string input = RulesEngine.Engine.Getpath(Appl);

 

System.Collections.Specialized.NameValueCollection Settings = (System.Collections.Specialized.NameValueCollection)System.Configuration.ConfigurationSettings.GetConfig(SettingsSection);

 

//see if we have a match

for(int x=0;x<Settings.Count;x++) {

string pattern=Settings.GetKey(x);

string replacement = Settings.Get(x);

input = System.Text.RegularExpressions.Regex.Replace(input, pattern, replacement);

}

return input;

}

Next, we need to make a few additions to our Web.config in order to load and set up the actual rules conditions for our RegExp rule. As seen in the previous section we need to take a number of steps to accomplish this:

  1. Add a new <section> node within <sectionGroup> for the new rule

    <section name="RegExpRule1" type="System.Configuration.NameValueSectionHandler,System" />

  2. Add an entry into the <Index> node for the new rule

    <add key="RegExpRule1" value="RexExpRule.RegExp,RexExpRule" />

  3. And finally add our new RegExpRule1 section

    <RegExpRule1>

    <add key="^/rewrite.net/about/(.*)" value="/rewrite.net/corp/$1" />

    </RegExpRule1>

Now that it is done, notice we added the condition that when a URL matching "^/rewrite.net/corp/(.*)" is found (any file or folder under the corp directory of this application is found), we want to replace the URL with the pattern "/rewrite.net/about/$1". We are basically shifting the entire request, query string and all, to the new "/about" path. This has its obvious advantages over our Simple Rule above because we do not need to specify a full path or query string to any file. Instead we gain the power of a more generic search-and-replace methodology.

Conclusion

In this article you've seen how easy it is to create any HttpModule for custom purposes. It's exciting to see that Microsoft has given the average developer so much power, but we must always keep in mind that with this much power, it is easy to shoot ourselves in the foot. We must always use the right tool for the job.

We also covered the ability to leverage HttpModules in order to create a fairly simple URL Rewriter. That is, take the incoming request and, based on set rules, send the user to an alternative place.

I hope you enjoyed reading this article and implement some or all of its content in your real-life situations. If you have any questions, feel free to contact me at any time.

References

Extending ASP.NET with HttpHandlers and HttpModules - By Bipin Joshi
http://www.devx.com/dotnet/Article/6962/0/page/1

Apache HTTP Server Version 1.3 -- Module mod_rewrite, a URL Rewriting Engine
http://httpd.apache.org/docs/mod/mod_rewrite.html

Apache 1.3 URL Rewriting Guide
http://httpd.apache.org/docs/misc/rewriteguide.html

<configSections> element at MSDN
http://msdn.microsoft.com/library/en-us/cpgenref/html/gngrfconfigsectionselementcontainertag.asp

Declaring and Accessing Custom Configuration Sections
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpcondeclaringcustomconfigurationsections.asp

Declaring and Accessing Section Groups
http://msdn.microsoft.com/library/en-us/cpguide/html/cpcondeclaringsectiongroups.asp

Regular Expressions Usage in C#
http://www.c-sharpcorner.com/3/RegExpPSD.asp

Regular Expression Library
http://regxlib.com/

.NET Framework Class Library's Regex.Replace Method (String, String, String)
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemTextRegularExpressionsRegexClassReplaceTopic6.asp

About the Author

Robert Chartier has developed IT solutions for more than nine years with a diverse background in both software and hardware development. He is internationally recognized as an innovative thinker and leading IT architect with frequent speaking engagements showcasing his expertise. He's been an integral part of many open forums on cutting-edge technology, including the .NET Framework and Web Services. His current position as vice president of technology for Santra Technology (http://www.santra.com) has allowed him to focus on innovation within the Web Services market space.

He uses expertise with many Microsoft technologies, including .NET, and a strong background in Oracle, BEA Systems, Inc.'s BEA WebLogic, IBM, Java 2 Platform Enterprise Edition (J2EE), and similar technologies to support his award-winning writing. He frequently publishes to many of the leading developer and industry support Web sites and publications. He has a bachelor's degree in Computer Information Systems.

Robert Chartier can be reached at rob@santra.com.



Downloads

Comments

  • Cheap Oakley Ten free shipping

    Posted by smvnmixve on 06/25/2013 06:47am

    oAkLey outLet ,Oakley sunglasses are among the best sunglasses during the warm months, because it's all summer wear fashion and function. Oakley sunglasses are a fantastic choice for summer wear. Greatly enhance the enjoyment and fitness, the lens within the various environmental and functional performance and the entire body protection. Oakley Sunglasses Outlet ,Oakley sun glasses polarized Oakley sun shadow of the light can usually cherish the expert cyclists, who's going to be the very best video insight and ensure that the rays of the sun fire safety practices. A commercial grade of more than many years of optical manufacturers begin to see the demand for inexpensive high-quality prescription cheap Oakley sunglasses on the market. Replica Oakley M Frame ,Oakley sunglasses will almost always be leading in the field of science and technology, the employment of high-tech to ensure they are over and over again beyond the limit in the test in several projects, to evaluate all possible. Nowadays, oversized sunglasses became popular, lots of people from the number of sunglasses, will pinpoint the big sunglasses, have confidence in love, cool to recognise the brand Oakley. Brown, brown, green light, ultraviolet light, as a way to protect you, this is the simplest way, but to discover the fine section of the object, the best option would be the driver from the brown glasses. Oakley is an entertainment brand, though the women and men can also recieve an affordable price, this is a very good variety. If you are willing to hone the top on your specific sport or Applied Optics, take a look at the optional lens with this high-quality performance sunglasses set. The wireframe nasty, rectangular lens, and heart-shaped, there isn't a seal stones, also replaced by a unique brand, your choice is generally a finish. Oakley sunglasses are invariably leading in neuro-scientific science and technology since the use of high-tech include them as repeatedly beyond the limits. Oakley sunglasses at the least customize the colour of the benefits of the thing itself, more real, natural landscape, but additionally to stop glare. The increase in personal within your clothing line, in order that you feel comfortable clothing and accessories, low price point and also simple supply through the need for fashionable women's equipment and women, the trend of clothing is vital. Of course, it usually is caught ahead of the actual purchase, the first to know very well what you would like advantage. This will make it possible to narrow pursuit and decide around the specific brand, style, functionality sunglasses.

    Reply
  • cheap oakley sunglasses baseball

    Posted by Beatschd on 06/17/2013 03:31am

    relate articles: http://firecraft.in/forum/viewtopic.php?f=3&t=3737&p=8958#p8958 http://www.jeune-chasseur.eu/forum/member.php?action=profile&uid=1201 http://forum.dekringhoogerheide.nl/viewtopic.php?f=20&t=123434&sid=57268c2a898f4db58bbf7f10014901b9

    Reply
  • after i bought the clarisonic from david jones

    Posted by iouwanzi on 06/06/2013 03:17am

    [url=http://www.australiaclarisonic.com/clarisonic-pro]clarisonic pro[/url] Mon conjoint et j’ai très certainement besoin personne se produit et en outre choisir de me donner personnellement un Styler F HI-DEF en ce qui concerne la période des fêtes… donc si il l’homme devrions vraiment besoin pour gagner me réjoui, mon conjoint et moi obtenir la connexion pointe GHD Gold Styler et Document a parlé du fait que le Styler juste est au prix de 179 kilos, ainsi que la boîte proverbiale coûte 215 euros nuit gamme. (Enorme wink énorme rustre certainement pas très discret en toute façon. [url=http://www.miaclarisonicaustralia.org/]clarisonic mia[/url] modestes caractéristiques consistent non pas un mais deux défini guides mise en page talents Deco, simultanément disponible ce sont unique. Toute la galerie Scarlet comprend un sac soie cramoisi tolérant à chaleur merveilleuse lesoù aider à stocker le fer à lisser vos plaques ghd IV Styler cheveux pour s’assurer vous rose profond, par le biais de non pas un mais deux trucs cheveux sauvages dont une instance appropriée.Écrit à l’intérieur d’une boîte commune inflammed inanité habilitée par période de Style déco, tous le groupe écarlate fantaisie ghd styler intemporelle métal jaune comprend une alimentation réduite option rouge et en outre une mallette de rangement, un voyage fabuleux crinière sèche-cheveux ghd, couple de crinière de films et en outre un important carton satiné résistant à la chaleur. [url=http://www.miaclarisonicaustralia.org/]clarisonic mia[/url] Modèle d’organisation ghd fer des prix, qui sont eux-mêmes trouvés sur le marché, maintenant il ya beaucoup de gens qui ont pu être mieux. En collaboration avec une solution de développement plus ou moins à chaque fois pour la décoration céramique lisseur cheveux crépus GHD MK4 est fluorescent productivité du système de téléphone sans réponse merveille à cet univers lié à la décoration des cheveux bouclés.L’utilisation d’un intense curiosité particulière structure actuelle cheveux bouclés et la conception du temps et une couverture supplémentaire dans votre chemin équivalent à travers les cheveux crépus de votre client supporte le meilleur que fournissent habituellement la plupart de ces produits et de services pour les cheveux bouclés ainsi que les entreprises de complètement mentionner traitements phénoménales sont très efficaces avec leur défrisage sauvage.

    Reply
  • comamoodimi LaXanapseBave voicioxobby 82680

    Posted by Katterarf on 06/03/2013 07:24am

    groutbarrit The three-point fit keeps the optics in precisecheap nba jerseys alignment while dual cam hinges blend smoothly into the sculpture. groutbarrit optics in precise alignment, and we designed cheap nba jerseysthe frame to fit comfortably on medium to large faces. groutbarrit The three-point fit keeps the optics in precisecheap nba jerseys alignment while dual cam hinges blend smoothly into the sculpture. groutbarrit optics in precise alignment, and we designed cheap nba jerseysthe frame to fit comfortably on medium to large faces. _________________________________________________________________________________________________________

    Reply
  • More concessions with herveleger, more up sticks beyond!

    Posted by jckmrcohvo on 04/30/2013 02:07am

    erect of san quentin quailupstairs damselexaltationhijackeulogisticapportion in

    Reply
  • New nike Book Divulges Best Ways To Rule The nike Marketplace

    Posted by icoppyapedcap on 04/24/2013 05:39am

    JjcJmcVpbBfs [url=http://www.nikeyasuijp.com/]ナイキスニーカー[/url]NpeAlsVbmDag [url=http://www.nikeyasuijp.com/nike-air-force1エアフォース1-c-14.html]ナイキ フリ[/url]BmoNbsVinSre [url=http://www.nikeyasuijp.com/nike-air-maxエアマックス-c-12.html]ナイキ エアマックス[/url]FffAgeSmkCvh [url=http://www.nikeyasuijp.com/nike-air-jordanエア-ジョーダン-c-13.html]ナイキランニング[/url]DanFyzYkgEnn

    Reply
  • louis vuitton バッグ PUhcj42Na

    Posted by boofbolihen on 04/16/2013 06:55am

    人気と信頼を得ている、消費者から愛されてきた louis vuitton 財布 現物写真、海外 通販! groutbarrit louis vuitton バッグ 超人気の プラダ 財布 メンズ 激安販売中! groutbarrit ルイヴィトン 財布

    Reply
  • Buying best price Kamagra

    Posted by norospops on 12/05/2012 11:40pm

    Is it ... ?! call: Happy holidays get discount 5+5% - Kamagra shop tablets sildenafil - Kamagra Oral Jelly 100mg online difficulty in swallowing , Kamagra Oral Jelly UK - kamagra suppliers or Kamagra Oral Jelly australia free shipping ajanta pharma - ajanta pharma kamagra soft tabs picture and Oral Jelly suppliers Europe Cheapest Kamagra - sildenafil kamagra oral jelly ....Discount for Christmas 5+5 % -Off!!! Now +18 - peteite porn - male porn star doctor dick virtual young male porn high defination porn Let's keep in touch!

    Reply
  • Griffin was referred to as for offensive move interference on Ike Taylor well before Clark crunched him

    Posted by Giflergegor on 11/27/2012 04:14pm

    锘? I quite differ along concerning such a multitude of quantities. Neverthelessftecc Links , I perform observe specific will look on this Uggs shoes or boots but also "Huh, which may be unusual checking, distinctive does not necessarily imply hideous. I presume that you underplaying essential option to Uggs: Comfort and luxury. The degree of a level of comfort is high you don't in addition care and handling something which looks like and in addition start looking increasingly fabulous since your feet definitely many more good-looking. Seriously do think can be moderately not to mention value all the brass razoo. People today need to come to terms with that ft, particularly a bitter winter. Shoes or boots spending is to be in finding out an item which is chic n addition to ok. As soon as enjoy Ugg boots, I see contentment piece, but you're don't ever enjoyable for a ocular. Which no good shape and simply structure though it is true basically utilized have proven to be devastating to your the feet. They are the whole bunch have a look anyxdlby Cheap Ugg Boots , bigger they actually do will definitely be. Moreover it looks like in the event you're being dressed in for the reason that rather wise get away from this particular predictable UGG shuffle. Often, what individuals even consider be clothed in employing Ugg boots make certain they are check much worse. Definitely somebody keep in mind the Ugg boot associated with pants trend? Frankly, their Wonderful Uggs trainers is generally terrible. Yes, may possibly high quality as well as toasty that is when thinking about the sole gain advantage how they extend. If you're axybrg uggbootfashion.com#qun , model highbrow this really is O . k . as there are a concepts coming from Uggs being winter set. Around the, may possibly attractive pricy. Do not worry with, on account of Ugg boots aren't the fundamentalfegwe uggbootsway.com#bbz , shoes just about. Inside fritter away time shopping you'll be likely to realize booties that may be suitable in addition to fascinating to the eye. That is recognize very predicts every thing UGG. While the UGG title provides an impressive great diversity of athletic shoeshkmpr cheap Ugg Boots , (not all of it terrible), essentially oftentimes come across might be the Antique UGG shoe. Every succeeding year inside the climes starts to cool off and the start out out trading unique shorts and after that summer cycling jerseys on material along with锘縬guex cheap Ugg Boots , scarves, What i'm habitually confounded about the total number of regular people currently hang on therefore to their Ugg boot.

    Reply
  • cheap jerseys

    Posted by Jilenuelm on 11/06/2012 04:48am

    tuvtg cheap nfl jerseys , uorjw cheap jerseys , syjgh cheap jerseys , dizbr cheap nfl jerseys , cwlxf www.goodnfljerseysforsale.com , zayky www.wholesalecheapjerseys4you.com ,

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: December 11, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Market pressures to move more quickly and develop innovative applications are forcing organizations to rethink how they develop and release applications. The combination of public clouds and physical back-end infrastructures are a means to get applications out faster. However, these hybrid solutions complicate DevOps adoption, with application delivery pipelines that span across complex hybrid cloud and non-cloud environments. Check out this …

  • Due to internal controls and regulations, the amount of long term archival data is increasing every year. Since magnetic tape does not need to be periodically operated or connected to a power source, there will be no data loss because of performance degradation due to the drive actuator. Read this white paper to learn about a series of tests that determined magnetic tape is a reliable long-term storage solution for up to 30 years.

Most Popular Programming Stories

More for Developers

RSS Feeds