Archive for the ‘from scratch’ tag
Keep Destination Paths Intact when Forwarding Domains in IIS 6.0
When there is a need to transparently forward one domain to another without making search engines think there’s more then one, the recommended tool is Apache. Apache makes it as simple as a mod_rewrite rule to send your visitors on their way to the correct domain without even noticing it changed. This is not such an easy task with IIS 6.0, however. There are solutions which emulate the functionality of mod_rewrite in IIS, but they all cost money (and those that don’t require lots of custom rules per domain, which can get tricky). After much thought, I realized a simple solution does, in fact, exist!
The process involves some php, but I’m sure it would be fairly easy to do in other languages.
How does this method work?
Oh I’m so glad you asked. The method has two parts necessary to make it work. The first is a PHP file with a 301 redirect within, the second is in the “Custom Error” tab for the site in question. All we have to do is create a PHP file that sends users to a URL with their original full path tacked onto the redirect. After that’s done, all that’s left is to tell IIS to send all 404s to that php file! Simple, right?
The Step-By-Step
- Create a PHP file- I like calling them index.php, but if there’s nothing else in your site folder, it really doesn’t matter. Fill it with the code below, and drop it in your siteroot.
- Open the IIS Management Console (Start > Administrative Tools > Internet Information Services (IIS) Manager). Once you’re in, right click on the site you want to set the redirect up in, and click Properties.
- On this page, we’re looking for the “custom error” tab. Once there, find HTTP error 404. Double click it.
- Set the “Message Type” to “URL”, and enter the path to the php file you created earlier. If you named it “index.php”, you would type “/index.php” here. It should look like the demo to the upper-right when you’re done.
- Click “OK”, then “OK” again. Assuming your site can parse PHP, you should now have a fully functional domain redirect in place, which will pass path information along with it. Huzzah!
The Code
As always, this code is released under no official license, but is free to use as desired for profit or otherwise.
<?php
// Forward-to domain (with trailing slash)
$domain = 'http://blogs.apr.com/dev/';
// Getting the path from the request
// If you have ISAPI_REWRITE installed, this variable exists.
if(isset($_SERVER['HTTP_X_REWRITE_URL']) AND !empty($_SERVER['HTTP_X_REWRITE_URL'])) {
$path = substr($_SERVER['HTTP_X_REWRITE_URL'], 1);
} else {
// If you don't, IIS sends the error and request URL as a $_GET variable.
foreach($_GET as $key => $value) {
$key = explode( "/", $key, 4);
if(isset($key[3])) { $path = $key[3]; break; }
}
if(!isset($path)) { $path = ''; }
}
header("HTTP/1.1 301 Moved Permanently");
header("Location: ".$domain.$path);
?>
Introducing Fling!
Recently here in the APR IT department, there has been a lot of focus on Email management and support. As a result of more then a few storage concerns, our IT management team was looking for an easy solution to the complex problem. Ultimately, the easiest solution is obviously to get the large files out of email!
The easiest solution is never as easy as it looks, however. Pre-existing sites like Yousendit can’t give their services away for absolutely nothing- there’s advertising and other potential hangups that make the process less then streamlined and frequently inconsistent. These are exactly the sorts of problems our agents would view as deal-breakers in a solution like this.
“It has too much overhead? Not simplistic enough? Well we have a web developer, right? Why not have her make one?”- and after 2 weeks in the making, here it is!
(http://fling.apr.com)
Fling is very simple by design- there’s nothing outside of what you see when you open the box (so to speak). The text boxes are nice and big, and tell you in plain English what they require of you. The error messages slide down in a way that’s pleasing to the eye- and then get out of your way so you can correct the problem they report. And in the end, when you send the message- a neat animation sequence happens. Hooray jQuery.animate!
All files uploaded to the site are given a unique name to ensure confidentiality, and they’re deleted two weeks after you upload them to ensure we don’t run out of space!
For the bullet-point fans out there, here’s a breakdown of the basic features of the site.
Summary of
Features
- The Captcha displays words in plain English! Convenient!
- Logged into Savi recently? Your username and password will be entered automatically- and you won’t have to deal with the Captcha.
- You can upload files up to 50MB- and as many as you like!
- You can add another recipient by clicking the “+” next to To. Click again for more!
- We give your files unique names to ensure confidentiality, and store them for 2 weeks.
This utility is currently open to the general public, but will not be advertised in any way shape or form (except here, I guess!)- but not intended to be heavily used. If it starts getting too popular, we’ll lock down access to it from the outside (but that gets so complicated that I’d like to avoid it).
This has not yet been released to the company- but after Marketing gets to test it, it should be ready to go! Hooray!
Captchas! The long and short.
Yesterday and Today, I put the final touches on a Captcha for use on a new service that’s nearly complete (look for another update soon). I learned a lot about Captchas that I hadn’t thought about before. The Wikipedia article (linked above) had a lot of useful information!
My intentions were to produce a simple Captcha for the purposes of creating a themed and at least mostly effective image with an English word (for ease of reading) as the captcha text. Let’s walk through the process of creating a Captcha together, shall we?
Step 1: The Word list.
This is a very important part of this process. The Captcha requires a random string to display in the image. You can get random letters and numbers from an MD5 Encryption algorithm like this one in PHP:
$string = substr(
md5(
microtime() * mktime()
), 0, 5
);
This will output a string such as “6vk3d”, which is effective, but not as easy to read as an actual English word. This is why I opted to use a word list to produce randomly produced readable English words. How would one go about doing that you ask?
- Obtain a list of words in text format.
Where you find your list of words is up to you- I found a list of words on a random website. - Trim undesired words.
Make sure you pull only the text you want to use for the captcha here! Many word lists will include 1-3 letter words that would be very easy to circumvent. This process is much easier to do using a text editor with regex replace capabilities. The best I have ever used is Notepad++, which is only available for windows (which is the sole reason I keep my Windows VM up while here at work). This having been said, you could also do this after importing it to the SQL server just as easily.
(delete * from table where STR_LEN(word) < 4) - Create a database to house the text.
I gave it two columns- an auto-populating identity column called “wordid”, and a varchar(255) column called “word”. This makes for quick retrieval. - Convert the text format into something importable by SQL.
This process is made a lot easier by using a good text editor with macro capability and/or regex replace. - Import the text to the previously created SQL table.
Depending on how you formatted the data above, and what you’re using for a SQL server, this will vary dramatically. I converted my word list into a list of insert statements, and just ran the Query.
Now you have a word list in a form that’s usable!
Step 2: The Base Image.
This part is actually a lot easier then you’d think. For this example, we’re going to start with a pre-made image, and write on top of it. The image can be of any size or shape you like- it’s up to you! I’m trying to make this fit into a site design, so I’m going to go with a PNG with transparent rounded corners: ![]()
Once you have your background image created, it’s time to write some code.
Step 3: The Code.
Since this is all done in PHP with a MSSQL back-end in this site, I’ll be sticking to that standard.
///////////////////////////////////////////////////////////
// After connecting to the SQL server, we select a random word to use as our captcha.
$query = @mssql_query("
SELECT TOP 1
word
FROM captcha_words
ORDER BY NEWID()"
);
// If the query failed, generate a Captcha via the older MD5 method.
if(!$query) { $captcha['word'] = substr(md5(microtime() * mktime()), 0, 5); }
else { $captcha = mssql_fetch_assoc($query); }
// Start a session, and store the captcha string in it.
@session_start();
$_SESSION['captcha'] = $captcha['word'];
///////////////////////////////////////////////////////////
// Now we create the GD Image from our base image above.
$captcha = imagecreatefrompng('./images/captcha-bg.png');
imagesavealpha($captcha, true); // To preserve transparency.
///////////////////////////////////////////////////////////
// And now, the lines! First, we must define a list of colors to randomize:
$linecolors = array(
'102,88,203', // Light Purple
'219,107,58', // Bright Orange
'162,255,97', // Spring Green
'146,171,255', // Sky Blue
'59,255,86', // Bright 'friggin' green
'255,255,255', // White
'255,75,78', // Lightish Red
'255,249,90', // Bright Yellow
'100,96,255', // Washed-out Blue
'255,64,197' // Magenta
);
///////////////////////////////////////////////////////////
// Then, we draw our random lines, using them!
// Top Left Origin
$c = explode(",",$linecolors[rand(0,count($linecolors) - 1)]);
$line = imagecolorallocate($captcha, $c[0], $c[1], $c[2]);
imageline(
$captcha, // Image Resource
0, // X1
rand(imagesy($captcha)*0.1,imagesy($captcha)), // Y1
rand(imagesx($captcha)*0.1,imagesx($captcha)), //X2
imagesy($captcha), //Y2
$line // Color
);
// Bottom Right Origin
$c = explode(",",$linecolors[rand(0,count($linecolors) - 1)]);
$line = imagecolorallocate($captcha, $c[0], $c[1], $c[2]);
imageline(
$captcha, // Image Resource
rand(imagesx($captcha)*0.1,imagesx($captcha)*0.9), // X1
0, // Y1
imagesx($captcha), //X2
rand(imagesy($captcha)*0.1,imagesy($captcha)), //Y2
$line // Color
);
// Bottom Left Origin
$c = explode(",",$linecolors[rand(0,count($linecolors) - 1)]);
$line = imagecolorallocate($captcha, $c[0], $c[1], $c[2]);
imageline(
$captcha, // Image Resource
rand(imagesx($captcha)*0.1,imagesx($captcha)*0.9), // X1
0, // Y1
0, //X2
rand(imagesy($captcha)*0.1,imagesy($captcha)), //Y2
$line // Color
);
// Bottom Right Origin
$c = explode(",",$linecolors[rand(0,count($linecolors) - 1)]);
$line = imagecolorallocate($captcha, $c[0], $c[1], $c[2]);
imageline(
$captcha, // Image Resource
rand(imagesx($captcha)*0.1,imagesx($captcha)*0.9), // X1
imagesy($captcha), // Y1
imagesx($captcha), //X2
rand(imagesy($captcha)*0.1,imagesy($captcha)), //Y2
$line // Color
);
// Top Center origin
$c = explode(",",$linecolors[rand(0,count($linecolors) - 1)]);
$line = imagecolorallocate($captcha, $c[0], $c[1], $c[2]);
imageline(
$captcha, // Image Resource
imagesx($captcha)/2, // X1
0, // Y1
rand(imagesx($captcha)/4,imagesx($captcha)*0.75), //X2
imagesy($captcha), //Y2
$line // Color
);
// Top Center Offset
$c = explode(",",$linecolors[rand(0,count($linecolors) - 1)]);
$line = imagecolorallocate($captcha, $c[0], $c[1], $c[2]);
imageline(
$captcha, // Image Resource
imagesx($captcha) * 0.4, // X1
0, // Y1
rand(imagesx($captcha)/4,imagesx($captcha)*0.75), //X2
imagesy($captcha), //Y2
$line // Color
);
///////////////////////////////////////////////////////////
// Now we write the text!
// Set the color...
$textcolor = imagecolorallocate($captcha, 155, 194, 198);
// Get the width of the text in this font...
$text_width = imagefontwidth(5)*strlen($captcha['word']);
// Find the origin points on the image that center the text.
$x = ceil(imagesx($captcha) / 2) - (ceil($text_width/2));
$y = ceil(imagesy($captcha) / 2) - (imagefontheight(5)/1.8);
// Add the text!
imageString($captcha, 5, $x, $y, $captcha['word'], $textcolor);
///////////////////////////////////////////////////////////
// Finally, we Output our image.
header("Content-type: image/png");
imagepng($captcha);
Once you put all this together, you should have something that looks like this:
This script will re-size itself to the background image you provide it- but it will use all of the available space! Make sure you only feed it things you want scribbled over. :)
I am releasing this script as unofficial GPL- if you want it, please feel free to steal it!


