<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>TechKnack &#187; web</title>
	<atom:link href="http://techknack.net/category/web/feed/" rel="self" type="application/rss+xml" />
	<link>http://techknack.net</link>
	<description>The rantings of a techie</description>
	<lastBuildDate>Thu, 24 Dec 2009 19:53:49 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>PHP Socket Implementation and Webpage Downloader</title>
		<link>http://techknack.net/php-socket-implementation-and-webpage-downloader/</link>
		<comments>http://techknack.net/php-socket-implementation-and-webpage-downloader/#comments</comments>
		<pubDate>Fri, 19 Jun 2009 04:09:12 +0000</pubDate>
		<dc:creator>eternicode</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://techknack.net/?p=294</guid>
		<description><![CDATA[This post reveals two handy PHP constructs I&#8217;ve been using for a while now: a Socket class and a webpage-downloading function.
The files:

Socket.php (highlighted; plaintext)
webpage.php (highlighted; plaintext)

What good is a full-on Socket class and function, you may ask, when you can simply run file_get_contents with allow_url_fopen turned on?  Well, consider that you want to send [...]]]></description>
			<content:encoded><![CDATA[<p>This post reveals two handy PHP constructs I&#8217;ve been using for a while now: a Socket class and a webpage-downloading function.</p>
<p>The files:</p>
<ul>
<li>Socket.php (<a href="/examples/source_highlighted.php?file=phpwebpage/Socket.php">highlighted</a>; <a href="/examples/source_plaintext.php?file=phpwebpage/Socket.php">plaintext</a>)</li>
<li>webpage.php (<a href="/examples/source_highlighted.php?file=phpwebpage/webpage.php">highlighted</a>; <a href="/examples/source_plaintext.php?file=phpwebpage/webpage.php">plaintext</a>)</li>
</ul>
<p>What good is a full-on Socket class and function, you may ask, when you can simply run file_get_contents with allow_url_fopen turned on?  Well, consider that you want to send specific headers to the server, to POST data for example.  Also, there are other uses for a Socket class than webpage downloading; I use this Socket implementation in a PHP-based IRC bot that I run (by the name of ecode on the Freenode network).  You can use the socket to interact with many different servers.</p>
<h3>Socket</h3>
<p>The Socket class essentially encapsulates PHP&#8217;s socket_* functions, making it easy and straightforward to make a TCP connection with a server.  The socket is given a timeout period in microseconds; while I&#8217;m not 100% sure what this means, I do know that it emulates a sort of &#8220;busy wait&#8221; while waiting for content, allowing applications to do processing while waiting for data to come in through the pipe.</p>
<p>To use the socket, include the Socket.php file and create a variable to hold a new Socket.</p>
<pre class="brush: php;">
require_once(&quot;Socket.php&quot;);

$s = new Socket(1000);
</pre>
<p>The Socket will automatically set up the outgoing TCP socket for usage.  The parameter passed to the new socket (1000 in this case) is the microsecond timeout &#8212; this can be left blank if you wish.</p>
<p>Once created, the socket can connect to any service through the connect() function.  The function takes two arguments: host and port.  Both parameters are optional to allow reuse of the connection; if called without parameters, the Socket will establish a new connection using a host and port from the last connection.  The host is the address you would ping to see if the servers are up &#8212; for example, either google.com or 74.125.67.100, the Socket doesn&#8217;t care which as long as it&#8217;s a server it can connect to.  The port is optional: if you specify a port number, that will be used; if no port number is specified, it attempts to extract a port number from the host (for example, if you used google.com:80); failing that, it will use the last port number specified (default of 80).</p>
<p>Once connected, you can use the send() and get() functions to &#8212; you guessed it &#8212; send() and get() data.  The send function takes a string parameter, the message to be sent, sends the message through socket_write, and returns the value returned by socket_write (the number of bytes successfully sent through the socket).  The get function takes an array parameter to specify fetching options: line (boolean) and length (integer).  If line is set to true, then get will fetch one character at a time until a newline (\n) is encountered and return the line along with any trailing carriage returns (\r) and newlines (\n).  If length is specified as greater than 0, get will fetch one character at a time until the specified number of characters have been read.  If neither is specified, the function will read and return the next 512 characters.  Of course, all cases will terminate if the end of data has been reached.</p>
<p>As a quick example, this portion uses the previously created socket to download the HTTP response headers from google.com&#8217;s homepage:</p>
<pre class="brush: php;">
if ($s-&gt;connect(&quot;www.google.com&quot;, 80)) {
    $get;
    $s-&gt;setVerbose(false);
    $s-&gt;send(&quot;GET / HTTP/1.1&quot;);
    $s-&gt;send(&quot;Host: www.google.com&quot;);
    $s-&gt;send(&quot;&quot;);

    $response = &quot;&quot;;
    while (strpos($response, &quot;\r\n\r\n&quot;)===false) {
        $response .= $s-&gt;get(array(&quot;line&quot;=&gt;true));
    }
}
</pre>
<p>The Socket supports logging and verbosity functions.  The setLog function takes a boolean (true/false for logging) and a string (filename to log to).  The setVerbose function takes only a boolean (true/false &#8212; default false &#8212; for printing out extra information to the console).</p>
<p>Finally, when you&#8217;re finished with the connection, you can call the disconnect() function to cleanly sever the connection.</p>
<h3>webpage()</h3>
<p>The webpage function takes three parameters: a url, a headers array, and a &#8220;headers only&#8221; flag.  The url is simple enough; this is the full url that you want to fetch, including both the host name and the file path (and, optionally, a port number after the hostname).  The headers array goes two ways; you can pass in headers to send and you&#8217;ll get back any headers received.  The headers only flag specifies whether or not to fetch the content of the page; if not, it saves the time of downloading that content, and leaves you with only the response headers.</p>
<p>The headers parameter is two-way, as I mentioned.  You can pass in an associative array of header-name => header-value pairs, which will be formatted properly and sent to the server along with the HTTP request.</p>
<pre class="brush: php;">
$h = array(
    &quot;User-Agent&quot; =&gt; &quot;PHP-webscraper/1.0 php/5&quot;,
    &quot;Authorization&quot; =&gt; &quot;Basic &quot;.base64_encode(&quot;username:password&quot;)
);
$page = webpage(&quot;http://twitter.com/statuses/mentions.json&quot;, $h);
</pre>
<p>The above will send the User-Agent, for identification, and Authorization, to login, headers to the Twitter API, fetching any tweets that mention the user name &#8220;username&#8221; (using the password &#8220;password&#8221;).  The response will be in JSON, and will require extra processing, but this will get you the data.  For more information on HTTP headers, check out the <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html">HTTP 1.1 RFC, section 14</a>.</p>
<p>Once the page is received from the server, the headers array you passed in will be overwritten by the server&#8217;s response headers, which you can then examine with external code.  With this method, you can also pass in a simple empty array, which will then be populated with the response headers.</p>
<p>The third parameter to the webpage function is simple enough.  Pass true if you want to receive only the server&#8217;s response headers, cutting off the response once those have been received; a blank string will be returned from the function.  Pass false (or no third parameter) if you wish to receive the entire page, the contents of which will be returned as a string.</p>
<p>With these two files (and, of course, the PHP constructs they define), you can download any webpage you would have access to with your browser, provided you are able to use sockets on your server.  Need to scrape some data from a page?  Download that page and apply some regexes to the content.  HTTP Auth required?  No problem, send an extra header with your creds.  The function could also be modified to POST data to a page, or even download and save images and other media; however, those functions will be left as an exercise for the reader.</p>
<img src="http://techknack.net/?ak_action=api_record_view&id=294&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://techknack.net/php-socket-implementation-and-webpage-downloader/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rounded Corners at the Src</title>
		<link>http://techknack.net/rounded-corners-at-the-src/</link>
		<comments>http://techknack.net/rounded-corners-at-the-src/#comments</comments>
		<pubDate>Sun, 08 Feb 2009 22:57:57 +0000</pubDate>
		<dc:creator>eternicode</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://techknack.net/?p=242</guid>
		<description><![CDATA[CSS-based rounded corner solutions are excellent for website layouts, but it&#8217;s just downright silly to envelope a single img tag with two to four extraneous divs just to get some nice rounded corners on that one image.  PHP (with its GD library) is excellent for this purpose.

Image: Warped by ~eternicode (me).
My PHP script can [...]]]></description>
			<content:encoded><![CDATA[<p>CSS-based rounded corner solutions are excellent for website layouts, but it&#8217;s just downright silly to envelope a single img tag with two to four extraneous divs just to get some nice rounded corners on that one image.  PHP (with its GD library) is excellent for this purpose.</p>
<p><img alt="Example image without rounded corners." src="http://th00.deviantart.com/fs26/300W/i/2008/094/b/a/Warped_by_eternicode.png" style="float:left;" /><img alt="Example image using the PHP rounded corners script." src="http://techknack.net/examples/phprounded/irrcos.php?src=http://th00.deviantart.com/fs26/300W/i/2008/094/b/a/Warped_by_eternicode.png" title="Example image using the PHP rounded corners script." style="float:right" /></p>
<p style="clear:both; font-style:italic;">Image: <a href="http://eternicode.deviantart.com/art/Warped-81839030">Warped</a> by <a href="http://eternicode.deviantart.com/">~eternicode</a> (me).</p>
<p>My PHP script can take any jpg, png, or static gif image (supplied through the &#8220;src&#8221; GET variable) and apply rounded corners to them.  The space left by the corners is transparent, and so blends in with any background you may have applied to your content section.</p>
<p>Using GET variables, you can control various aspects of the output image.  Using &#8220;rad&#8221; or &#8220;radius&#8221;, you can increase and decrease the size of the corners.  The default value for the radius is 20, which I&#8217;ve found to be reasonable for most images.</p>
<p><img alt="Original image." src="http://techknack.net/examples/phprounded/irrcos.php?src=http://th00.deviantart.com/fs23/300W/i/2007/350/4/4/Let_It_Shine_by_eternicode.png" style="float:left;" /><img alt="Image with rounded corners, using radius option." src="http://techknack.net/examples/phprounded/irrcos.php?src=http://th00.deviantart.com/fs23/300W/i/2007/350/4/4/Let_It_Shine_by_eternicode.png&#038;radius=40" style="float:right"/></p>
<p style="clear:both; font-style:italic;">Image: <a href="http://eternicode.deviantart.com/art/Let-It-Shine-71549321">Let It Shine</a> by <a href="http://eternicode.deviantart.com/">~eternicode</a>.</p>
<p>Using &#8220;width&#8221; or &#8220;height&#8221;, you can scale down the image to meet your needs &#8212; the specified width or height will be taken as the maximum width or height, in pixels, and the aspect ratio will be maintained.  If both height and width are given, the smallest result of the two possible outputs will be used.</p>
<p><img alt="Original image." src="http://th04.deviantart.com/fs24/300W/i/2007/350/4/3/Minty_by_eternicode.png" style="float:left;" /><img alt="Image with rounded corners, using width option with value of 300." src="http://techknack.net/examples/phprounded/irrcos.php?src=http://th04.deviantart.com/fs24/300W/i/2007/350/4/3/Minty_by_eternicode.png&#038;width=250" style="float:right"/></p>
<p style="clear:both; font-style:italic;">Image: <a href="http://eternicode.deviantart.com/art/Minty-72269137">Minty</a> by <a href="http://eternicode.deviantart.com/">~eternicode</a>.</p>
<p>There is also a &#8220;squarification&#8221; option, which will reduce either the width or height (whichever is largest) to produce a squared image.  If &#8220;squared&#8221; is specified as true, radius and scaling will take effect as normal, using the new squared aspect ratio in place of the old ratio.</p>
<p><img alt="Original image." src="http://th02.deviantart.com/fs17/300W/i/2007/218/8/3/Convergence_by_eternicode.png" style="float:left;" /><img alt="Image with rounded corners, using squared option." src="http://techknack.net/examples/phprounded/irrcos.php?src=http://th02.deviantart.com/fs17/300W/i/2007/218/8/3/Convergence_by_eternicode.png&#038;squared=true" style="float:right"/></p>
<p style="clear:both; font-style:italic;">Image: <a href="http://eternicode.deviantart.com/art/Convergence-61635157">Convergence</a> by <a href="http://eternicode.deviantart.com/">~eternicode</a>.</p>
<p>The final option, which was kind of an afterthought, is the &#8220;format&#8221; option &#8212; you can choose either &#8220;png&#8221; or &#8220;gif&#8221; as the output format.  I only added this because with png format, in IE6, the method I used would produce magenta-colored corners, rather than transparent colors.  Supplying a gif output fixes this problem for IE6, though the png option is generally preferred.</p>
<p>The source of the script is very well documented, but feel free to ask questions if I missed something.<br />
<a href="http://techknack.net/examples/phprounded/">The example directory.</a><br />
<a href="http://techknack.net/examples/phprounded/irrcos.php?src=Rekindled_by_eternicode.jpg">Active script</a> using a local image, for your experimentation (any other image can be specified through &#8220;src&#8221;).<br />
<a href="http://techknack.net/examples/phprounded/source_highlighted.php">Highlighted script source.</a><br />
<a href="http://techknack.net/examples/phprounded/source_plaintext.php">Plain text script source.</a></p>
<img src="http://techknack.net/?ak_action=api_record_view&id=242&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://techknack.net/rounded-corners-at-the-src/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>I Love Me Some APIs</title>
		<link>http://techknack.net/i-love-me-some-apis/</link>
		<comments>http://techknack.net/i-love-me-some-apis/#comments</comments>
		<pubDate>Sat, 18 Oct 2008 21:54:14 +0000</pubDate>
		<dc:creator>eternicode</dc:creator>
				<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://techknack.net/?p=182</guid>
		<description><![CDATA[I love APIs.  They make using web services so much easier.
I&#8217;ve been developing an IRC bot as a side project, and three of its functions require the use of web services.  It can shorten urls using http://is.gd/, search google, and validate web pages using the W3C&#8217;s HTML and CSS validators.  Fortunately, and [...]]]></description>
			<content:encoded><![CDATA[<p>I love <a href="http://en.wikipedia.org/wiki/API"><acronym title="Application Programming Interfaces">APIs</acronym></a>.  They make using web services so much easier.</p>
<p>I&#8217;ve been developing an IRC bot as a side project, and three of its functions require the use of web services.  It can shorten urls using <a href="http://is.gd/">http://is.gd/</a>, search google, and validate web pages using the W3C&#8217;s <a href="http://validator.w3.org/">HTML</a> and <a href="http://jigsaw.w3.org/css-validator/">CSS</a> validators.  Fortunately, and to my great elation, all four services have APIs available.</p>
<p>Is.gd&#8217;s API is straightforward and easy to use: call the page http://is.gd/api.php?longurl=http://really-long-url-goes-here.com , and is.gd will return the shortened url (or an error message) as the only text.  You&#8217;ll have to parse out the HTTP headers, of course, but that&#8217;s the easy part.</p>
<p>The W3C&#8217;s APIs are just as easy to use.  For HTML validation, fetch the page http://validator.w3.org/check?uri=http://webpage-to-check.com .  This is the same page you would navigate to in a browser, and returns a full-on HTML page with the results.  However, it also puts custom headers in the HTTP response.  To get the results, you have to parse out the values of the X-W3C-Validator-Status, X-W3C-Validator-Errors, and X-W3C-Validator-Warnings headers.  For CSS, the same info comes in the headers of a call to http://jigsaw.w3.org/css-validator/validator?uri=http://webpage-to-check.com .  In the case of the CSS validator, though, the X-W3C-Validator-Warnings header is not returned.</p>
<p>Google&#8217;s search API is a little more involved.  Not only because it uses JSON, but because <a href="http://googlesystem.blogspot.com/2006/11/secret-google-json-api.html">it&#8217;s a secret</a>.  Google&#8217;s <a href="http://code.google.com/apis/ajaxsearch/">AJAX Search</a> package is no secret of course, but the API calls that it makes are hidden away.  Fortunately, Google set up an experimental search site called <a href="http://www.searchmash.com/">SearchMash.com</a>, along with an API of its own.  Simply fetch the page http://www.searchmash.com/results/search+terms+go+here , and searchmash will return a JSON string which can then be parsed out to obtain the google search results, alternate spelling suggestions, estimated number of results, the works.  Even better, you can append &#8220;?n=X&#8221; to the end to limit the search to X results.  Using ?n=1 returns the top result only.</p>
<p>These APIs all save processing power that would otherwise be spent parsing out possibly badly-formed HTML from HTTP responses.</p>
<p><b>Update:</b> The SearchMash API has &#8220;gone the way of the dinosaur.&#8221;  If you&#8217;re looking for something similar to what SM offered, check out Google&#8217;s RESTful search API: <a href="http://code.google.com/apis/ajaxsearch/documentation/#fonje">AJAX API for non-JS environments</a>.  It gives the same results in basically the same format &#8212; I was able to switch over with very few adjustments to my own code.</p>
<p><i>Aside: If you would like to check the bot out, it currently resides on #ecode (and, probably, other channels) on the freenode network.  It goes by the name of &#8220;ecode&#8221;.</i></p>
<img src="http://techknack.net/?ak_action=api_record_view&id=182&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://techknack.net/i-love-me-some-apis/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google Chrome Not Yet For Linux</title>
		<link>http://techknack.net/google-chrome-not-yet-for-linux/</link>
		<comments>http://techknack.net/google-chrome-not-yet-for-linux/#comments</comments>
		<pubDate>Wed, 03 Sep 2008 03:23:37 +0000</pubDate>
		<dc:creator>eternicode</dc:creator>
				<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://techknack.net/?p=174</guid>
		<description><![CDATA[Google recently announced and released their browser, Google Chrome.  And, as should be expected, everyone is talking about it (QuirksMode, Dave Woods, and LifeHacker, amongst others).  Unfortunately, it&#8217;s not yet available for linux.  There&#8217;s promise that the developers are working on a linux port, and there&#8217;s a nice little textbox you can [...]]]></description>
			<content:encoded><![CDATA[<p>Google recently announced and released their browser, <a href="http://google.com/chrome">Google Chrome</a>.  And, as should be expected, <i>everyone</i> is talking about it (<a href="http://www.quirksmode.org/blog/archives/2008/09/google_chrome.html">QuirksMode</a>, <a href="http://www.dave-woods.co.uk/index.php/google-chrome-web-browser/">Dave Woods</a>, and <a href="http://lifehacker.com/5044484/google-chrome-first-look">LifeHacker</a>, amongst <a href="http://digg.com/search?section=all&#038;s=google+chrome">others</a>).  Unfortunately, it&#8217;s <a href="http://www.google.com/chrome/intl/en/linux.html">not yet available for linux</a>.  There&#8217;s promise that the developers are working on a linux port, and there&#8217;s a nice little textbox you can drop your email into for updates on the status.</p>
<p>The features touted on Google&#8217;s promotional website include searchable history / smart address bar, a &#8220;portal&#8221; page as the default &#8220;new tab&#8221; view, individual tab processes, dynamic tabs (ala <a href="http://www.youtube.com/watch?v=lWyT2MfMUKo&#038;fmt=18">Safari 3.1</a>), and &#8220;incognito mode&#8221; (is that the <a href="http://www.redhat.com/">Red Hat</a> mascot I see in the corner?).  Underneath the hood, I&#8217;ve heard it uses a combination of opensource code from Safari&#8217;s Webkit and Mozilla&#8217;s Gecko engines, so it should be interesting from a web development perspective.</p>
<p>All in all, from what I&#8217;ve read others saying, it looks like Google took some opensource browser code, implemented a few nifty FireFox addons as default features, and slapped a shiny Google interface on it.  My test run for Chrome won&#8217;t happen until it&#8217;s available for linux, but if you&#8217;re itching to see it, check out <a href="http://lifehacker.com/5044484/google-chrome-first-look">LifeHacker&#8217;s first look at Chrome</a> (using the Windows release).</p>
<img src="http://techknack.net/?ak_action=api_record_view&id=174&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://techknack.net/google-chrome-not-yet-for-linux/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Stop the OpenDNS Address Bar Hijack</title>
		<link>http://techknack.net/stop-the-opendns-address-bar-hijack/</link>
		<comments>http://techknack.net/stop-the-opendns-address-bar-hijack/#comments</comments>
		<pubDate>Sun, 24 Aug 2008 20:15:45 +0000</pubDate>
		<dc:creator>eternicode</dc:creator>
				<category><![CDATA[firefox]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://techknack.net/?p=171</guid>
		<description><![CDATA[I started using OpenDNS a few weeks ago.  One thing I immediately noticed was that OpenDNS was hijacking my address-bar-initiated google searches.  You know that feature in FireFox that, if the words entered in the address bar don&#8217;t match a website, it takes you to the google search for those keywords?  Seems [...]]]></description>
			<content:encoded><![CDATA[<p>I started using <a href="http://opendns.com">OpenDNS</a> a few weeks ago.  One thing I immediately noticed was that OpenDNS was hijacking my address-bar-initiated google searches.  You know that feature in FireFox that, if the words entered in the address bar don&#8217;t match a website, it takes you to the google search for those keywords?  Seems OpenDNS redirects that particular page of google to their own custom search.  Yuck.  Fortunately, there&#8217;s a way to fix it &#8212; by changing the default url.</p>
<p>I found <a href="http://www.labnol.org/software/browsers/prevent-opendns-google-redirects-firefox-address-bar-ie/2662/">this trick</a> over at <a href="http://labnol.org">labnol.org</a>.  Simply change the about:config key <i>keyword.url</i> to <i>http://www.google.com/search?q=</i> and make sure <i>keyword.enabled</i> is set to <i>true</i>.</p>
<p>The default value of <i>keyword.url</i> is <i>http://www.google.com/search?ie=UTF-8&#038;oe=UTF-8&#038;sourceid=navclient&#038;gfns=1&#038;q=</i>.  Most likely, OpenDNS has this particular string programmed into their system, to catch navbar searches from FireFox (and IE) with default settings.  Change the setting, and you can skirt the redirect <img src='http://techknack.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
<img src="http://techknack.net/?ak_action=api_record_view&id=171&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://techknack.net/stop-the-opendns-address-bar-hijack/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Hosting a Website: The Email</title>
		<link>http://techknack.net/hosting-a-website-the-email/</link>
		<comments>http://techknack.net/hosting-a-website-the-email/#comments</comments>
		<pubDate>Fri, 15 Aug 2008 15:16:08 +0000</pubDate>
		<dc:creator>eternicode</dc:creator>
				<category><![CDATA[thunderbird]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://techknack.net/?p=168</guid>
		<description><![CDATA[Hosting a website on your own server gives you ultimate control over all the details of how that site works.  Running your domain&#8217;s mail on your own server gives you the same amount of control.  Unfortunately, setting up postfix (Ubuntu server edition&#8217;s default mail server) is not nearly as simple as setting up [...]]]></description>
			<content:encoded><![CDATA[<p>Hosting a website on your own server gives you ultimate control over all the details of how that site works.  Running your domain&#8217;s mail on your own server gives you the same amount of control.  Unfortunately, setting up postfix (Ubuntu server edition&#8217;s default mail server) is not nearly as simple as setting up Apache.  Ultimately, I decided to go with <a href="http://www.google.com/a/help/intl/en/index.html">Google Apps for Your Domain</a> to handle my email.</p>
<p>In addition to gmail-style email hosting for your domain (and ThunderBird and Outlook hookup instructions to boot), GAppsFYD, as <a href="http ://lifehacker.com/software/ask-lifehacker/what-does-google-apps-for-your-domain-actually-do-330318.php">LifeHacker</a> calls it, sports Docs, Chat, and Calendar, all private to specified users of your domain.  It also includes Web Pages, giving you space to host static web pages (but you have <a href="http://techknack.net/hosting-a-website-the-server/">your own server</a> for that &#8212; right?); Sites, a collaborative intranet-style hosting space; and a Start Page, a central page from which all domain users can access the activated services.  Best of all, you can activate/deactivate whichever services you choose, allowing only what you need.</p>
<p>Each domain you set up with Google Apps can accomodate up to 100 users under the free version.  If the email service is activated, each user gets their own inbox with up to 6GB of storage.  You can also setup multiple addresses per user (with one shared inbox amongst them), and a &#8220;catchall&#8221; email address, where mail sent to a nonexistent user will end up.  And, of course, you get all the standard <a href="http://lifehacker.com/software/gmail/">advantages of gmail</a>.</p>
<img src="http://techknack.net/?ak_action=api_record_view&id=168&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://techknack.net/hosting-a-website-the-email/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hosting a Website: The Server</title>
		<link>http://techknack.net/hosting-a-website-the-server/</link>
		<comments>http://techknack.net/hosting-a-website-the-server/#comments</comments>
		<pubDate>Tue, 12 Aug 2008 15:04:57 +0000</pubDate>
		<dc:creator>eternicode</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://techknack.net/?p=158</guid>
		<description><![CDATA[A server, in the basic sense, is a computer which runs a program (also called a server or server application) that provides a service to other computers.  This could include an HTTP (or web) server, a DNS name server, a mail server, a VNC server, an SSH server, an FTP server &#8212; and many, [...]]]></description>
			<content:encoded><![CDATA[<p>A <a href='http://en.wikipedia.org/wiki/Server_(computing)'>server</a>, in the basic sense, is a computer which runs a program (also called a server or server application) that provides a service to other computers.  This could include an HTTP (or web) server, a DNS name server, a mail server, a VNC server, an SSH server, an FTP server &#8212; and many, many others.  A server can run any number of server applications, provided it has the resources to run them all simultaneously.  Each program binds and listens to a distinct port on the computer running it, usually the standard port for whatever service it is providing (for example, 22 for SSH, or 80 for HTTP).  When another computer wants to use that service, it sends a message to the server, on the appropriate port, to request service from the program.  The program then sends a response, establishing a connection between the two computers; the service is rendered, and the connection is severed.</p>
<p>To host your own website, you need a computer with an HTTP server, and a decent (not dialup) always-on internet connection.  A spare computer (used as a &#8220;dedicated server&#8221;) with, say, a 333MHz processor and 256MB memory is plenty sufficient to serve a low-traffic website, especially if you put an <a href="http://www.ubuntu.com/products/whatisubuntu/serveredition">operating system</a> with <a href="https://help.ubuntu.com/community/Installation/SystemRequirements">low resource requirements</a> on it.  If you have a &#8220;modern&#8221; home computer (usually 1GHz+ and 512MB+), you could even install the web server on that machine, provided you always leave the machine running.  Hard drive requirements are very small as well; if you are using a dedicated server, you could use a 10GB hard drive and have more than enough space for your website.</p>
<p>Once you have a machine designated as your server, you need to set it up.  If you have a dedicated server, and you plan on using the existing operating system, make sure that no unnecessary programs start running at startup.  Once the operating system is prepped (or installed, as the case may be; your home computer can most likely be run normally), you need to install the web server.</p>
<p>In terms of web servers, <a href="http://www.apache.org/">Apache</a> is the <a href="http://news.netcraft.com/archives/web_server_survey.html">most widely used</a>.  And it&#8217;s <a href="http://www.apache.org/foundation/licence-FAQ.html#WhatDoesItMEAN">free</a>.  And it&#8217;s bundled with <a href="http://www.ubuntu.com/products/whatisubuntu/serveredition">Ubuntu server edition</a>, should you choose to add it during installation.  These reasons and more make Apache a good web server to start with (and, ultimately, stick with).  Once you have Apache installed, it needs to be setup to know what files to serve as what website.  Check out the <a href="http://httpd.apache.org/docs/1.3/vhosts/">Apache Virtual Host documentation</a> for details on setting up individual websites.</p>
<img src="http://techknack.net/?ak_action=api_record_view&id=158&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://techknack.net/hosting-a-website-the-server/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Hosting a Website: The Domain and DNS</title>
		<link>http://techknack.net/hosting-a-website-the-domain-and-dns/</link>
		<comments>http://techknack.net/hosting-a-website-the-domain-and-dns/#comments</comments>
		<pubDate>Sat, 09 Aug 2008 15:09:58 +0000</pubDate>
		<dc:creator>eternicode</dc:creator>
				<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://techknack.net/?p=156</guid>
		<description><![CDATA[The cost of a domain name these days is about $10 per year, depending on which registrar you work with.  I&#8217;m currently using GoDaddy.com, where I can get .com, .net, and .org domains for $10/year (less, if I find a valid coupon code online   ).  I&#8217;ve heard that there are better [...]]]></description>
			<content:encoded><![CDATA[<p>The cost of a domain name these days is about $10 per year, depending on which registrar you work with.  I&#8217;m currently using GoDaddy.com, where I can get .com, .net, and .org domains for $10/year (less, if I find a valid coupon code online <img src='http://techknack.net/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  ).  I&#8217;ve heard that there are better registrars out there, but I haven&#8217;t been able to find them.  The ones I&#8217;ve found either don&#8217;t tell you how much they charge per domain until you&#8217;re checking out, or charge too much, or, according to reviews, have horrible customer service.  However, my failure to find these good registrars surely doesn&#8217;t preempt their existence.  Please, feel free to share whatever domain registrar(s) you use, what you pay per domain per year, and all the good details, in the comments <img src='http://techknack.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
<p>Once you have your domain bought, you need an IP to point it at.  For this series, I&#8217;m going to assume you&#8217;re using your home IP, assigned by your ISP.  Usually, an ISP will assign its users dynamic IPs, meaning that whenever you connect to your ISP, you get a different IP.  Some ISPs offer packages with static IPs, giving you an IP that will always point at your computer.  While a static IP would make hosting easier, hosting with a dynamic IP is completely doable.</p>
<p>After getting a domain name and an IP, you need to link them together.  This is done through DNS, the <a href='http://en.wikipedia.org/wiki/Domain_Name_System'>Domain Name System</a>.  I gave a basic explanation of DNS in my last article, &#8220;<a href='http://techknack.net/is-your-dns-cache-poisoned/'>Is your DNS cache poisoned?</a>&#8220;.  To tell the system to point your domain at your IP, you need to specify your domain&#8217;s nameservers through your registrar, and then set up those nameservers with the appropriate information.  I use <a href='http://freedns.afraid.org/'>FreeDNS</a>&#8217;s nameservers for my domains.  FreeDNS requires registration to use their service, but there is no mandatory fee.  They do have a <a href='http://freedns.afraid.org/premium/'>premium membership option</a>, but the free membership provides all of the basics for managing a domain.</p>
<p>If you have a dynamic IP address, you&#8217;ll need some way to alert your Dynamic DNS provider (FreeDNS being an example) when your IP has changed.  FreeDNS has a <a href='http://freedns.afraid.org/scripts/freedns.clients.php'>list of programs</a> that are capable of updating that service, and other Dynamic DNS services often provide their own clients.  I run a linux server, and I&#8217;ve settled on using inadyn (<a href='http://linux.die.net/man/8/inadyn'>manual page</a>, <a href='http://www.brothersoft.com/inadyn-download-43392.html'>download</a>).  Inadyn is a command-line program available for Windows and Linux (and, presumably, is capable of running on Mac); it takes a number of command line options and, once called, can run in the background as a service, updating the appropriate Dynamic DNS service when a different IP is detected.</p>
<p>Next article, I&#8217;ll talk about setting up a server.  In the meantime, what domain registrar and DNS solutions do you use, if any?</p>
<img src="http://techknack.net/?ak_action=api_record_view&id=156&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://techknack.net/hosting-a-website-the-domain-and-dns/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Moving from Blogger to Wordpress</title>
		<link>http://techknack.net/moving-from-blogger-to-wordpress/</link>
		<comments>http://techknack.net/moving-from-blogger-to-wordpress/#comments</comments>
		<pubDate>Tue, 22 Jul 2008 15:37:35 +0000</pubDate>
		<dc:creator>eternicode</dc:creator>
				<category><![CDATA[blogs]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://techknack.net/?p=153</guid>
		<description><![CDATA[Recently, I&#8217;ve reached the point, like probably many bloggers have, where I&#8217;ve outgrown Blogger.
Don&#8217;t get me wrong, Blogger was great to use as I began my blogging journey.  A freely-hosted blog is probably the best way to test the waters, so you don&#8217;t spend $10 on a domain and who knows how much on [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, I&#8217;ve reached the point, like probably many bloggers have, where I&#8217;ve outgrown Blogger.</p>
<p>Don&#8217;t get me wrong, Blogger was great to use as I began my blogging journey.  A freely-hosted blog is probably the best way to test the waters, so you don&#8217;t spend $10 on a domain and who knows how much on hosting for a blog that&#8217;ll be dead in a few months.  It&#8217;s just that hacking functionality into Blogger, when that functionality can easily be gained through a WordPress plugin, gets old after a while.  And besides, I had to do something with my new server <img src='http://techknack.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
<p>The main problem with moving is that free services like Blogger give you very, very little control over the server.  The best way to maintain whatever incoming links and &#8220;Google juice&#8221; you&#8217;ve built up, assuming you&#8217;re moving to a new domain, is to set up a 301 Permanent Redirect to the new blog.  And, well, Blogger doesn&#8217;t like that idea <img src='http://techknack.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
<p>The next best thing, though nowhere near as desirable, is to setup various client-side redirects, and hope that at least one of them works.  This, of course, pretty much leaves behind whatever link juice you may have, but it&#8217;s better than users coming to a seemingly dead blog without some way to find the regularly-updated version.</p>
<p>Here&#8217;s what I did: throughout the course of using blogspot, I&#8217;ve been using &#8220;post pages&#8221;, which is essentially a permalink.  You can setup self-hosted WordPress to use the .htaccess file to redirect users from the old URL version (with year, month, and trailing .html) to the new version used by WordPress.  For details, see <a href='http://www.blogbloke.com/migrating-redirecting-blogger-wordpress-htaccess-apache-best-method/'>BlogBloke.com&#8217;s article</a> (currently under construction, see the <a href='http://64.233.167.104/search?q=cache:www.blogbloke.com/migrating-redirecting-blogger-wordpress-htaccess-apache-best-method/'>google cached version</a>).  To test if your implementation works (after importing all your Blogger posts), pull up an article on the blogspot blog, replace the blog.blogspot.com in the url with your WordPress blog&#8217;s base address, and hit enter. You should be redirected to that same article on your WP blog.</p>
<p>As for performing the actual redirect, there are several ways to go, including javascript, meta redirects, and plain links within your pages.  I set up a simple javascript redirect that goes in the head of the blog template.  This takes the current URL, replaces the blogspot part with the new blog&#8217;s URL, and sends the user there.  Instant client-side redirect, provided the user has javascript enabled.</p>
<pre class="brush: jscript;">
&lt;script type='text/javascript'&gt;
// &lt; ![CDATA[

document.location.href=document.location.href.replace(/oldblog.blogspot.com/, &quot;newblog.com&quot;);

// ]]&gt;
&lt;/script&gt;
</pre>
<p>I put this directly under the title tags, so it would be executed as soon as possible.  Then, it occurred to me to move the Google Analytics tracker code above that, so that I would still receive stats from that site.<br />
Note: The CDATA tags are from the fact that New Blogger templates use XML.  Occasionally, I would get issues with using my javascript without CDATA tags surrounding the code.  These may or may not be necessary.
</p>
<p>In addition to the javascript redirect, I put a Text widget above the main blog content, alerting users to the new location, in case they&#8217;ve disabled javascript.<br />
<a href='http://techknack.net/wp-content/uploads/screenshot1.png'><img src="http://techknack.net/wp-content/uploads/screenshot1.png" alt="" title="screenshot1" width="500" height="117" class="aligncenter size-full wp-image-154" /></a><br />
I wouldn&#8217;t recommend using a <a href='http://www.libertyinteractivemarketing.com/blog/successfully-forwarding-blogger-to-wordpress/'>meta tag redirect</a>, unless you can somehow incorporate the current article&#8217;s URL into it.  You don&#8217;t want to auto-redirect the user from the article they want to read to the homepage of your new blog, even if you give them a 6-second warning.  It&#8217;s just downright inconsiderate.  If you can&#8217;t &#8220;seamlessly&#8221; redirect them, tell them how they can get to the new place, and leave it at that.</p>
<p>Once you&#8217;ve got the web-based redirects working, you need to take care of your RSS readers.  If you used Blogger (which, since you&#8217;re reading this, I assume you have), check out their RSS redirect service.  If you&#8217;re using FeedBurner, it&#8217;s almost as simple.  FeedBurner has acquired a FeedBurner WordPress plugin called <a href='http://www.google.com/support/feedburner/bin/answer.py?answer=78483&#038;topic=13252'>FeedSmith</a>.  Simply install the plugin, re-burn your FeedBurner feed (&#8221;Edit feed details&#8221; from your feed&#8217;s dashboard, and enter your WordPress feed, which should be at http://blog.com/feed/), and enter your FeedBurner URL in the appropriate field in WordPress&#8217;s Settings &rarr; FeedBurner page.  Your existing readers shouldn&#8217;t notice any change (they may receive duplicate entries of your recent articles), and any future subscribers will be redirected to your FeedBurner feed.</p>
<img src="http://techknack.net/?ak_action=api_record_view&id=153&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://techknack.net/moving-from-blogger-to-wordpress/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Is your DNS cache poisoned?</title>
		<link>http://techknack.net/is-your-dns-cache-poisoned/</link>
		<comments>http://techknack.net/is-your-dns-cache-poisoned/#comments</comments>
		<pubDate>Sat, 19 Jul 2008 11:54:41 +0000</pubDate>
		<dc:creator>eternicode</dc:creator>
				<category><![CDATA[security]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://blog.techknack.net/?p=152</guid>
		<description><![CDATA[Say what?
First, some background on DNS; feel free to skip this paragraph if you know what it is   .  &#8220;Domain Name System&#8221; is a distributed system for translating web addresses (Google.com) to IP addresses (64.233.187.99).  You type &#8220;Google.com&#8221; into your browser, the browser (through the computer) sends that address to the [...]]]></description>
			<content:encoded><![CDATA[<p><i>Say what?</i></p>
<p>First, some background on DNS; feel free to skip this paragraph if you know what it is <img src='http://techknack.net/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  .  &#8220;<a href='http://en.wikipedia.org/wiki/Domain_Name_System'>Domain Name System</a>&#8221; is a distributed system for translating web addresses (Google.com) to IP addresses (64.233.187.99).  You type &#8220;Google.com&#8221; into your browser, the browser (through the computer) sends that address to the DNS, the DNS looks up the address and retrieves the corresponding IP, the DNS sends that IP to your computer, and, finally, the browser can use that IP to contact the appropriate website&#8217;s server to fetch the content.  Each domain has at least one &#8220;authoritative&#8221; DNS server, which holds the master information for that domain.  Other servers in the DNS system contact the authoritative server, and cache the IP address in their own tables.  This way, if an authoritative server goes down, less-reliable-yet-still-useful results can be obtained from secondary servers.  (This is the way I understand it, please correct me if I&#8217;m wrong).  OK, moving on.</p>
<p>I was doing some domain name management on <a href='http://freedns.afraid.org'>FreeDNS</a> a few days ago, when, seemingly out of nowhere, I was getting &#8220;error loading page&#8221; for that site.  I tried a few other sites to make sure my internet wasn&#8217;t down; I could access Google, but not eBay, with the same situation for a number of other sites.  Very strange.  Having recently been educating myself about DNS (that happens when you start looking into the details of dynamic DNS <img src='http://techknack.net/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ), I immediately assumed that my ISP&#8217;s (AT&#038;T&#8217;s) DNS servers were on the fritz.  Which, to my knowledge, has never happened before.</p>
<p>So, naturally, I went straight to google with a query: &#8220;att dns servers broke&#8221;.  Not the best grammar in the world, but it worked <img src='http://techknack.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .  Nothing especially recent popped up under Web results, so I checked out the Blog results, and found this: <a href='http://isitmeoriseveryoneelsestupid.com/2008/07/15/your-dns-is-broken-and-it-cannot-be-fixed-oops/'>Your DNS Server is Broken, and Can&#8217;t Be Fixed</a>.  Naturally, that site was one of the sites that my working DNS server(s) couldn&#8217;t find, so I had to call up a google cached version.  &#8216;Twas a scary article.</p>
<p>Basically, there is an inherent flaw in the very <i>design</i> of the DNS system.  This flaw allows malicious entities with knowledge of this flaw to poison the DNS cache.  This means that they can update the system&#8217;s cache to point a domain name at <i>their</i> IP address, which, in theory, could be a perfect copy of the original website.  This would allow them to redirect major bank websites, for example, to their perfect copies designed to steal your account information.  And you, of course, would never know the difference, because the URL bar still says &#8220;mybank.com&#8221;.</p>
<p>Fortunately, the discoverer of the flaw, Dan Kaminsky of <a href='http://Doxpara.com'>Doxpara.com</a>, was a security researcher.  And, fortunately, he kept this monumental news quiet and got together with some other security guys and programmers, as well as some of the big names in technology, to work up a workaround.  The flaw isn&#8217;t fixable, but we can make it harder to exploit.</p>
<p>After reading this article, which didn&#8217;t exactly answer my first question (&#8221;Are AT&#038;T&#8217;s DNS servers down, broken, or worse?&#8221;), I headed to the news search.  The most recent article there was on Forbes.com: <a href='http://www.forbes.com/technology/2008/07/17/dns-security-flaw-tech-security-cx_ag_0717security.html'>Hackable Broadband Left Unpatched</a>.  This article, besides describing the flaw, detailed some major ISPs who hadn&#8217;t updated their servers as of the day the article was published.  To my disdain, AT&#038;T was among them.  This may explain the DNS hiccups, though, if implementing this workaround to the main servers is at all a major undertaking.</p>
<p>While sooner is better, the major ISPs (or, really, anyone who runs a DNS server) have until August 6th to update their systems.  That&#8217;s when Kaminsky will be discussing all the gritty details of the exploit in his talk at the Black Hat Briefings.  In other words?  DNS D-Day for anyone who hasn&#8217;t patched up yet.</p>
<img src="http://techknack.net/?ak_action=api_record_view&id=152&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://techknack.net/is-your-dns-cache-poisoned/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
