<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><!-- generator="wordpress/2.3.3" --><rss 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/" version="2.0">

<channel>
	<title>Peering Behind the Browser</title>
	<link>http://iablog.sybase.com/efarrar</link>
	<description>Exploring the World of Data Behind the Tags</description>
	<pubDate>Mon, 27 Oct 2008 17:31:21 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.3.3</generator>
	<language>en</language>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/PeeringBehindTheBrowser" type="application/rss+xml" /><item>
		<title>Musings on AjaxWorld 2008</title>
		<link>http://iablog.sybase.com/efarrar/2008/10/musings-on-ajaxworld-2008/</link>
		<comments>http://iablog.sybase.com/efarrar/2008/10/musings-on-ajaxworld-2008/#comments</comments>
		<pubDate>Mon, 27 Oct 2008 15:38:39 +0000</pubDate>
		<dc:creator>Eric Farrar</dc:creator>
		
		<category><![CDATA[Conferences]]></category>

		<guid isPermaLink="false">http://iablog.sybase.com/efarrar/2008/10/musings-on-ajaxworld-2008/</guid>
		<description><![CDATA[I am back from a week in sunny San Jose at the AjaxWorld 2008 conference. The conference is a bit of a hodge-podge of Enterprise RIA, and Web 2.0, with a dash of iPhone development for flavour. I have included some of my thoughts after leaving the conference, as well as some contrasts to last [...]]]></description>
			<content:encoded><![CDATA[<p>I am back from a week in sunny San Jose at the <a href="http://ajaxworld.com/">AjaxWorld 2008 </a>conference. The conference is a bit of a hodge-podge of Enterprise RIA, and Web 2.0, with a dash of iPhone development for flavour. I have included some of my thoughts after leaving the conference, as well as some contrasts to last year’s conference:</p>
<p><strong>No mention of Mash-ups</strong></p>
<p>Last year several of the talks (especially the keynotes) focused on enterprise mash-ups. By contrast, this year I hardly heard the word uttered (despite being one of the themes of the conference). I must admit that I was quite interested in the concepts of mash-ups after last year’s conference, but have since become more skeptical. I think that plain old Excel <a href="http://blogs.computerworld.com/are_enterprise_mashups_the_excel_of_our_era">will continue to reign</a> as the great mash-up platforms for some years to come.</p>
<p><strong>Struggle between server-centric and client-centric architectures</strong></p>
<p>For those who gave talks pontificating for a platform solution to web development, there was a very clear divide between those who favoured a client-centric approach, and those who favoured a server-centric approach. In reality, I would say that neither is clearly superior to the other in every case. As I have oft heard <a href="http://iablog.sybase.com/paulley/2008/05/i-dont-have-any-silver-bullets/">Glenn say</a> (quoting a professor of his), “There are no right answers, only tradeoffs.”  In a future post, I will go into a bit more detail on what I think those tradeoffs are.</p>
<p><strong>Choices abound at every turn</strong></p>
<p>There is no shortage of choices in RIA development, and “To plugin, or not to plugin” will be among the first. In the plugin arena there is a host of relatively new heavyweight contenders including Microsoft SilverLight, Adobe AIR, and JavaFX (although it was hardly mentioned at the conference). In the non-plugin camp, many speakers talked about the proliferation of JavaScript libraries available (such as <a href="http://jquery.com/">jQuery</a>, <a href="http://www.prototypejs.org/">Prototype</a>, and <a href="http://script.aculo.us/">Script.aculo.us</a>). Similar to my previous point, there are advantages and tradeoffs associated with each of them, and in my opinion, there was no obvious choice among them.<br />
<strong><br />
The database is being increasingly ignored and abstracted</strong></p>
<p>I was a little surprised at how little mention databases received in the talks. Even the keynotes by Microsoft and Oracle made only passing references to the database. In reality, for most websites (especially enterprise ones) the database will be a very central piece of the application. Coupled with this is the trend towards object-relational mappers to wrap the database. Although from a database purist point of view ORMs seem to discard years of database research and development, there are very compelling reasons to use them (especially in the web space). Again, I will be going into more detail on this in a future post.</p>
]]></content:encoded>
			<wfw:commentRss>http://iablog.sybase.com/efarrar/2008/10/musings-on-ajaxworld-2008/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Setting the MIME Type</title>
		<link>http://iablog.sybase.com/efarrar/2008/10/setting-the-mime-type/</link>
		<comments>http://iablog.sybase.com/efarrar/2008/10/setting-the-mime-type/#comments</comments>
		<pubDate>Fri, 10 Oct 2008 17:33:22 +0000</pubDate>
		<dc:creator>Eric Farrar</dc:creator>
		
		<category><![CDATA[Practical]]></category>

		<guid isPermaLink="false">http://iablog.sybase.com/efarrar/2008/10/setting-the-mime-type/</guid>
		<description><![CDATA[While browsing around the internet, your browser makes many requests for many different types of content. The content that is returned may be an image, a sound file, a SWF file, or hundreds of other things. The browser relies on the web server that’s returning the data to tell it what it’s receiving, and how [...]]]></description>
			<content:encoded><![CDATA[<p>While browsing around the internet, your browser makes many requests for many different types of content. The content that is returned may be an image, a sound file, a SWF file, or hundreds of other things. The browser relies on the web server that’s returning the data to tell it what it’s receiving, and how it should be interpreted and displayed.</p>
<p>This meta information is called the document’s MIME type (<a href="http://en.wikipedia.org/wiki/MIME">Multipurpose Internet Mail Extensions</a>).  The standard was first developed for e-mail (hence the word ‘Mail’ in the acronym), but has since extended to HTTP. However with browsers, it is often called the Content Type. This is because the <code>Content-Type</code> HTTP header is the vehicle used to convey the MIME type to the browser. In Firefox if you right-click on this page is choose ‘View Page Info’, you will see that the Content-Type of this page is <code>text/html</code>.</p>
<p>This explains why in our <a href="http://iablog.sybase.com/efarrar/2008/09/hello-world/">first example</a>, we had to specifically set the <code>Content-Type</code> to let the browser know what we were sending it. This may seem odd if you have worked with other web servers such as Apache. You may have used Apache to host lots of types of content and never had to set any MIME types. This is because Apache is doing all the MIME work for you. If you look in your Apache configuration directory, you will find a file called <a href="http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types">mime.types</a> that contains entries that look like this:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="text">image/bmp          bmp
image/gif          gif
image/jpeg         jpeg jpg jpe
...</pre></td></tr></table></div>

<p>This is Apache’s master list to convert a URL’s extension into a MIME type. If you want to change a mapping you can either edit this file directly, or use the <a href="http://httpd.apache.org/docs/1.3/mod/mod_mime.html">mod_mime</a> module. All Apache is doing under the covers is extracting the extension, and looking it up in mime.types. The <a href="http://technet.microsoft.com/en-us/library/bb742440.aspx">MIME table</a> in Microsoft IIS works in a similar way. Looking up things in a table is just what databases do well, so let’s build an automatic <code>Content-Type</code> setter for SQL Anywhere web services.</p>
<p>First, we need a table to hold the extensions dictionary:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> MIMEType <span style="color: #66cc66;">&#40;</span>
  <span style="color: #ff0000;">&quot;Extension&quot;</span> CHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span>,
  <span style="color: #ff0000;">&quot;Type&quot;</span> CHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>
<span style="color: #66cc66;">&#41;</span>;</pre></td></tr></table></div>

<p>Second, we need to make a procedure that extracts the extension from the URL, looks it up in the table, and sets the Content-Type header</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
</pre></td><td class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">CREATE</span> PROCEDURE AutoSetMIMEType<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
BEGIN
  DECLARE loc INTEGER;
  DECLARE ext CHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span>;
  DECLARE mimetype CHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
  <span style="color: #808080; font-style: italic;">-- Find the location of the last period in the URI</span>
  <span style="color: #993333; font-weight: bold;">SET</span> loc <span style="color: #66cc66;">=</span> LOCATE<span style="color: #66cc66;">&#40;</span>HTTP_Header<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'@HttpURI'</span><span style="color: #66cc66;">&#41;</span>, <span style="color: #ff0000;">'.'</span>, <span style="color: #cc66cc;">-1</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
  <span style="color: #808080; font-style: italic;">-- If no period exists, default to ‘text/plain’</span>
  <span style="color: #993333; font-weight: bold;">IF</span> loc <span style="color: #66cc66;">&gt;</span> <span style="color: #cc66cc;">0</span> THEN
    <span style="color: #808080; font-style: italic;">-- Extract the extension and convert to lower case</span>
    <span style="color: #993333; font-weight: bold;">SET</span> ext <span style="color: #66cc66;">=</span> LOWER<span style="color: #66cc66;">&#40;</span>SUBSTR<span style="color: #66cc66;">&#40;</span>HTTP_Header<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'@HttpURI'</span><span style="color: #66cc66;">&#41;</span>, loc + <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
    <span style="color: #808080; font-style: italic;">-- If the extension exists, use the corresponding type</span>
    <span style="color: #808080; font-style: italic;">-- Otherwise default to ‘text/plain’</span>
    <span style="color: #993333; font-weight: bold;">IF</span> <span style="color: #993333; font-weight: bold;">EXISTS</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> Extension <span style="color: #993333; font-weight: bold;">FROM</span> MIMEType <span style="color: #993333; font-weight: bold;">WHERE</span> Extension <span style="color: #66cc66;">=</span> ext<span style="color: #66cc66;">&#41;</span> THEN
      <span style="color: #993333; font-weight: bold;">SELECT</span> Type <span style="color: #993333; font-weight: bold;">INTO</span> mimetype <span style="color: #993333; font-weight: bold;">FROM</span> MIMEType <span style="color: #993333; font-weight: bold;">WHERE</span> Extension <span style="color: #66cc66;">=</span> ext;
      CALL sa_set_http_header<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Content-Type'</span>, mimetype<span style="color: #66cc66;">&#41;</span>;
    ELSE
      CALL sa_set_http_header<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Content-Type'</span>, <span style="color: #ff0000;">'text/plain'</span><span style="color: #66cc66;">&#41;</span>;
    END <span style="color: #993333; font-weight: bold;">IF</span>;
  ELSE
    CALL sa_set_http_header<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Content-Type'</span>, <span style="color: #ff0000;">'text/plain'</span><span style="color: #66cc66;">&#41;</span>;
  END <span style="color: #993333; font-weight: bold;">IF</span>;
END;</pre></td></tr></table></div>

<p>Now all that is left to do is add Extension/Type pairs to the table like this:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> MIMEType <span style="color: #993333; font-weight: bold;">VALUES</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'bmp'</span>,  <span style="color: #ff0000;">'image/bmp'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> MIMEType <span style="color: #993333; font-weight: bold;">VALUES</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'gif'</span>,  <span style="color: #ff0000;">'image/gif'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> MIMEType <span style="color: #993333; font-weight: bold;">VALUES</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'jpeg'</span>, <span style="color: #ff0000;">'image/jpeg'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> MIMEType <span style="color: #993333; font-weight: bold;">VALUES</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'jpg'</span>,  <span style="color: #ff0000;">'image/jpeg'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> MIMEType <span style="color: #993333; font-weight: bold;">VALUES</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'jpe'</span>,  <span style="color: #ff0000;">'image/jpeg'</span><span style="color: #66cc66;">&#41;</span>;
...</pre></td></tr></table></div>

<p>I have compiled a list of about 600 common MIME Types (based off mime.types) that you can cut and paste into Interactive SQL. You can get that SQL file <a href="http://iablog.sybase.com/efarrar/wp-content/uploads/2008/09/autosetmimetype.sql">here</a>.</p>
<p>To use the function, all we have to do is add</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="sql">CALL AutoSetMIMEType<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</pre></td></tr></table></div>

<p>Somewhere in our web service handler, and the MIME type will be automatically set from the extension, just like it is in Apache and IIS.</p>
<p>As a side note, there are actually some more sophisticated ways to determine the MIME type. One example is the <a href="http://publib.boulder.ibm.com/httpserv/manual60/mod/mod_mime_magic.html">mod_mime_magic</a> module for Apache that looks at the first few bytes of the content and makes a guess on what the type is (for example, does it look like a BMP header?, an XML header?, etc…). While useful, it is recommended that this should only be used as a &#8220;<a href="http://publib.boulder.ibm.com/httpserv/manual60/mod/mod_mime_magic.html">second line of defense</a>&#8220;, and not the primary strategy.</p>
]]></content:encoded>
			<wfw:commentRss>http://iablog.sybase.com/efarrar/2008/10/setting-the-mime-type/feed/</wfw:commentRss>
		</item>
		<item>
		<title>AjaxWorld 2008</title>
		<link>http://iablog.sybase.com/efarrar/2008/09/ajaxworld-2008/</link>
		<comments>http://iablog.sybase.com/efarrar/2008/09/ajaxworld-2008/#comments</comments>
		<pubDate>Fri, 26 Sep 2008 17:56:11 +0000</pubDate>
		<dc:creator>Eric Farrar</dc:creator>
		
		<category><![CDATA[Conferences]]></category>

		<guid isPermaLink="false">http://iablog.sybase.com/efarrar/2008/09/ajaxworld-2008/</guid>
		<description><![CDATA[I just found out that my abstract for AjaxWorld 2008 in San Jose has been accepted. I will be speaking on Tuesday, October 22nd at 9:20 about object-relational mapppers (ORMs) and the database. The talk is titled It&#8217;s 11 p.m., do you know where your queries are?:
Object-relational mappers such as Hibernate, LINQ, and Rail&#8217;s ActiveRecord [...]]]></description>
			<content:encoded><![CDATA[<p>I just found out that my abstract for <a href="http://ajaxworld.com/">AjaxWorld 2008</a> in San Jose has been accepted. I will be speaking on Tuesday, October 22nd at 9:20 about object-relational mapppers (ORMs) and the database. The talk is titled <a href="http://ajaxworld.com/general/sessiondetail1008.htm?id=99">It&#8217;s 11 p.m., do you know where your queries are?:</a></p>
<blockquote><p><small class="session-bodycopy">Object-relational mappers such as Hibernate, LINQ, and Rail&#8217;s ActiveRecord can greatly simplify creating database-backed web applications. These tools do such a good job of abstracting the database, that is possible to create very complex web applications without ever considering the database at all!. Unfortunately, ignorance is not always bliss. When naively programmed, seemingly trivial application code can cause inefficient queries at best, and scalability and concurrency nightmares at worst. This talk will show that while ORM&#8217;s provide tremendous power and speed, it is still very important to know what is going underneath the comfortable abstraction layer the ORM provides. Examples will include identifying client-side joins, concurrency problems, and scalability issues.  </small></p></blockquote>
<blockquote></blockquote>
<blockquote></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://iablog.sybase.com/efarrar/2008/09/ajaxworld-2008/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Where Does that URL End Up? Part 2</title>
		<link>http://iablog.sybase.com/efarrar/2008/09/where-does-that-url-end-up-part-2/</link>
		<comments>http://iablog.sybase.com/efarrar/2008/09/where-does-that-url-end-up-part-2/#comments</comments>
		<pubDate>Tue, 23 Sep 2008 18:31:35 +0000</pubDate>
		<dc:creator>Eric Farrar</dc:creator>
		
		<category><![CDATA[Practical]]></category>

		<guid isPermaLink="false">http://iablog.sybase.com/efarrar/2008/09/where-does-that-url-end-up-part-2/</guid>
		<description><![CDATA[In a first part of this post we discussed how the SQL Anywhere HTTP Server routes web requests. In brief, when a web request enters the web server, the web server will route the request to the service that most specifically identifies it. This post explains with how you can use the remaining part of [...]]]></description>
			<content:encoded><![CDATA[<p>In a <a href="http://iablog.sybase.com/efarrar/2008/09/where-does-that-url-end-up-part-1/">first part of this post</a> we discussed how the SQL Anywhere HTTP Server routes web requests. In brief, when a web request enters the web server, the web server will route the request to the service that most specifically identifies it. This post explains with how you can use the remaining part of the URL that does not match. In short, if we have defined a service,</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">CREATE</span> SERVICE <span style="color: #ff0000;">&quot;alice/files&quot;</span>
AUTHORIZATION OFF
USER DBA
TYPE ‘RAW’
URL OFF
<span style="color: #993333; font-weight: bold;">AS</span> CALL get_file<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</pre></td></tr></table></div>

<p>and we try to access the document <code>http://www.host.com/alice/files/business/overview</code>, how does our service use the remainder of the URL (the <code>'business/overview'</code> part in this case)?</p>
<p>The answer lies in the <code>URL</code> parameter of the service definition. The <code>URL</code> parameter can take three values, and the default value is <code>URL OFF</code>. With <code>URL OFF</code>, the service will not be used unless the URL identically matches the service name. So this case, not only can we not use the remaining part of the URL, but the service simply won’t work.</p>
<p>To allow access to the remaining part of the URL, we have two options. The first is to set <code>URL ON</code>. When <code>URL</code> is <code>ON</code>, a variable called <code>:url </code>is automatically created that contains the remaining part of the URL. Let’s say we altered the service to be:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">ALTER</span> SERVICE <span style="color: #ff0000;">&quot;alice/files&quot;</span>
AUTHORIZATION OFF
USER DBA
TYPE ‘RAW’
URL <span style="color: #993333; font-weight: bold;">ON</span>
<span style="color: #993333; font-weight: bold;">AS</span> CALL get_file<span style="color: #66cc66;">&#40;</span>:url<span style="color: #66cc66;">&#41;</span>;</pre></td></tr></table></div>

<p>Now we have access to the <code>:url </code>variable that contains <code>'business/overview</code>&#8216;, and we can pass that to the stored procedure that handles this service. The drawback to <code>URL ON</code> is that even if the remaining URL contains many elements, it will still only be captured as a single string. This is where the <code>URL ELEMENTS</code> is useful.</p>
<p><code>URL ELEMENTS</code> works differently. Instead of creating a single variable called <code>:url</code> that contains the whole string, it creates many variables each representing a part of the URL. These variables are called <code>:url1</code>, <code>:url2</code>, …, <code>:url10</code>. It will create as many variables as there are parts to the URL up to a maximum of 10.</p>
<p>Suppose your application uses RESTful services and the URLs to browse your product catalog all are of the form:</p>
<p><code>/[DEPARMENT]/[PRODUCT]/[SIZE]</code></p>
<p>A sample URL for this application might be:</p>
<p><code>www.host.com/Catalog/Mens/Polo_Shirt/Large</code></p>
<p>If you defined a service called <code>Catalog</code> and set <code>URL ON</code>, the <code>:url </code>variable would contain the entire string <code>'Mens/Polo_Shirt/Large</code>&#8216;. By using <code>URL ELEMENTS</code>, you instead end up with three strings:</p>
<p><code>:url1 = ‘Mens’</code><br />
<code>:url2 = ‘Polo_Shirt’</code><br />
<code>:url3 = ‘Large’</code></p>
<p>These string can then be passed into the stored procedure that handles the service as shown below.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">CREATE</span> SERVICE <span style="color: #ff0000;">&quot;Catalog&quot;</span>
AUTHORIZATION OFF
USER DBA
TYPE ‘RAW’
URL ELEMENTS
<span style="color: #993333; font-weight: bold;">AS</span> CALL get_price<span style="color: #66cc66;">&#40;</span>:url1, :url2, :url3<span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://iablog.sybase.com/efarrar/2008/09/where-does-that-url-end-up-part-2/feed/</wfw:commentRss>
		</item>
		<item>
		<title>At ZendCon 2008 This Week</title>
		<link>http://iablog.sybase.com/efarrar/2008/09/at-zendcon-2008-this-week/</link>
		<comments>http://iablog.sybase.com/efarrar/2008/09/at-zendcon-2008-this-week/#comments</comments>
		<pubDate>Tue, 16 Sep 2008 18:43:43 +0000</pubDate>
		<dc:creator>Eric Farrar</dc:creator>
		
		<category><![CDATA[Conferences]]></category>

		<guid isPermaLink="false">http://iablog.sybase.com/efarrar/2008/09/at-zendcon-2008-this-week/</guid>
		<description><![CDATA[I am at the ZendCon 2008 PHP show this whole week. I will be at the Sybase iAnywhere booth all day on Tuesday and Wednesday. Drop by and pick up and Sybase iAnywhere Remote Control Car, Web Edition CD, and have a chat with me.
On Thursday, I will be giving a talk entitled, Taking It [...]]]></description>
			<content:encoded><![CDATA[<p>I am at the <a href="http://www.zendcon.com/ZendCon08/public/content/home">ZendCon 2008 PHP</a> show this whole week. I will be at the Sybase iAnywhere booth all day on Tuesday and Wednesday. Drop by and pick up and Sybase iAnywhere Remote Control Car, Web Edition CD, and have a chat with me.</p>
<p>On Thursday, I will be giving a talk entitled, <a href="http://www.zendcon.com/ZendCon08/public/schedule/detail/214">Taking It All Offline</a>:</p>
<blockquote><p>Enterprise applications developed using <span class="caps">PHP</span> are getting better every day. They are continually becoming more secure, better performing, and more scalable. However, all of these applications can only be used when a network connection is available. This requirement prevents <span class="caps">PHP</span> applications from working in an occasionally-connected model. New browser plugin technologies such as Gears allow applications to run offline, but require the entire application be written in JavaScript (allowing little-or-no <span class="caps">PHP</span> code reuse). This talk will examine how <span class="caps">SQL</span> Anywhere can help solve this problem, and take your current <span class="caps">PHP</span> application offline by locally hosting, managing, serving, and synchronizing your <span class="caps">PHP</span> application and data with your current database.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://iablog.sybase.com/efarrar/2008/09/at-zendcon-2008-this-week/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Where Does that URL End Up? Part 1</title>
		<link>http://iablog.sybase.com/efarrar/2008/09/where-does-that-url-end-up-part-1/</link>
		<comments>http://iablog.sybase.com/efarrar/2008/09/where-does-that-url-end-up-part-1/#comments</comments>
		<pubDate>Fri, 12 Sep 2008 15:18:51 +0000</pubDate>
		<dc:creator>Eric Farrar</dc:creator>
		
		<category><![CDATA[Practical]]></category>

		<guid isPermaLink="false">http://iablog.sybase.com/efarrar/2008/09/where-does-that-url-end-up-part-1/</guid>
		<description><![CDATA[When a request enters a web server, the web server must go through a process to determine where the request should be sent, and what program should handle it. Basically, the web server must translate the logical URL into an absolute path. This process is called routing.
If you are using Apache, the default behavior is [...]]]></description>
			<content:encoded><![CDATA[<p class="MsoNormal">When a request enters a web server, the web server must go through a process to determine where the request should be sent, and what program should handle it. Basically, the web server must translate the logical URL into an absolute path. This process is called routing.</p>
<p class="MsoNormal">If you are using Apache, the default behavior is to route the request by appending the URL to the <code>DocumentRoot</code> defined in the Apache configuration file. For example, if the <code>DocumentRoot</code> is <code>/usr/web</code>, the following requests will be routed as:</p>
<pre><code>http://www.host.com/index.htm               -&gt; /usr/web/index.htm
http://www.host.com/alice/index.htm         -&gt; /usr/web/alice/index.htm
http://www.host.com/alice/files/index.htm   -&gt; /usr/web/alice/files/index.htm
http://www.host.com/alice/history/index.htm -&gt; /usr/web/alice/history/index.htm</code></pre>
<p class="MsoNormal">In this case, the routing is very simple since all URLs will be routed to the same place. But what if Alice’s files and history are in different places? The requests will have to be routed differently. In Apache, you would typically use the <a href="http://httpd.apache.org/docs/2.0/mod/mod_alias.html">mod_alias</a> module to accomplish this. <code>Mod_alias</code> allows you to define routing rules that will effectively make different <code>DocumentRoot</code>s for each request. If you added the following to your Apache configuration file:</p>
<pre><code>Alias /alice/files   /home/alice/projects/files
Alias /alice/history /home/alice/history
Alias /alice         /home/alice/www</code></pre>
<p class="MsoNormal">The resultant routes would be:</p>
<pre><code>http://www.host.com/index.htm               -&gt; /usr/web/index.htm
http://www.host.com/alice/index.htm         -&gt; /home/alice/www/index.htm
http://www.host.com/alice/files/index.htm   -&gt; /home/alice/projects/files/index.htm
http://www.host.com/alice/history/index.htm -&gt; /home/alice/history/index.htm</code></pre>
<p class="MsoNormal">When using <code>mod_alias</code>, it is important to make sure that the most specific aliases are defined first. <code>Mod_alias</code> works by stepping through the alias list and using the first rule that matches. If we had defined the <code>/alice</code> alias before the <code>/alice/file</code> alias, all request though <code>http://www.host.com/alice/files</code> would have actually been routed to <code>/home/alice/www/files</code>.</p>
<p class="MsoNormal">If no aliases match, Apache will use the default <code>DocumentRoot</code> to create the absolute path.</p>
<p class="MsoNormal"> For another example, let’s take a look at the routing of the <a href="http://code.google.com/appengine/">Google App Engine</a>. On that server, routing is determined by the handlers section of the <code>app.yaml</code> <a href="http://code.google.com/appengine/docs/configuringanapp.html">configuration file</a>. To do  similar routing to what we did in Apache, the file would look like:</p>
<pre><code>handlers:
- url: /alice/files
  static_dir: home/alice/projects/files

- url: /alice/history
  static_dir: home/alice/history

- url: /alice
  static_dir: home/alice/www

- url: /*
  script: home.py</code></pre>
<p>Similar to Apache, the Google App Engine evaluates the routes in order and will use the first one that matches.</p>
<p class="MsoNormal">So how does routing work in SQL Anywhere? In SQL Anywhere, every service that is created acts as an alias. So the equivalent routing in SQL Anywhere would be created like this:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">CREATE</span> SERVICE “root”
<span style="color: #993333; font-weight: bold;">AS</span> … ;
&nbsp;
<span style="color: #993333; font-weight: bold;">CREATE</span> SERVICE “alice”
<span style="color: #993333; font-weight: bold;">AS</span> … ;
&nbsp;
<span style="color: #993333; font-weight: bold;">CREATE</span> SERVICE “alice/files”
<span style="color: #993333; font-weight: bold;">AS</span> … ;
&nbsp;
<span style="color: #993333; font-weight: bold;">CREATE</span> SERVICE “alice/history”
<span style="color: #993333; font-weight: bold;">AS</span> … ;</pre></td></tr></table></div>

<p class="MsoNormal">The <code>root</code> service is the same as the default <code>DocumentRoot</code> in Apache, or the <code> url: /* </code>rule in the Google App Engine. It will be used to route when no other services match. This is why I said in my <a href="http://iablog.sybase.com/efarrar/2008/09/hello-world/">previous post</a> that the <code>root</code> service will respond to anything. However, unlike both Apache and the Google App Engine, SQL Anywhere will automatically choose the most specific service, so the order of creation does not matter.</p>
<p class="MsoNormal"><o:p></o:p>If you are wondering how we use the rest of the URL in the services we have just defined (that is, how <code>http://www.host.com/alice/files</code> will become <code>/home/alice/projects/files</code>), stay tuned for part 2.</p>
]]></content:encoded>
			<wfw:commentRss>http://iablog.sybase.com/efarrar/2008/09/where-does-that-url-end-up-part-1/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Hello, World!</title>
		<link>http://iablog.sybase.com/efarrar/2008/09/hello-world/</link>
		<comments>http://iablog.sybase.com/efarrar/2008/09/hello-world/#comments</comments>
		<pubDate>Mon, 08 Sep 2008 14:07:15 +0000</pubDate>
		<dc:creator>Eric Farrar</dc:creator>
		
		<category><![CDATA[Practical]]></category>

		<guid isPermaLink="false">http://iablog.sybase.com/efarrar/2008/09/hello-world/</guid>
		<description><![CDATA[Now that we have everything defined, we can start to look at what is actually going on behind the browser. To do this, we will need some software. First off, we will need a browser (and that choice has become more interesting in the last week with the appearance of Google Chrome), but for now [...]]]></description>
			<content:encoded><![CDATA[<p>Now that we have everything defined, we can start to look at what is actually going on behind the browser. To do this, we will need some software. First off, we will need a browser (and that choice has become more interesting in the last week with the appearance of <a href="http://www.google.com/chrome">Google Chrome</a>), but for now any browser should do.</p>
<p>We also will need a web server to respond to the browser&#8217;s requests, and a database or file system to actually hold the content. SQL Anywhere has a built-in HTTP server, it <em>is</em> a database server, and it has access to the file system.  As a result, for now at least, all we will need to produce a simple web page is SQL Anywhere.  The free SQL Anywhere Web Edition will work well for this example, and can be downloaded <a href="http://www.sybase.com/download_sqlany_11_web_edition">here</a>. I have also added a permanent download button to the sidebar on the right.</p>
<p>The <a href="http://en.wikipedia.org/wiki/Hello_world_program">Hello World </a>program is a classic, so it only seems fitting that we should start with it. First, we need to create a SQL Anywhere database.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="bash">dbinit hello.db</pre></td></tr></table></div>

<p>Now that the database file has been created, we need to start the database and HTTP server. The HTTP Server is not started by default when the database is started, so we need to add the <code>-xs</code> switch to enable it. There are lots of options for the HTTP server, but for now we have only specified that we want to start it on port 8080. You can change this to use any free port.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="bash">dbeng11 hello.db -xs http<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #007800;">port=</span><span style="color: #000000;">8080</span><span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></td></tr></table></div>

<p>After the database has started, start up DBISQL. We will use DBISQL to execute the SQL statements we need to create our page.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="bash">dbisql -c <span style="color: #ff0000;">&quot;eng=hello;uid=dba;pwd=sql&quot;</span></pre></td></tr></table></div>

<p>The first thing we will define is a service. A service can be thought of as an endpoint that responds to HTTP requests. Subsequent posts will go into a lot more detail on how exactly the requests are routed. For now, simply know that a service named <code>root</code> will respond to <em>anything</em>. You can ignore most of the other parameters for now. All you need to know is that we have defined a HTTP endpoint that responds by returning the results of calling the <code>hello_world</code> stored procedure.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">CREATE</span> SERVICE <span style="color: #ff0000;">&quot;root&quot;</span>
TYPE <span style="color: #ff0000;">'RAW'</span>
AUTHORIZATION OFF
USER DBA
URL OFF
<span style="color: #993333; font-weight: bold;">AS</span> CALL hello_world<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</pre></td></tr></table></div>

<p>Next, then, we had better create that stored procedure! The stored procedure only does two things:</p>
<ol>
<li>Set an HTTP header called Content-Type (more on this later)</li>
<li>Returns a block of HTML text representing our Hello, World! page</li>
</ol>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code"><pre class="sql"><span style="color: #993333; font-weight: bold;">CREATE</span> PROCEDURE hello_world<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
BEGIN
  CALL sa_set_http_header<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Content-Type'</span>, <span style="color: #ff0000;">'text/html'</span><span style="color: #66cc66;">&#41;</span>;
  <span style="color: #993333; font-weight: bold;">SELECT</span>
<span style="color: #ff0000;">'&lt;HTML&gt;
  &lt;HEAD&gt;
    &lt;TITLE&gt;Hello, World!&lt;/TITLE&gt;
  &lt;/HEAD&gt;
  &lt;BODY&gt;
    &lt;H1&gt;Hello, World!&lt;/H1&gt;
  &lt;/BODY&gt;
&lt;/HTML&gt;'</span>;
END;</pre></td></tr></table></div>

<p>Done! Start up your browser and point it at <a href="http://localhost:8080">http://localhost:8080</a>.</p>
<p><a href="http://iablog.sybase.com/efarrar/wp-content/uploads/2008/09/hello_world.PNG" title="HelloWorld"><img src="http://iablog.sybase.com/efarrar/wp-content/uploads/2008/09/hello_world.PNG" alt="HelloWorld" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://iablog.sybase.com/efarrar/2008/09/hello-world/feed/</wfw:commentRss>
		</item>
		<item>
		<title>What are we hoping to see?</title>
		<link>http://iablog.sybase.com/efarrar/2008/08/what-are-we-hoping-to-see/</link>
		<comments>http://iablog.sybase.com/efarrar/2008/08/what-are-we-hoping-to-see/#comments</comments>
		<pubDate>Thu, 28 Aug 2008 21:12:02 +0000</pubDate>
		<dc:creator>Eric Farrar</dc:creator>
		
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://iablog.sybase.com/efarrar/2008/08/what-are-we-hoping-to-see/</guid>
		<description><![CDATA[In my last blog entry, I dealt with defining the ‘browser’ part of my blog’s title. It only seems fitting that I also talk about the other half of the title and answer the question, “What is it we are hoping to see?”  The answer: When a browser displays data, where does that data [...]]]></description>
			<content:encoded><![CDATA[<p class="MsoNormal">In my <a href="http://iablog.sybase.com/efarrar/2008/08/what-is-it-we-are-peering-behind/">last blog entry</a>, I dealt with defining the ‘browser’ part of my blog’s title. It only seems fitting that I also talk about the other half of the title and answer the question, “What is it we are hoping to see?” <span> </span>The answer: When a browser displays data, where does that data live, and how does it get there?<o:p> </o:p></p>
<p class="MsoNormal">For a lot of websites, the answers may be quite simple. The data actually appears to come from a web server that handles HTTP requests. The web server, in turn, invokes a server-side scripting language such as PHP or ASP.net to talk to a database server. The data permanently lives in that database server. The database server and web server are either hosted internally, or hosted at an ISP. This simple setup describes how the majority of web sites operate today. So what more is there to look at?<o:p> </o:p></p>
<p class="MsoNormal">Lots. Developments in the last year have added a whole range of possibilities to this simple picture. One example of this is the variety of new hosting options available. Previously, hosting a website at an ISP would often involve sharing both machine and database with other users. It was very rare that you could have root SSH access to your machine. Now, with cloud-based solutions such as <a href="http://www.amazon.com/gp/browse.html?node=201590011">Amazon EC2</a> that host virtual machines images, a perfectly legitimate answer to the question, “Where is your data living?” may be, “Dunno…somewhere in the world…it is in the cloud somewhere.”<o:p> </o:p></p>
<p class="MsoNormal">Even if you don’t know where the data is actually living, you could argue that from the browser’s perspective that data still appears to come from the same place. Have there been any developments recently that change this? Absolutely.<br />
<o:p></o:p><br />
The one that pops most readily to mind is <a href="http://gears.google.com/">Gears</a>, an open source project focused on adding extra functionality to browsers. Although many ‘gears’ exist now, the <a href="http://gearsblog.blogspot.com/2007/05/posted-by-aaron-boodman-and-erik.html">project’s initial offerings</a> were focused on storing data locally in the browser, introducing the possibility of offline web applications. In addition to creating offline applications, developers soon discovered that even online application could benefit from having a quick, local data store. Currently both <a href="http://ajaxian.com/archives/gears-turns-one-old-enough-to-power-myspace-search">MySpace </a>and <a href="http://ajaxian.com/archives/speed-up-with-wordpress-and-gears">Wordpress </a>use Gears, not for offline access, but to enhance their online experience.</p>
<p class="MsoNormal">The question of where the data lives and how it gets there is bound to get more interesting as time goes on. Let’s peer behind the browser, and take a look…</p>
]]></content:encoded>
			<wfw:commentRss>http://iablog.sybase.com/efarrar/2008/08/what-are-we-hoping-to-see/feed/</wfw:commentRss>
		</item>
		<item>
		<title>What is it we are peering behind?</title>
		<link>http://iablog.sybase.com/efarrar/2008/08/what-is-it-we-are-peering-behind/</link>
		<comments>http://iablog.sybase.com/efarrar/2008/08/what-is-it-we-are-peering-behind/#comments</comments>
		<pubDate>Thu, 21 Aug 2008 20:42:58 +0000</pubDate>
		<dc:creator>Eric Farrar</dc:creator>
		
		<category><![CDATA[Technology]]></category>

		<category><![CDATA[AIR]]></category>

		<category><![CDATA[browser]]></category>

		<category><![CDATA[Flash]]></category>

		<category><![CDATA[JavaFX]]></category>

		<category><![CDATA[Socrates]]></category>

		<category><![CDATA[Theaetetus]]></category>

		<guid isPermaLink="false">http://iablog.sybase.com/efarrar/2008/08/21/what-is-it-we-are-peering-behind/</guid>
		<description><![CDATA[If I am going to write a blog titled Peering Behind the Browser, I had better start by defining what exactly it is I mean by a browser. So perhaps the title begs the simple question, “What is a browser?” The search for the answer, we will see, is actually not so simple.

The knee-jerk reaction [...]]]></description>
			<content:encoded><![CDATA[<p class="MsoNormal">If I am going to write a blog titled <u>Peering Behind the Browser</u>, I had better start by defining what exactly it is I mean by a browser. So perhaps the title begs the simple question, “What is a browser?” The search for the answer, we will see, is actually not so simple.</p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal">The knee-jerk reaction to the question might be, “Browsers are programs that display web pages like Firefox, Internet Explorer, and Safari.” This brings to mind a similar interaction in Plato’s <a href="http://en.wikipedia.org/wiki/Theaetetus_%28dialogue%29"><em>Theaetetus.</em></a> In that dialogue, Socrates asked Theaetetus to define <em>‘knowledge’</em>. Theaetetus replied that knowledge is things that could be learned like geometry, cobbling, and trades. <a href="http://books.google.com/books?id=w-Ku6zwIyJMC&amp;pg=PA34&amp;lpg=PA34&amp;dq=knowledge+socrates+clay&amp;source=web&amp;ots=tUOPd2esbs&amp;sig=9h_xdI5z-AqNI-tmUX_sxTS50wE&amp;hl=en&amp;sa=X&amp;oi=book_result&amp;resnum=1&amp;ct=result">Socrates criticized this answer</a>, pointing out that although those are examples of knowledge, they don’t actually describe what knowledge is. Similarly, the programs listed above are examples of browsers, but fail to explain what one is.</p>
<p class="MsoNormal"><o:p></o:p>So let’s broaden our definition and say it is a program that remotely accesses data through a network, and renders HTML, JavaScript, and CSS for display to the user. This certainly describes the vast majority of things that a browser does, but does it explain them all? Most people would agree that when they watch a video on YouTube, they are watching it in a browser. However, the underlying technology that YouTube is using is Adobe Flash. If you use a stand-alone Flash player to watch that same movie, does that make the stand-alone player a browser?</p>
<p class="MsoNormal"><o:p> </o:p>This actually becomes far more interesting with the recent offerings of RIA technologies in the last year. Adobe AIR allows exactly these types of stand-alone applications. The <a href="http://desktop.ebay.com/">ebay Desktop</a> is a perfect example. It uses AIR to provide a desktop-like experience for browsing your ebay account, but displays the same information available at <a href="http://www.ebay.com/">www.ebay.com</a>. Does this make ebay Desktop a browser? To muddy the waters more, AIR applications can be coded in HTML and CSS!</p>
<p class="MsoNormal"><o:p> </o:p>The last data point we will review is <a href="http://javafx.com/">JavaFX</a>, an RIA technology produced by Sun. It can allow running Java Applets to be dragged and dropped between programs such as Firefox and Internet Explorer, and the desktop. So if the applet was a browser application while in Firefox, is it still a browser application after it is dragged out and running on the desktop?</p>
<p class="MsoNormal"><o:p></o:p>I don’t actually intend to answer the question, so in a sense I have done no better than Theaetetus did. But in this blog we will be considering all of these technologies as browsers, and we will be peering behind them all to see what lies underneath.</p>
]]></content:encoded>
			<wfw:commentRss>http://iablog.sybase.com/efarrar/2008/08/what-is-it-we-are-peering-behind/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
