Posts Tagged ‘How To’

February 25th, 2009

How not to get help on an Open Source Project

So over the past couple of weeks I have been helping a user get up and running on a project I have developed called Managed Fusion Url Rewriter and Reverse Proxy.  Now I understand that my project isn’t well documented, and I really need to work on that.  So, until I get the time to better document the project, I willingly spend my time helping people through their issues.  99.9% of the time everything works out, and everybody walks away happy.  However there is this 0.1% of the time that the conversation ends like this:

Fuck all this shit crazy.  All I wanted was a revers proxy.  I can set this shit up in 20 minutes with ISA.  I don’t know why this is sooooooooooooooooooo hard.

The syntax of RewriteRule is soooooooo confusing.  WTF does ^/(.*)$ mean?
any why is there a $1 on the end of my other “thing”

RewriteRule ^/(.*)$        http://192.168.0.35/$1 [P]

What does port :8888 have to do with anything.

This is just getting to hard to make work.  I should need to have advanved knowledge of http to make stupid proxy work.
I want to proxy everything.

I don’t think the problem is with the traffic between the two web servers, the problem seems to only apply to the number of /’s in the query string and their placement.

My guess is if I could figure out how to make more RewriteRules and define all the / cases the shit would just go.  Somehow when there are a few slashes in the query string your guy drops the ball.  Maybe because my RewriteRule is balls or because it’s broken.  I wouldn’t know either way.

All I want it to do it fucking work.

Ugh

I mean how do you respond to this?  The guy basically has started freaking out on me, because he doesn’t understand the basic premis of what my open source project is trying to accomplish and is unwilling to spend the time to learn about the mod_rewrite syntax. Plus none of what he is saying is true, I eat my own dog food on this project.  So I imidiatly know about simple problems such as query strings are not working.

Basically the whole problem came down to the fact that this guy was in a crunch, didn’t understand the basics of the internet, and thought it would be easier to use a new technology instead of one that is proven for him such as ISA server.  None of this is my problem so it is inappropriate to swear at a person just trying to help you out.  I understood he was frustrated with a technology he has never used before, but I wasn’t going to continue a conversation with a guy who was proven to be unstable and irrational.  So I just replied with:

Ok I am done you are on your own.

There really wasn’t any point to this post besides airing my disgust at this type of user.  Also to shed light on the fact that even though I am developing this software on my free time, giving it away for free, and supporting it for free, that there are many people out there that don’t understand this and demand the same level of support as if they just paid you a months worth of their salery for support.

If you ever find yourself heading down this path, be aware that people who create open source software are dedicating their free time to help you out.  So be grateful for their help, because they could just as easily blow you off and spend time with their family.

Tags: , ,

Posted in How To, Rant | kick it on DotNetKicks.com | Bookmark | View blog reactions | 6 Comments »

January 19th, 2009

Creating a Wireless Access Point using DD-WRT – Refresh

I found a setup that I like even better than my previous one.  I have highlighted the main differences, in red, below.

To set it up as repeater do the following:

  • Do a 30 second reset

Under wireless->basic settings:

  • Wireless mode: AP
  • Wireless Network Name (SSID): Your prefer SSID
  • Wireless Channel: Your prefer channel ( Use channel with less interference from other access point)
  • Save Settings

Under Wireless > Wireless Security

  • Set your wireless authentication

Under Setup->Basic Setup:

  • Under WAN Connection Type:
    • Connection Type : Disabled
    • STP : Disable
  • Under Router IP:
    • Local IP address :Set your IP your address to a same subnet of your main router (if your main router IP is 192.168.1.1, set it to same subnet like 192.168.1.2)
    • Subnet Mask : same as your main router subnet
    • Gateaway : Your main router IP
    • DNS : Your main router IP
  • Under Network address Server Setting (DHCP)

    • DHCP Type : DHCP Forwarder
    • DHCP Server : Your main router IP
    • Time settings : disable
  • Save Settings

Under Security Tab

  • Un-check all items in the “Block WAN Request” section
  • Then disable the SPI firewall
  • Save Settings

Under Administration Tab

  • Enter all other necessary information, remember to change your password
  • Click the Save button
  • Then click Reboot button

Tags: , , , , ,

Posted in How To | kick it on DotNetKicks.com | Bookmark | View blog reactions | 4 Comments »

December 28th, 2008

Creating a Wireless Access Point using DD-WRT

This post is a reminder to myself in case I ever need to troubleshoot this setup process again, but I thought I would post it just in case it is useful to somebody else.

A couple days ago I ordered myself a Linksys WRT150N to replace my aging Linksys WRT54G wireless router. I wanted to update my wireless capabilities to the latest 802.11 Draft N standard, so that I could take advantage of the speed boost when working wirelessly.  However I had one problem the WRT150N will not run the Tomato Firmware.  And I didn’t want to switch to DD-WRT for a couple of reasons, the most important being that I really like the Tomato user experience and it would be a pain to setup the router with all my custom configurations again.  So I decided to try and have the best of both worlds and keep my WRT54G (old router running Tomato Firmware) as my gateway and turn the WRT150N (new router running DD-WRT) in to an access point on my network.

Before I started I made sure to disable the Wireless Radio on my WRT54G in preparation for the Wireless Access Point (WAP).  This is important so that the wireless signals and SID (Wireless Name) doesn’t conflict when you are done.

Step 1 – Upgrade to DD-WRT

The first step I had to do was get rid of the crappy Linksys Firmware and upgrade the WRT150N to the latest stable version of DD-WRT.  DD-WRT may not have the user experience that Tomato has, but it is still miles ahead of the Linksys Firmware.  So in the case where I cannot use Tomato, DD-WRT serves as a great alternative to me. The process of installing the DD-WRT firmware is pretty straight forward.  Download the mini generic .bin file and browse to the firmware upgrade page for the router and install.  You can find more indepth information at this blog post.

Step 2 – Turn DHCP Off

I turned off the DHCP on the router for my WAP.

If you do not turn off DHCP, when you plug your router into the network (after configuration), your WAP may provide IP addresses to clients on the wired network, and this may be inappropriate. Tracking down problems caused by multiple DHCP servers can be time-consuming and difficult.

Step 3 – Add A Start Up Script

This part took me the better part of a day to perfect, because like many UNIX commands it is a convoluted syntax of piped commands flowing over each other in order to massage the data for the desired results.

ln -s /sbin/rc /tmp/udhcpc
udhcpc -i br0 -p /var/run/udhcpc.pid -s /tmp/udhcpc -H `nvram get router_name`
if test `ifconfig br0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'` != `nvram get lan_ipaddr`; then
    nvram set lan_ipaddr=`ifconfig br0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'`;
    nvram commit;
fi

This startup script runs whenever the router is booted or rebooted, and the purpose of it is to request an IP Address from the DHCP server and set the Local IP Address (or LAN IP Address). There is no option available through the interface for this type of request because normally the LAN IP Address is the routers static local address (most cases 192.168.1.1) that acts as the constant in your network. The 192.168.1.1 acts as the main gateway to the internet, and if that wasn’t static, the LAN traffic wouldn’t be able to get out to the internet. This behavior is, however, undesirable for a Wireless Access Point, the WAP needs to pass through the wireless connections to the real router and needs to act as a client of the LAN instead of the master of the LAN.

Step 4 – Connect LAN to LAN

To complete the link between the two routers, I connected a LAN port on my main router, to a LAN port on the WRT150N (to be used as my WAP).

You may need a crossover cable to do this, although many modern routers have an automatic polarity sensing. To test this, connect a standard Ethernet cable between the two routers. If the LAN light comes on, the router has automatically switched the polarity and a crossover cable is not required.

Step 5 – Power On & Test

The last step required is to power on (or reboot) the router acting as the WAP.  After I powered on the WRT150N I was able to connect to my network through my new WAP.

So that is the process, it took a lot of hunting around on the internet.  But I think I finally got my setup to a state that I can deal with, until Tomato starts supporting the Linksys WRT 150N.

Tags: , , , , ,

Posted in How To, Personal | kick it on DotNetKicks.com | Bookmark | View blog reactions | 7 Comments »

December 9th, 2008

Creating an extension module for .NET URL Rewriter and Reverse Proxy

Wow that is a long title. Recently I have been looking for quick posts that I can put out each day to keep my blog relevant and also so I don’t feel like I am slacking off too much. Today I want to post about a little known feature in my .NET URL Rewriter and Reverse Proxy (aka. Managed Fusion URL Rewriter) that I have developed in my spare time, mostly out of necessity for this blog and other projects I have worked on.  Here is a quick run through of what it does.

Managed Fusion URL Rewriter is a powerful URL manipulation engine based on the Apache mod_rewrite extension. It is designed, from the ground up to bring all the features of Apache mod_rewrite to IIS 6.0 and IIS 7.0. Managed Fusion Url Rewriter works with ASP.NET on Microsoft’s Internet Information Server (IIS) 6.0 and Mono XPS Server and is fully supported, for all languages, in IIS 7.0, including ASP.NET and PHP. Managed Fusion Url Rewriter gives you the freedom to go beyond the standard URL schemes and develop your own scheme.

But one feature that I added that is not part of the official Apache mod_rewrite documentation is the ability to add custom modules to extend the use of the URL rewriter in non-traditional ways.  One great example of this was born out of wanting to clean up the SEO mess I created in the early days of this blog.  I had to support the following different types of URL patterns:

  1. http://www.coderjournal.com/?p=23
  2. http://www.coderjournal.com/2008/03/14/some-post.html
  3. http://www.coderjournal.com/2008/03/14/some-post

to transform them in to the URL pattern that I finally settled on today:

  • http://www.coderjournal.com/2008/03/some-post

In the above list #2 and #3 were pretty easy to transform using the following rules:

RewriteRule ^(/[0-9]{4}/.*).html$    $1/ [NC,R=301]
RewriteRule ^(/[0-9]{4}/[0-9]{1,2}/)[0-9]{1,2}/(.*)$    $1$2 [R=301]

Because they contained all of the elements that make up my current URL.  As you can imagine problems arose when I had to support links that used #1’s syntax.  It contains zero elements that I can use to create my current URL.  Being a programmer who beleives that each part of a system should handle gracefully the domain it was designed to support, in this case a URL rewriter should be able to handle any senario that has to do with URL rewriting.  I added in support that allowed developers to naturally extend the URL rewriter to accomplish any type of URL rewriting task they could think of.

Setting Up the URL Rewriter Rules

In my case I needed to handle the following SQL query everytime I saw a URL that matched #1.

select concat('http://www.coderjournal.com/',year(post_date),'/',month(post_date),'/',post_name,'/') from wp_posts where ID = $1;

What this query does is query the WordPress database table that contains all the posts by the post ID and have it return the actual absolute path to the post, that should be displayed in the URL.  To do this I created a new directive for the mod_rewrite syntax called RewriteModule.  I also had to extend the RewriteRule and RewriteCond directives to support these new module extensions.  The RewriteModule, RewriteRule, and RewriteCond are defined by the following syntax:

RewriteModule <Reference Name> <Namespace>,<Assembly>
RewriteRule[([<Left Module>],[<Right Module>])] <Pattern> <Substitution>
RewriteCond[([<Left Module>],[<Right Module>])] <Test String> <Condition Pattern>

The parts in light blue parts above are optional to creating the rule.  In my case for this blog the rewriter directives looked like the following:

RewriteModule PostQueryString CoderJournal.Rewriter.Rules.PostQueryStringRuleAction, CoderJournal.Rewriter.Rules
RewriteRule(,PostQueryString)   ^/\?p=([0-9]+)$    "select guid from wp_posts where ID = $1;" [R=301]

I have highlighted in red the important parts of the syntax that indicate the custom module processor that should be used on the RewriteRule directive and how it relates back to the class defined in the RewriteModule

Creating the Module

I have to warn you that I am not going to demonstrate and show all the properties and methods on the interface that are important for creating a custom module, but I am going to show you the actual meat of the module that is involved in the lookup of the URL from the database.

public Uri Execute(int logLevel, string logCategory, HttpContext context,
                   Pattern pattern, Uri url, string[] conditionValues,
                   IDictionary<string, string> flags)
{
	string inputUrl = url.GetComponents(UriComponents.PathAndQuery, UriFormat.UriEscaped);
	string sqlCommand = pattern.Replace(inputUrl, Text, conditionValues);
	string substituedUrl = String.Empty;

	using (MySqlConnection connection = new MySqlConnection(Properties.Settings.Default.DatabaseConnection)) {
		using (MySqlCommand command = connection.CreateCommand()) {
			command.CommandText = sqlCommand;
			command.CommandType = CommandType.Text;

			try {
				connection.Open();
				substituedUrl = command.ExecuteScalar() as string;
			} finally {
				connection.Close();
			}
		}
	}

	return new Uri(url, substituedUrl);
}

It may not be clear right away what is going on, but on line 6, I am replacing the defined value in the regular expression (^/\?p=([0-9]+)$) with the SQL query (from above) to produce a query that will be run against the database. So if the following URL came in to my server:

It would produce a SQL query that looked like this:

select concat('http://www.coderjournal.com/',year(post_date),'/',month(post_date),'/',post_name,'/') from wp_posts where ID = 372;

Notice that the ID, 372, shows up in both the URL and the query, that is because this is the part I am most interested in, in the URL, because it is the only part of the URL that I need to query the database to find the actual path of the post.

Now that we have the query we can execute it on the database, using lines 9 through 21, and create the resulting URL on line 23. The resulting URL is then passed back through the URL rewriter, and processed using the flags defined. In my case [R=301], actually indicates that I want to do a 301 Permanent Redirect on the URL, which tells the browser and search engines, a like, that they need to update their URL for this page.

You can test out the above conditions by using the following URL’s that all redirect back to this page:

  1. http://www.coderjournal.com/?p=372
  2. http://www.coderjournal.com/2008/12/9/creating-extension-module-net-url-rewriter-reverse-proxy.html
  3. http://www.coderjournal.com/2008/12/9/creating-extension-module-net-url-rewriter-reverse-proxy/

The code as always is available on my SVN server at Google Code.

I hope this comes in handy to some of you developers that have to support legacy URL’s in your own product or a project that you are working on. As always if you have any questions or need anything clarified please feel free to contact me or leave a comment below.

Tags: , , , , ,

Posted in C#, How To, SEO, SQL | kick it on DotNetKicks.com | Bookmark | View blog reactions | 3 Comments »