<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Nando @ Aria Media]]></title>
  <link href="http://dnando.github.io/atom.xml" rel="self"/>
  <link href="http://dnando.github.io/"/>
  <updated>2017-11-20T22:19:35+01:00</updated>
  <id>http://dnando.github.io/</id>
  <author>
    <name><![CDATA[Nando @ Aria Media]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Cfqueryparam Setting for SQL 'in' Statements]]></title>
    <link href="http://dnando.github.io/blog/2017/04/09/cfqueryparam-setting-for-sql-in-statements/"/>
    <updated>2017-04-09T01:32:33+02:00</updated>
    <id>http://dnando.github.io/blog/2017/04/09/cfqueryparam-setting-for-sql-in-statements</id>
    <content type="html"><![CDATA[<p>When using an SQL IN statement within a ColdFusion query, it is necessary to add the attribute <code>list="true"</code> to the param used for the list. See the example below that selects all employees that have a birthdate in March, April or May.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>public query function findUpcomingBirthdates() {
</span><span class='line'>  var params = {};
</span><span class='line'>  var ml = "3,4,5";
</span><span class='line'>  params.insert( "monthList", { value: ml, cfsqltype: "cf_sql_integer", list: true } );
</span><span class='line'>  var sql = "
</span><span class='line'>      select employeeId, firstName, lastName, birthdate
</span><span class='line'>      from Employee
</span><span class='line'>      where month( birthdate ) in ( :monthList )
</span><span class='line'>  ";
</span><span class='line'>  return queryExecute( sql, params );
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>Thanks to Ben Nadel&rsquo;s post <a href="https://www.bennadel.com/blog/425-coldfusion-cfqueryparam-list-attribute-is-sweeet.htm">here</a> for this crucial tidbit of information!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Hot Browser Reloading With Browsersync]]></title>
    <link href="http://dnando.github.io/blog/2017/03/20/hot-browser-reloading/"/>
    <updated>2017-03-20T00:06:28+01:00</updated>
    <id>http://dnando.github.io/blog/2017/03/20/hot-browser-reloading</id>
    <content type="html"><![CDATA[<p>I&rsquo;ve fallen down the rabbit hole of front end development in the last few weeks, and in that time <a href="https://css-tricks.com/snippets/css/a-guide-to-flexbox/">Flexbox CSS</a>, <a href="http://blog.getbootstrap.com/2017/01/06/bootstrap-4-alpha-6/">Bootstrap v4</a>, <a href="http://foundation.zurb.com/">Foundation</a>, <a href="http://sass-lang.com/guide">Sass / SCSS</a>, and <a href="http://gulpjs.com/">Gulp</a> have all whizzed by as I&rsquo;ve taught myself portions of each, and today I landed at the bottom, <a href="https://www.browsersync.io/">Browsersync</a>.</p>

<p>In a nutshell, Browsersync will live reload one or more browsers for you whenever your project&rsquo;s files change. It will also live reload external devices pointed at the same web application. This allows you to simultaneously and efficiently test a responsive design in multiple browsers, phones and tablets - without needing to touch or reload any of them. It also synchronizes form entries and clicks across browsers and devices. For example, with my phone and tablet connected to Browsersync, I log into the app I&rsquo;m developing on the tablet, and my keystrokes and touch gestures are replicated on the phone, and I&rsquo;m logged in on both. Then I start navigating in the application in Chrome on my desktop, and the phone, tablet and other browsers follow as &ldquo;slaves&rdquo;. Interacting with any interface causes the rest of them to follow. What an incredible tool! In the few minutes I&rsquo;ve been experimenting with it, I was able to easily and quickly fix a layout issue on the tablet and phone for the login screen.</p>

<p>Browsersync works by wrapping your application or website in its own Node server process, on another port. You can start Browsersync on the command line, or via a Grunt or Gulp task. During startup, you specify the local url of your app, the files you want it to watch - a number of other options are possible - and then a browser window opens, on port 3000 by default, and browsersync is activated for that browser. To add others, you simply use the same url. To add external devices, on localhost:3001 there is an admin panel for Browsersync that will list the external url to use. Navigate to that external url on your phone or tablet or another computer, for me it currently <a href="http://192.168.1.103:3000/,">http://192.168.1.103:3000/,</a> and Browsersync is set up on these devices as well. Once you have it configured, it is really simple to use.</p>

<p>A quick overview on installation and configuration: Basic instructions are on the homepage <a href="https://www.browsersync.io/.">https://www.browsersync.io/.</a></p>

<ol>
<li>Install or upgrade Node.js</li>
<li>Install Browsersync using npm</li>
</ol>


<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>npm install -g browser-sync</span></code></pre></td></tr></table></div></figure>


<p>The -g flag means global so it is available from anywhere.</p>

<ol>
<li>Start Browsersync</li>
</ol>


<p>There are 2 start modes, &ndash;server and &ndash;proxy. <em>server</em> is for static files, <em>proxy</em> is for applications running on a server. Here&rsquo;s a simplified example starting Browsersync from the command line:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>browser-sync start --proxy "myproject.dev" --files "css/*.css"</span></code></pre></td></tr></table></div></figure>


<p>&hellip; assuming you have your local host file set up to point your app at myproject.dev. Or you can also start Browsersync using a localhost:port url, like this:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>browser-sync start --proxy "localhost:8500/myproject" --files "css/*.css"</span></code></pre></td></tr></table></div></figure>


<p>There are a few real world ways to do this, but what I&rsquo;ve done is to create a gulpfile.js in the root of my project so I can configure Browsersync conveniently and start it with a simple gulp command after cd&#8217;ing in to my project directory. That way I don&rsquo;t have to remember much. Here&rsquo;s my first working gulpfile.js for a real development scenario. I have ACF (Adobe ColdFusion) installed on port 8501 on my dev laptop, and  gulp.watch() is configured for an FW/1 app. I&rsquo;m not sure if I actually want to watch the controllers and services directories, perhaps the views directory and CSS directory is enough. But for now I will leave it like this and see how it goes.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>var gulp = require('gulp');
</span><span class='line'>var browserSync = require('browser-sync').create();
</span><span class='line'>var reload = browserSync.reload;
</span><span class='line'>
</span><span class='line'>gulp.task('browser-sync', function() {
</span><span class='line'>  browserSync.init({
</span><span class='line'>      proxy: "localhost:8501/myproject"
</span><span class='line'>  });
</span><span class='line'>
</span><span class='line'>  gulp.watch([
</span><span class='line'>      'controllers/*.cfc', 'services/*.cfc', 'views/**/*.cfm', 'dist/*.css'
</span><span class='line'>  ]).on("change", function() {
</span><span class='line'>      console.log("Watch hit");
</span><span class='line'>      browserSync.reload();
</span><span class='line'>  });
</span><span class='line'>});
</span><span class='line'>
</span><span class='line'>gulp.task('default', ['browser-sync']);</span></code></pre></td></tr></table></div></figure>


<p>Note carefully the syntax of gulp.watch() for multiple directories / files. It&rsquo;s an array of strings separated by commas. Note also that the root of the relative paths specified is where the gulpfile.js is located.</p>

<p>But wait, wouldn&rsquo;t it be better if I could use Browsersync to develop against both ACF and Lucee? Here&rsquo;s a solution that I have working that creates named instances of Browsersync so they don&rsquo;t step on each other:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>var gulp = require('gulp');
</span><span class='line'>var bsacf = require('browser-sync').create('browserSyncACF');
</span><span class='line'>var bslucee = require('browser-sync').create('browserSyncLucee');
</span><span class='line'>
</span><span class='line'>gulp.task('browser-sync', function() {
</span><span class='line'>  bsacf.init({
</span><span class='line'>      proxy: "localhost:8501/myproject",
</span><span class='line'>      browser: "google chrome",
</span><span class='line'>      reloadOnRestart: true
</span><span class='line'>  });
</span><span class='line'>
</span><span class='line'>  bslucee.init({
</span><span class='line'>      proxy: "localhost:8888/myproject",
</span><span class='line'>      browser: "vivaldi",
</span><span class='line'>      port: 3010,
</span><span class='line'>      reloadOnRestart: true,
</span><span class='line'>      ui: {
</span><span class='line'>          port: 3011
</span><span class='line'>      }
</span><span class='line'>  });
</span><span class='line'>
</span><span class='line'>  gulp.watch([
</span><span class='line'>      'controllers/*.cfc', 'services/*.cfc', 'views/**/*.cfm', 'dist/*.css'
</span><span class='line'>  ]).on("change", function() {
</span><span class='line'>      console.log("Watch hit");
</span><span class='line'>      bsacf.reload();
</span><span class='line'>      bslucee.reload();
</span><span class='line'>  });
</span><span class='line'>});
</span><span class='line'>
</span><span class='line'>gulp.task('default', ['browser-sync']);</span></code></pre></td></tr></table></div></figure>


<p>I specify separate browsers for each so that ACF and Lucee sessions don&rsquo;t step on one another, and separate ports for the Lucee instance of Browsersync so they can coexist. The advantage to doing it this way is I can start both instances with a single <em>gulp</em> command on the command line. Unfortunately the ACF and Lucee instances of Browsersync will not mirror or ghost each other, so I will still have to click and enter test data on forms separately while developing, but this is still much better than needing to reload both browsers manually all the time.</p>

<h5>Update:</h5>

<p>I&rsquo;ve noticed one other feature of Browsersync that I wanted to see if I could get working - injecting modified CSS into the browser to avoid reloading the DOM. I&rsquo;ve now rearranged my gulpfile.js to be the following, adding a second gulp.watch() call to inject the minified bootstrap css directly into the browser, and removing the <em>dist</em> directory from the first gulp.watch() call so the browsers are not reloaded.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>var gulp = require('gulp');
</span><span class='line'>var bsacf = require('browser-sync').create('browserSyncACF');
</span><span class='line'>var bslucee = require('browser-sync').create('browserSyncLucee');
</span><span class='line'>
</span><span class='line'>gulp.task('browser-sync', function() {
</span><span class='line'>  bsacf.init({
</span><span class='line'>      proxy: "localhost:8501/easycal",
</span><span class='line'>      browser: "google chrome",
</span><span class='line'>      reloadOnRestart: true
</span><span class='line'>  });
</span><span class='line'>
</span><span class='line'>  bslucee.init({
</span><span class='line'>      proxy: "localhost:8888/easycal",
</span><span class='line'>      browser: "vivaldi",
</span><span class='line'>      port: 3010,
</span><span class='line'>      reloadOnRestart: true,
</span><span class='line'>      ui: {
</span><span class='line'>          port: 3011
</span><span class='line'>      }
</span><span class='line'>  });
</span><span class='line'>
</span><span class='line'>  gulp.watch([
</span><span class='line'>      'controllers/*.cfc', 'services/*.cfc', 'views/**/*.cfm',
</span><span class='line'>      'layouts/**/*.cfm', 'dist/*.css', 'easycal-app.css'
</span><span class='line'>  ]).on("change", function() {
</span><span class='line'>      console.log("Watch hit");
</span><span class='line'>      bsacf.reload();
</span><span class='line'>      bslucee.reload();
</span><span class='line'>  });
</span><span class='line'>
</span><span class='line'>  gulp.watch([
</span><span class='line'>      'dist/toolkit.min.css'
</span><span class='line'>  ]).on("change", function() {
</span><span class='line'>      console.log("CSS hit");
</span><span class='line'>      return gulp.src(['dist/toolkit.min.css'])
</span><span class='line'>          .pipe(bsacf.stream())
</span><span class='line'>          .pipe(bslucee.stream());
</span><span class='line'>  });
</span><span class='line'>});
</span><span class='line'>
</span><span class='line'>gulp.task('default', ['browser-sync']);</span></code></pre></td></tr></table></div></figure>


<p>I like how this is shaping up now. :-)</p>

<p>Comments or suggestions welcome!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Scale Attribute Is Essential With Decimal Cfsqltype]]></title>
    <link href="http://dnando.github.io/blog/2016/08/05/scale-attribute-is-essential-with-decimal-cfsqltype/"/>
    <updated>2016-08-05T00:22:47+02:00</updated>
    <id>http://dnando.github.io/blog/2016/08/05/scale-attribute-is-essential-with-decimal-cfsqltype</id>
    <content type="html"><![CDATA[<p>I just ran across something important to know regarding the cfsqltype cf_sql_decimal. Here&rsquo;s the code I was testing:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>params.insert( 'previousNumericDuration',
</span><span class='line'>  { value: preNDuration, cfsqltype: 'cf_sql_decimal' } );</span></code></pre></td></tr></table></div></figure>


<p>Here&rsquo;s what it would look like if you are using the cfqueryparam tag:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>&lt;cfqueryparam value='#preNDuration#' cfsqltype='cf_sql_decimal' /&gt;</span></code></pre></td></tr></table></div></figure>


<p>The database column this is persisted to is defined as a <code>decimal(4,2)</code>, so 2 digits are reserved for the whole number portion of the value and 2 digits reserved for the decimal portion of the value. Logging showed values being calculated such as 4.25 and 4.5, but these were being persisted to the database rounded to the nearest integer, but with 2 decimal places none the less, so 4.25 was persisted as <em>4.00</em> and 4.5 was persisted as <em>5.00</em>. Definitely not what I wanted. What&rsquo;s the point of a decimal datatype if the decimal portion is always 0?</p>

<p>Digging into the documentation for cfqueryparam I found a scale attribute that until today I hadn&rsquo;t realized was absolutely essential to use for decimal fields like this. Scale defines the &hellip; &ldquo;Number of decimal places in parameter. Applies to CF_SQL_NUMERIC and CF_SQL_DECIMAL.&rdquo; Its default is 0, so my values were being rounded to 0 decimal places. After changing my code to the following:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>params.insert( 'previousNumericDuration',
</span><span class='line'>  { value: preNDuration, cfsqltype: 'cf_sql_decimal', scale: 2 } );</span></code></pre></td></tr></table></div></figure>


<p>the decimal portion of the values was then persisted correctly.</p>

<p>So the <em>scale</em> attribute is absolutely essential for a <em>decimal</em> cfsqltype. I might have tripped over this before, I&rsquo;m not sure. Perhaps this blog post will help me remember it next time. Now I should search my code to see if I&rsquo;ve neglected this attribute elsewhere!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[First Steps With the Clojure Version of FW/1]]></title>
    <link href="http://dnando.github.io/blog/2016/03/22/first-steps-with-the-clojure-version-of-fw-slash-1/"/>
    <updated>2016-03-22T20:45:04+01:00</updated>
    <id>http://dnando.github.io/blog/2016/03/22/first-steps-with-the-clojure-version-of-fw-slash-1</id>
    <content type="html"><![CDATA[<p>Sean Corfield has built a Clojure version of the popular CFML framework FW/1. I&rsquo;ve been using FW/1 for a number of years, so I thought it might help me learn Clojure to begin developing an app in fw1-clj.</p>

<p>The first step to get up and running is to head on over to the <a href="https://github.com/framework-one/fw1-clj">fw1-clj GitHub repository</a> and follow the directions to <a href="https://github.com/boot-clj/boot#install">install Boot</a>, which is a build tool for Clojure. Next, as per the instructions on the fw1-clj GitHub repository, we run a boot command in a terminal to create a new fw1-clj app, which currently looks like this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>boot -d seancorfield/boot-new new -t fw1 -n myfw1app
</span></code></pre></td></tr></table></div></figure>


<p>(Sean has indicated this invocation may change in the future, so best to follow the fw1-clj repository instructions.)</p>

<p>Then, we &ldquo;cd&rdquo; into the application directory we specified above, in this example &ldquo;myfw1app&rdquo;, and start the application up like so:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nb">cd </span>myfw1app
</span><span class='line'><span class="nv">PORT</span><span class="o">=</span><span class="m">8111</span> boot run
</span></code></pre></td></tr></table></div></figure>


<p>Specifying the PORT variable isn&rsquo;t required, but may be necessary to avoid conflicts. If omitted, the default port is 8080.</p>

<p>Navigating to localhost:8111, we see a lovely default page that says &ldquo;Framework One - Welcome to FW/1&rdquo;. Yay! It certainly is impressive how easy that is. No server to install. Nothing to download. No settings to find and configure. We&rsquo;re ready to start developing.</p>

<p>There are several options to choose from in terms of an IDE for Clojure. Many experienced Clojure developers use <a href="https://www.gnu.org/software/emacs/">Emacs</a> with <a href="https://github.com/clojure-emacs/cider">CIDER</a>, or the <a href="https://cursive-ide.com/userguide/index.html">Cursive plugin</a> for <a href="https://www.jetbrains.com/idea/download/index.html">Intellij</a>. Both of those have a learning curve that you may prefer to avoid to focus on getting the basics of Clojure down first.</p>

<p>For beginners, good IDE&rsquo;s for experimentation are <a href="http://lighttable.com/">Light Table</a> or <a href="https://atom.io/">Atom</a> with <a href="https://atom.io/packages/search?q=clojure">a few Clojure packages</a> installed, such as language-clojure, proto-repl and parinfer. I&rsquo;m using Atom at the moment because I&rsquo;m also using it for CFML development, and also because the Clojure packages seem to work very well.</p>

<p>One of the first things I wanted to figure out was how to visualize the rc map (or struct as it would be known in CFML). With a tip from Sean, I navigated to src/projectName/controllers/main.clj in the project that boot generated for me, and within the default function definition, I added <code>(println rc)</code></p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='clojure'><span class='line'><span class="p">(</span><span class="kd">defn </span><span class="nv">default</span> <span class="s">&quot;/main/default handler&quot;</span> <span class="p">[</span><span class="nv">rc</span><span class="p">]</span>
</span><span class='line'>  <span class="p">(</span><span class="nb">println </span><span class="nv">rc</span><span class="p">)</span>
</span><span class='line'>  <span class="nv">rc</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>reloaded the app in the browser, and then checked the terminal window where I had started the app with the boot command for the output. Nothing was output there. After a moment, I remembered that I probably had to reload the application to get the changes picked up. Checking the somewhat sparse documentation on the Github page, I found the default reload query string would be &ldquo;?reload=secret&rdquo;. Hitting localhost:8111?reload=secret in the browser then generated the rc map in my terminal window - all in one <em>very</em> long line. After another suggestion from Sean, I replaced the print line function <code>(println rc)</code> with the clojure pretty print function  <code>(clojure.pprint/pprint rc)</code></p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='clojure'><span class='line'><span class="p">(</span><span class="kd">defn </span><span class="nv">default</span> <span class="s">&quot;/main/default handler&quot;</span> <span class="p">[</span><span class="nv">rc</span><span class="p">]</span>
</span><span class='line'>  <span class="p">(</span><span class="nf">clojure.pprint/pprint</span> <span class="nv">rc</span><span class="p">)</span>
</span><span class='line'>  <span class="nv">rc</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>hit localhost:8111?reload=secret again, and now the keys within the rc map were nicely separated by line breaks in the terminal output. Much more readable that way.</p>

<p>I noticed within the output that the :reload-application-on-every-request key was set to false. Better in development to have that set to true, so reading the docs, I found &ldquo;the call to (fw1/start) can be passed configuration parameters either as a map or as an arbitrary number of inline key / value pairs&rdquo;</p>

<p>Ok, so opening src/projectName/main.clj, I found the call to (fw1/start) and changed it from</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='clojure'><span class='line'><span class="p">(</span><span class="kd">defn </span><span class="nv">-main</span> <span class="p">[]</span>
</span><span class='line'>  <span class="p">(</span><span class="k">let </span><span class="p">[</span><span class="nv">port</span> <span class="p">(</span><span class="nf">Integer/parseInt</span> <span class="p">(</span><span class="nb">get </span><span class="p">(</span><span class="nf">System/getenv</span><span class="p">)</span> <span class="s">&quot;PORT&quot;</span> <span class="s">&quot;8080&quot;</span><span class="p">))]</span>
</span><span class='line'>    <span class="p">(</span><span class="nf">run-jetty</span> <span class="p">(</span><span class="nf">fw1/start</span> <span class="ss">:application-key</span> <span class="s">&quot;easycalclj&quot;</span><span class="p">)</span>
</span><span class='line'>               <span class="p">{</span><span class="ss">:port</span> <span class="nv">port</span><span class="p">})))</span>
</span></code></pre></td></tr></table></div></figure>


<p>to</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='clojure'><span class='line'><span class="p">(</span><span class="kd">defn </span><span class="nv">-main</span> <span class="p">[]</span>
</span><span class='line'>  <span class="p">(</span><span class="k">let </span><span class="p">[</span><span class="nv">port</span> <span class="p">(</span><span class="nf">Integer/parseInt</span> <span class="p">(</span><span class="nb">get </span><span class="p">(</span><span class="nf">System/getenv</span><span class="p">)</span> <span class="s">&quot;PORT&quot;</span> <span class="s">&quot;8080&quot;</span><span class="p">))]</span>
</span><span class='line'>    <span class="p">(</span><span class="nf">run-jetty</span> <span class="p">(</span><span class="nf">fw1/start</span> <span class="ss">:application-key</span> <span class="s">&quot;easycalclj&quot;</span> <span class="ss">:reload-application-on-every-request</span> <span class="s">&quot;true&quot;</span><span class="p">)</span>
</span><span class='line'>               <span class="p">{</span><span class="ss">:port</span> <span class="nv">port</span><span class="p">})))</span>
</span></code></pre></td></tr></table></div></figure>


<p>Then I reloaded the app with &ldquo;?reload=secret&rdquo;, and the rc output for :reload-application-on-every-request didn&rsquo;t change. Hmmm &hellip;</p>

<p>After a bit of investigation, (I asked Sean again on Slack), I found that to reload changes to the configuration params, I needed to go to the terminal window where I started the app with <code>boot run</code>, shut the app down with <code>control-c</code>, and then start it up again with <code>PORT=8111 boot run</code>.</p>

<p>Checking the rc output in the console again, I saw that :reload-application-on-every-request was now true!</p>

<p>These were all small baby steps, but unless I take them, I won&rsquo;t learn.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Generating Accurate PDFs Using Cfdocument]]></title>
    <link href="http://dnando.github.io/blog/2015/07/01/generating-accurate-pdfs-using-cfdocument/"/>
    <updated>2015-07-01T23:55:41+02:00</updated>
    <id>http://dnando.github.io/blog/2015/07/01/generating-accurate-pdfs-using-cfdocument</id>
    <content type="html"><![CDATA[<p>I&rsquo;ve been developing a PDF, generated within a CFML application, that needs very accurate placement of chunks of text so that it can be printed on a standard form. It also needs to use a specified font, OCR-B, so that a line of text on the printed form can be machine scanned. I&rsquo;ve managed to get this working much better than expected on both ACF and Lucee, in a cross-compatible way, so I thought I&rsquo;d write everything up to remember the details down the line.</p>

<p>I was at first thinking I might be able to use the new cfhtmltopdf tag, but quickly dropped that idea: I couldn&rsquo;t get the PDF Service needed to use this tag to work on my Mac; it seems to be an enterprise only feature; and I wasn&rsquo;t so sure this approach would be compatible to use within Lucee. After looking around over the fence for a bit at potential solutions outside of CFML, nothing hit me as particularly appealing, so I dug into getting cfdocument to work as best I could. First the tag attributes.</p>

<h2>Attributes</h2>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>&lt;cfdocument format="pdf" pagetype="A4" orientation="portrait" fontEmbed="true" unit="cm" localUrl="true" saveAsName="#pdfFileName#" marginLeft="0" margintop="0" marginright="0" marginbottom="0"&gt;</span></code></pre></td></tr></table></div></figure>


<p>FontEmbed=&ldquo;true&rdquo; is essential so that anyone can print the PDF with the OCR-B code line correctly displayed, even if they don&rsquo;t have this font on their system. LocalUrl is set to true to easily pull in a logo image from the local file system. Note the margins are set to 0, because I&rsquo;m using a <code>&lt;div&gt;</code> tag to define the size of the page to control the tendency of the 2 different PDF generation engines used in ACF and Lucee to scale the layout, differently.</p>

<h2>Layout</h2>

<p>Nested directly within the cfdocument tag is a div tag that sets the page width, with <code>position:relative</code> so it remains within the page flow, and acts as the parent tag within which all layout divs that position text are nested <em>and proportionally scaled against</em>:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>&lt;div style="position:relative; top:0mm; left:0mm; width:210mm;"&gt;</span></code></pre></td></tr></table></div></figure>


<p>Then within that parent div tag are nested the various div tags, absolutely positioned, containing the blocks of text and images that make up the PDF content. Here are a few examples to demonstrate:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>&lt;div class="address"  style="position:absolute; top:13mm; left:100mm; "&gt;
</span><span class='line'>  #biller.address1# &middot #biller.zipcode# #biller.city#
</span><span class='line'>&lt;/div&gt;
</span><span class='line'>&lt;!--- client address ---&gt;
</span><span class='line'>&lt;div class="text" style="position:absolute; top:45mm; left:130mm"&gt;
</span><span class='line'>  #invoice.getClient().getName()#&lt;br&gt;
</span><span class='line'>  &lt;cfif len( trim( invoice.getClient().getAddress1() ) )&gt;#invoice.getClient().getAddress1()#&lt;br&gt;&lt;/cfif&gt;
</span><span class='line'>  &lt;cfif len( trim( invoice.getClient().getAddress2() ) )&gt;#invoice.getClient().getAddress2()#&lt;br&gt;&lt;/cfif&gt;
</span><span class='line'>  &lt;cfif len( trim( invoice.getClient().getAddress3() ) )&gt;#invoice.getClient().getAddress3()#&lt;br&gt;&lt;/cfif&gt;
</span><span class='line'>  #invoice.getClient().getCountryCode()#-#invoice.getClient().getZipCode()# #invoice.getClient().getCity()#
</span><span class='line'>&lt;/div&gt;</span></code></pre></td></tr></table></div></figure>


<p>What I really like about this approach is that each of the text blocks winds up very close to the top and left dimensions specified, and the ACF and Lucee outputs are nearly identical.</p>

<p>Without the parent div tag specifying the width, the results between the 2 engines are vastly different, and positioning the elements is much more a question of trial and error than simply entering the top and left positions as measured with a ruler (and perhaps tweaking them by a few milimeters if necessary). Also without the parent div tag to control how layout elements scale, changing the dimension of one absolutely positioned div within the PDF can easily alter the position or size of other divs, which can be very frustrating if you have 20 or 30 elements that all need to be precisely positioned.</p>

<p>Feel free to experiment with paddings or margins on the parent div if you want - I suspect it would work just as well (but haven&rsquo;t tried). For myself, I found it easier simply to measure placement from the edge of the page.</p>

<p>I haven&rsquo;t tried this myself, yet, but I have it from a reliable source that a parent div tag in the layout specifying the page width, as above, will fix page break issues if a table extends over more than one page.</p>

<h2>Fonts</h2>

<p>Specifying a font for a block of text is simple. You can use a CSS style declaration within a style block that is nested <em>within</em> the cfdocument tag, or you can place the font specification directly in a style attribute of an html tag like `<div> <span> <td>. Here are the styles I used for the above text blocks (and again, the style block must be nested within the cfdocument tag, or the PDF generator won&rsquo;t see it):</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>&lt;cfdocument format="pdf" pagetype="A4" orientation="portrait" fontEmbed="true" unit="cm" localUrl="true" saveAsName="#pdfFileName#" marginLeft="0" margintop="0" marginright="0" marginbottom="0"&gt;
</span><span class='line'>&lt;style&gt;
</span><span class='line'>  div.text {
</span><span class='line'>      font: 9pt Arial;
</span><span class='line'>      line-height: 13pt;
</span><span class='line'>  }
</span><span class='line'>
</span><span class='line'>  div.address {
</span><span class='line'>      font: 9pt Arial;
</span><span class='line'>      color: #033B7D;
</span><span class='line'>  }
</span><span class='line'>  ...
</span><span class='line'>&lt;/style&gt;
</span></code></pre></td></tr></table></div></figure>


<p>As of this writing, available CSS attributes remain limited. There is a list of CSS attributes that work in the ACF documentation for cfdocument, reproduced here:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
<span class='line-number'>73</span>
<span class='line-number'>74</span>
<span class='line-number'>75</span>
<span class='line-number'>76</span>
<span class='line-number'>77</span>
<span class='line-number'>78</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>The cfdocument tag supports the following CSS styles:
</span><span class='line'>
</span><span class='line'>background
</span><span class='line'>background-attachment
</span><span class='line'>background-color
</span><span class='line'>background-image
</span><span class='line'>background-position
</span><span class='line'>background-repeat
</span><span class='line'>border
</span><span class='line'>border-bottom
</span><span class='line'>border-bottom-color
</span><span class='line'>border-bottom-style (solid border only)
</span><span class='line'>border-bottom-width
</span><span class='line'>border-color
</span><span class='line'>border-left
</span><span class='line'>border-left-color
</span><span class='line'>border-left-style (solid border only)
</span><span class='line'>border-left-width
</span><span class='line'>border-right
</span><span class='line'>border-right-color
</span><span class='line'>border-right-style (solid border only)
</span><span class='line'>border-right-width
</span><span class='line'>border-spacing
</span><span class='line'>border-style (solid border only)
</span><span class='line'>border-top
</span><span class='line'>border-top-color
</span><span class='line'>border-top-style (solid border only)
</span><span class='line'>border-top-width
</span><span class='line'>border-width
</span><span class='line'>bottom
</span><span class='line'>clear
</span><span class='line'>clip
</span><span class='line'>color
</span><span class='line'>content (strings, counters only)
</span><span class='line'>counter-increment
</span><span class='line'>counter-reset
</span><span class='line'>cursor
</span><span class='line'>display
</span><span class='line'>float
</span><span class='line'>font
</span><span class='line'>font-family
</span><span class='line'>font-size
</span><span class='line'>font-style
</span><span class='line'>font-weight
</span><span class='line'>height
</span><span class='line'>left
</span><span class='line'>letter-spacing
</span><span class='line'>line-height
</span><span class='line'>list-style-type
</span><span class='line'>margin
</span><span class='line'>margin-bottom
</span><span class='line'>margin-left
</span><span class='line'>margin-right
</span><span class='line'>margin-top
</span><span class='line'>outline
</span><span class='line'>outline-color
</span><span class='line'>outline-style (solid, dotted, dashed only)
</span><span class='line'>outline-width
</span><span class='line'>padding
</span><span class='line'>padding-bottom
</span><span class='line'>padding-left
</span><span class='line'>padding-right
</span><span class='line'>padding-top
</span><span class='line'>page-break-after
</span><span class='line'>page-break-before
</span><span class='line'>page-break-inside
</span><span class='line'>position
</span><span class='line'>right
</span><span class='line'>text-align (left, right, and center)
</span><span class='line'>text-decoration
</span><span class='line'>text-indent
</span><span class='line'>top
</span><span class='line'>unicode-bidi
</span><span class='line'>vertical-align
</span><span class='line'>visibility
</span><span class='line'>white space (normal, nowrap only)
</span><span class='line'>width
</span><span class='line'>z-index</span></code></pre></td></tr></table></div></figure>


<h2>Custom fonts</h2>

<p>Scattered around the internet I found a variety of comments suggesting that getting a &ldquo;custom&rdquo; font to work within cfdocument isn&rsquo;t at all easy. Once you know how, it&rsquo;s actually fairly simple. For both ACF and Lucee, it&rsquo;s a question of getting the correct font file in the right place, with the right permissions, and restarting ACF/Lucee.</p>

<p>For ACF, log into the administrator and go to the Font Management Panel. There you will see all the fonts available to use in cfdocument &hellip; except that as of this writing, the OTF fonts won&rsquo;t work, even tho&#8217; the Font Management panel claims they are useable in PDFs. Unless something changes in the future, forget OTF fonts for cfdocument. I tried a bunch that already seemed to be recognized, none worked.</p>

<p>At the top of the font panel, you&rsquo;ll see a feature that allows you to add fonts &ldquo;Register New Font(s) with ColdFusion&rdquo;. I couldn&rsquo;t get this to work reliably - I think the validation routine on it isn&rsquo;t well designed. Go ahead and try if you like, but I found it easier to simply find a path to a font directory already recognized by ACF from the list of fonts installed ( I chose a directory with TTF files, just to be sure ), copy the TTF font files you want to use to that directory, change the owner/group and permissions to match the other font files in that directory (if necessary on your OS), restart ACF, log back into the administrator, go to the Font Management panel again and look for your fonts. In the left columns of the font table there are 3 names, Font Family, Font Face, Postscript Name. From my experience, using the font face name in your CSS specification should work. ( If not, try the other names - I saw a post suggesting that. )</p>

<p>To be clear, after you get the font installed in a directory that ACF recognizes as a font directory, one way or another, you&rsquo;ll need to find the name you need to use in your CSS. The file name often does not match the font name.</p>

<p>For Lucee, the process is different. ;-) Go to your Lucee installation directory, and within the /lib/ directory underneath it, find the fonts.jar file. Copy it to a working directory, rename the copy to fonts.zip and unzip it. ( A .jar file is essentially a ZIP file ). In the unzipped <em>fonts</em> directory that results, add your custom font files, again use only TTFs, and then open the pd4fonts.properties file you find in there and following the pattern you see, add the names of the fonts. In Lucee, you can choose the name, but to be cross compatible with ACF, I used the same name that ACF picked up from the font file. Here&rsquo;s what my pd4fonts.properties looked like after I added the OCR-B font I needed:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>#this is an autogenerated file. please remove manually any references to copyrighted fonts
</span><span class='line'>#Fri Apr 17 20:00:52 CEST 2009
</span><span class='line'>Arial=arial.ttf
</span><span class='line'>Arial\ Bold=arialbd.ttf
</span><span class='line'>Arial\ Bold\ Italic=arialbi.ttf
</span><span class='line'>Arial\ Italic=ariali.ttf
</span><span class='line'>Courier\ New=cour.ttf
</span><span class='line'>Courier\ New\ Bold=courbd.ttf
</span><span class='line'>Courier\ New\ Bold\ Italic=courbi.ttf
</span><span class='line'>Courier\ New\ Italic=couri.ttf
</span><span class='line'>Times\ New\ Roman=times.ttf
</span><span class='line'>Times\ New\ Roman\ Bold=timesbd.ttf
</span><span class='line'>Times\ New\ Roman\ Bold\ Italic=timesbi.ttf
</span><span class='line'>Times\ New\ Roman\ Italic=timesi.ttf
</span><span class='line'>OCRB=ob______.ttf
</span></code></pre></td></tr></table></div></figure>


<p>I added the last line, <code>OCRB=ob______.ttf</code>, following the pattern <code>FontFaceName=fontFileName.ttf</code>.</p>

<p>Note that spaces in the font name are escaped with backslashes, so those look like this <code>Font\ Face\ Name=fontFileName.ttf</code>.</p>

<p>Ok, save pd4fonts.properties when you&rsquo;re done, zip the fonts directory up into fonts.zip, rename it to fonts.jar, copy it back where it came from in the /lib/ directory, overwriting &hellip; no wait! Don&rsquo;t just overwrite the old fonts.jar. Keep a copy of it, just in case &hellip; replace the old fonts.jar with the new fonts.jar, change the owner/group permissions to match the old file, and then restart Lucee.</p>

<p>The name to use in your CSS for the font is the name you placed in the pd4fonts.properties file.</p>

<p>Of course, the above approach for Lucee ( 4.5 ) might certainly change in the future. But for now, it works like this.</p>

<p>A big thanks to <a href="http://blog.hnat.de/post.cfm/schriftarten-zu-railo-hinzufugen">Michael Hnat</a> for pointing me in the right direction regarding Lucee with his very helpful blog post.</p>

<h2>Images</h2>

<p>There is a logo image at the top of this PDF that was scaling up when rendered in Lucee in a way that caused it to be misplaced. The top left position was correct, but it was about 50% too big, pixelated, and overran other text. After a bunch of reading that indicated modifying the image print size or resolution would not help, I tried adding a css style declaration to the image that specified a size in mm, and it worked! Thanks to faxi05 for the suggestion.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>&lt;img src="logos/imageName.png" style="width:78mm; height:14mm" /&gt;
</span></code></pre></td></tr></table></div></figure>


<p>&hellip; and it&rsquo;s cross compatible with ACF!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[CFML Queries in Script]]></title>
    <link href="http://dnando.github.io/blog/2015/06/16/cfml-queries-in-script/"/>
    <updated>2015-06-16T18:39:54+02:00</updated>
    <id>http://dnando.github.io/blog/2015/06/16/cfml-queries-in-script</id>
    <content type="html"><![CDATA[<p>Recently, I needed to write a somewhat complex query with a conditional where clause. I resisted the urge to revert to the cfquery tag for this sort of thing, and came up with the following using queryExecute(), submitted as an example without explanation. This approach works on both ACF and Lucee.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>public query function findRawAudit( string entity, numeric userId, date dateFrom, date dateTo, numeric timeZoneOffset ) {
</span><span class='line'>  var newLine = CHR(13) & CHR(10);
</span><span class='line'>  var params = {};
</span><span class='line'>  var sql = "
</span><span class='line'>      select a.entity, a.entityId, a.timestamp, a.transaction, a.attribute, a.value as previousValue, u.name as username, null as currentValue, null as auditName, null as asql
</span><span class='line'>      from Audit a inner join User u
</span><span class='line'>      on a.userId = u.userId
</span><span class='line'>      where 0=0
</span><span class='line'>  ";
</span><span class='line'>
</span><span class='line'>  if ( structKeyExists(arguments, 'entity') and len( arguments.entity ) ) {
</span><span class='line'>      sql &= newLine & "and entity = :entity";
</span><span class='line'>      structInsert(params, "entity", { value: arguments.entity, cfsqltype: "cf_sql_varchar" } );
</span><span class='line'>  }
</span><span class='line'>
</span><span class='line'>  if ( structKeyExists(arguments, 'userId') ) {
</span><span class='line'>      sql &= newLine & "and a.userId = :userId";
</span><span class='line'>      structInsert(params, "userId", { value: arguments.userId, cfsqltype: "cf_sql_integer" } );
</span><span class='line'>  }
</span><span class='line'>
</span><span class='line'>  if ( structKeyExists(arguments, 'dateFrom') ) {
</span><span class='line'>      sql &= newLine & "and timestamp &gt; :dateFrom";
</span><span class='line'>      //  adjust dateFrom to account for time zone difference between server and user
</span><span class='line'>      var dateFromUTC = DateAdd( 'h', -arguments.timeZoneOffset, arguments.dateFrom );
</span><span class='line'>      structInsert(params, "dateFrom", { value: arguments.dateFrom, cfsqltype: "cf_sql_timestamp" } );
</span><span class='line'>  }
</span><span class='line'>
</span><span class='line'>  if ( structKeyExists(arguments, 'dateTo') ) {
</span><span class='line'>      sql &= newLine & "and timestamp &lt; :dateTo";
</span><span class='line'>      //  adjust dateFrom to account for time zone difference between server and user
</span><span class='line'>      var dateToUTC = DateAdd( 'h', -arguments.timeZoneOffset, arguments.dateTo );
</span><span class='line'>      // we add a day to dateTo to arrive at an effectiveEndDateTime, namely midnight of the endDate
</span><span class='line'>      // so that the endDate is inclusive, as users would very likely expect
</span><span class='line'>      dateToUTC = dateAdd( 'd', 1, dateToUTC );
</span><span class='line'>      // stdout.println( "dateToUTC : #dateToUTC #" );
</span><span class='line'>      structInsert(params, "dateTo", { value: dateToUTC, cfsqltype: "cf_sql_timestamp" } );
</span><span class='line'>  }
</span><span class='line'>
</span><span class='line'>  sql &= newLine & "and a.attribute != 'version' ";
</span><span class='line'>
</span><span class='line'>  sql &= newLine & "and a.attribute != 'lastEdited' ";
</span><span class='line'>
</span><span class='line'>  sql &= newLine & "and a.attribute != 'userId' ";
</span><span class='line'>
</span><span class='line'>  sql &= newLine & "order by a.timestamp desc, a.transaction";
</span><span class='line'>
</span><span class='line'>  return queryExecute( sql, params );
</span><span class='line'>}
</span></code></pre></td></tr></table></div></figure>


<p>Thanks to Igal Sapir for helping me work this out!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Debugging Technique CFML Development]]></title>
    <link href="http://dnando.github.io/blog/2015/06/16/debugging-technique-cfml-development/"/>
    <updated>2015-06-16T17:01:52+02:00</updated>
    <id>http://dnando.github.io/blog/2015/06/16/debugging-technique-cfml-development</id>
    <content type="html"><![CDATA[<p>I learned a debugging techique from Sean Corfield recently that I think is well worth sharing more widely. It works just as well for Lucee, Railo or Adobe Coldfusion. Here&rsquo;s what he reccommends:</p>

<blockquote><p>For ease of debugging any problems that may occur, I strongly recommend you always keep a Terminal / Console window open containing a tail of the console output from your CFML server. If you’re using Lucee or a Railo installation based on Tomcat, you’ll want to find the catalina.out log file and tail that. If you’re using ColdFusion 11, even tho’ it is notionally based on Tomcat, it’s completely non-standard and you’ll want to tail cfusion/logs/coldfusion-out.log.</p><footer><strong>Sean Corfield</strong> <cite><a href='https://framework-one.github.io/documentation/3.5/cfml-and-clojure.html'>framework-one.github.io/3.5/&hellip;</a></cite></footer></blockquote>


<p>To &ldquo;tail&rdquo;, in this case, means to show the newly added contents of a log file in real time. To get this to work, I open Terminal on my Mac and issue the following commands:</p>

<p> &hellip; for my local CF11 install:</p>

<pre><code class="`"> tail -f /Applications/ColdFusion11/cfusion/logs/coldfusion-out.log
</code></pre>

<p>  and for my local Lucee install:</p>

<pre><code class="``">  tail -f ~/tomcat/logs/catalina.out
</code></pre>

<p>  You will of course need to change those paths to match the directory under which your applications are installed.</p>

<p>  To get out of tail mode and back to the command line, hit CTRL-C.</p>

<p>  What I see when I do this is the last 10 lines of the log file, to start with. Anytime an additional line is added to the log file, it immediately appears in the console display in real time.</p>

<p>  Now what I can do in my code is send output to these log files. An example should explain it sufficiently. I just used this technique to debug a the following service function, where I wanted to ensure that dateTo UTC was being set as needed:</p>

<pre><code class="``">    public query function findRawAudit( string entity, numeric userId, date dateFrom, date dateTo, numeric timeZoneOffset ) {
        var stdout = createObject( "java", "java.lang.System" ).out;

        ...

        if ( structKeyExists(arguments, 'dateTo') ) {
            sql &amp;= "#newLine#" &amp; "and timestamp &lt; :dateTo";
            //  adjust dateFrom to account for time zone difference between server and user
            var dateToUTC = DateAdd( 'h', -arguments.timeZoneOffset, arguments.dateTo );
            // we add a day to dateTo to arrive at an effectiveEndDateTime, namely midnight of the endDate
            // so that the endDate is inclusive, as users would very likely expect
            dateToUTC = dateAdd( 'd', 1, dateToUTC );
            stdout.println( "dateToUTC : #dateToUTC #" );
            structInsert(params, "dateTo", { value: dateToUTC, cfsqltype: "cf_sql_timestamp" } );
        }
        ...
    }
</code></pre>

<p>Note the lines <code>var stdout = createObject( "java", "java.lang.System" ).out;</code> and <code>stdout.println( "dateToUTC : #dateToUTC #" );</code> which creates an instance of java.lang.System.out and prints a line to the log file.</p>

<p>Immediately upon running this code <code>dateToUTC : {ts '2015-06-16 22:00:00'}</code> appeared in my tail output, which is what I expected. The bug was elsewhere, . I find this very useful. It&rsquo;s simple and effective, and it works in the same way across ACF, Lucee and Railo. I don&rsquo;t have to fiddle around with an admin setting to turn on trace output, check if trace output is enabled, remember the syntax used for cftrace / trace, and I can use it directly on a production server in a pinch in case of need.</p>

<p>Of course, you can tail any log file necessary, or use WriteLog() if you prefer. WriteLog() does the exact same thing as stdout.println(), and it&rsquo;s easier to remember. So taking the above example, I could also use</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>WriteLog( "dateToUTC : #dateToUTC #" );</span></code></pre></td></tr></table></div></figure>


<p>or</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>WriteLog( "dateToUTC : "  & dateToUTC );</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Nginx Tweaks Using Proxy_redirect and Rewrite Directives]]></title>
    <link href="http://dnando.github.io/blog/2015/01/15/nginx-tweaks-using-proxy-redirect-and-rewrite-directives/"/>
    <updated>2015-01-15T13:05:56+01:00</updated>
    <id>http://dnando.github.io/blog/2015/01/15/nginx-tweaks-using-proxy-redirect-and-rewrite-directives</id>
    <content type="html"><![CDATA[<p>I ran across a few niggles in setting up ColdFusion and Lucee behind a Nginx web server, and thought it might be helpful to document the solutions I came to.</p>

<p>The first small problem was that when users logged out of an FW/1 app, they would encounter a blank screen rather than being redirected to the login screen. Further investigation, using Chrome&rsquo;s Developer Tools Network panel, showed that Nginx was returning a blank location response header on the redirect to the login screen. I&rsquo;m still not exactly clear why this is occuring - other 302 redirects within the app work as expected, but the solution I came up with worked like a charm. All I needed to do was use the proxy_redirect directive alongside the proxy_pass directive, redirecting a blank location to the root location, like so:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>proxy_redirect '' /;</span></code></pre></td></tr></table></div></figure>


<p>I was happy that it worked as I guessed it would. In any case, proxy_redirect is a handy directive to have in your toolkit.</p>

<p>In another case, a url pointing to a directory without a trailing slash would result in a 404 error behind Nginx. This url was being processed using the proxy_pass directive. For example, <a href="http://domain.com/directory">http://domain.com/directory</a> would result in a 404 while <a href="http://domain.com/directory/">http://domain.com/directory/</a> works, locating the default index.cfm template under /directory.</p>

<p>Since I had only one url to adjust, the solution was rather simple:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>rewrite ^/directory$ /directory/ redirect;</span></code></pre></td></tr></table></div></figure>


<p>There are several trailing slash issues using Nginx that need to be taken into account. Search for &ldquo;nginx trailing slash&rdquo; to get a handle on them.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[UTF-8 Extended Character File Names in Railo / Lucee]]></title>
    <link href="http://dnando.github.io/blog/2015/01/15/utf-8-extended-character-file-names-in-railo/"/>
    <updated>2015-01-15T13:04:08+01:00</updated>
    <id>http://dnando.github.io/blog/2015/01/15/utf-8-extended-character-file-names-in-railo</id>
    <content type="html"><![CDATA[<p>I ran into an issue when porting an application from ACF9 to Railo 4.2 where Railo could not find files that use extented characters in file names, namely letters with accents, umlauts and such. The  request would error out with a template not found error. I briefly considered renaming a bunch of files that my clients had uploaded, building a system to filter out and rename all files with extended characters in them, but decided there has to be a better way. And indeed there is!</p>

<p>Specifically on a Linux or Mac OS, open setenv.sh, which should be located under <railo install directory>/tomcat/bin/ and add the following line at the end of the file:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>export LC_CTYPE="en_US.UTF-8"</span></code></pre></td></tr></table></div></figure>


<p>Restart Railo, and you should be good to go!</p>

<p>The background here is that the default file encoding system used in tomcat isn&rsquo;t utf-8. There should be Tomcat documentation available for a Windows install somewhere. Feel free to add a comment if you happen to know how to set the file system encoding on Windows.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Testing Nginx Config Directives]]></title>
    <link href="http://dnando.github.io/blog/2015/01/09/testing-nginx-config-directives/"/>
    <updated>2015-01-09T11:50:19+01:00</updated>
    <id>http://dnando.github.io/blog/2015/01/09/testing-nginx-config-directives</id>
    <content type="html"><![CDATA[<p>After setting up both Lucee and ColdFusion web apps behind Nginx, I wanted to prove to myself that the configuration was functioning how I thought it should. The apps worked, but there were several issues I was concerned about.</p>

<p>Here&rsquo;s the configuration I wanted to test:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>upstream    cf_servers {
</span><span class='line'>  server          127.0.0.1:8500;
</span><span class='line'>  keepalive       32; ## number of upstream connections to keep alive
</span><span class='line'>}
</span><span class='line'>
</span><span class='line'>server {
</span><span class='line'>  server_name     domain.com;
</span><span class='line'>  listen          80;
</span><span class='line'>  root            /var/sites/domain-com;
</span><span class='line'>
</span><span class='line'>  location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
</span><span class='line'>      add_header Pragma public;
</span><span class='line'>      add_header Cache-Control "public, must-revalidate, proxy-revalidate";
</span><span class='line'>      gzip  on;
</span><span class='line'>      gzip_http_version 1.0;
</span><span class='line'>      gzip_vary on;
</span><span class='line'>      gzip_comp_level 6;
</span><span class='line'>      gzip_proxied any;
</span><span class='line'>      gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
</span><span class='line'>      gzip_buffers 16 8k;
</span><span class='line'>      # Disable gzip for certain browsers.
</span><span class='line'>      gzip_disable ~@~\MSIE [1-6].(?!.*SV1)~@~];
</span><span class='line'>      expires modified +90d;
</span><span class='line'>  }
</span><span class='line'>
</span><span class='line'>  location / {
</span><span class='line'>      proxy_pass  http://cf_servers/domain.com/;
</span><span class='line'>      proxy_redirect '' /;
</span><span class='line'>      proxy_http_version  1.1;
</span><span class='line'>      proxy_set_header    Connection "";
</span><span class='line'>      proxy_set_header    Host                $host;
</span><span class='line'>      proxy_set_header    X-Forwarded-Host    $host;
</span><span class='line'>      proxy_set_header    X-Forwarded-Server  $host;
</span><span class='line'>      proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;     ## CGI.REMOTE_ADDR
</span><span class='line'>      proxy_set_header    X-Forwarded-Proto   $scheme;                        ## CGI.SERVER_PORT_SECURE
</span><span class='line'>      proxy_set_header    X-Real-IP           $remote_addr;
</span><span class='line'>      expires             epoch;
</span><span class='line'>  }
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>First off, I had a doubt regarding how Nginx was selecting which location directive to use for each file requested from the documentation I&rsquo;ve read. What I wanted to ensure is that Nginx was serving the static files, and proxying only the CFML files.</p>

<p>A deeper issue here is whether or not the proxy_pass directive contains a URI. If it does, you can&rsquo;t use a regex to filter a location for CFML files only. A few examples will explain this better:</p>

<p>This configuration contains a URI in the proxy_pass directive, namely <strong>/domain.com/</strong>. You cannot use a regex in the location directive to filter the request, so in my case, the location directive simply had to point to the root ( recursively in the way Nginx works, so essentially this directive will process any file under the root ).</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>location / {
</span><span class='line'>  proxy_pass  http://cf_servers/domain.com/;
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>This configuration also contains a URI in the proxy_pass directive, the trailing slash. Again, no regex in the location is possible.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>location / {
</span><span class='line'>  proxy_pass  http://cf_servers/;
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>This config does not have a URI component in the proxy_pass directive, no trailing slash and no subdirectory are present here. In this case, we CAN apply a regex filter to pass only those files we want to our application server.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>location ~ \.(cfm|cfc|cfml)$ {
</span><span class='line'>  proxy_pass  http://cf_servers;
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>The tradeoff here is that if we use a filter to ensure only CFML files are pass to our app server, then we need to additionally configure each virtual host in Tomcat&rsquo;s server.xml ( assuming multiple hosts per server ) so that Tomcat can locate the files.</p>

<p>If you&rsquo;d rather configure each server only in Nginx, as I did with my CF11 install, then another approach might be to use a regex to filter all your static files. Hence:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
</span><span class='line'>  ...
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>With the essential background information out of the way, the question that arose was this. Is Nginx actually serving the static files, as I hoped, or are they all being passed to ColdFusion? The documention I found here and there seemed contradictory.</p>

<p>Here&rsquo;s one way to test this using curl on the command line to fetch the response headers, with the output I got using the above settings:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ curl -X GET -I http://domain.com/index.cfm
</span><span class='line'>HTTP/1.1 200 OK
</span><span class='line'>Server: nginx
</span><span class='line'>Date: Thu, 08 Jan 2015 21:48:26 GMT
</span><span class='line'>Content-Type: text/html;charset=UTF-8
</span><span class='line'>Transfer-Encoding: chunked
</span><span class='line'>Connection: keep-alive
</span><span class='line'>Set-Cookie: CFID=20071; Expires=Sat, 31-Dec-2044 21:48:26 GMT; Path=/; HttpOnly
</span><span class='line'>Set-Cookie: CFTOKEN=8ff3e8f3dde25bcd-F33324A1-AEBC-7E8D-FEEEB610DD6412E7; Expires=Sat, 31-Dec-2044 21:48:26 GMT; Path=/; HttpOnly
</span><span class='line'>Cache-Control: no-cache
</span><span class='line'>Pragma: no-cache
</span><span class='line'>Expires: Thu, 01 Jan 1970 00:00:01 GMT
</span><span class='line'>X-Frame-Options: SAMEORIGIN
</span><span class='line'>X-Content-Type-Options: nosniff
</span><span class='line'>X-XSS-Protection: 1; mode=block
</span><span class='line'>
</span><span class='line'>$ curl -X GET -I http://domain.com/images/some_logo.gif
</span><span class='line'>HTTP/1.1 200 OK
</span><span class='line'>Server: nginx
</span><span class='line'>Date: Thu, 08 Jan 2015 21:50:12 GMT
</span><span class='line'>Content-Type: image/gif
</span><span class='line'>Content-Length: 10220
</span><span class='line'>Last-Modified: Thu, 11 Dec 2014 17:18:36 GMT
</span><span class='line'>Connection: keep-alive
</span><span class='line'>ETag: "5489d1ec-27ec"
</span><span class='line'>Expires: Wed, 11 Mar 2015 17:18:36 GMT
</span><span class='line'>Cache-Control: max-age=5340504
</span><span class='line'>Pragma: public
</span><span class='line'>Cache-Control: public, must-revalidate, proxy-revalidate
</span><span class='line'>Accept-Ranges: bytes
</span></code></pre></td></tr></table></div></figure>


<p>See the difference? The image is being cached on the browser and the headers are being set as per the static file location block, while index.cfm isn&rsquo;t being cached. The <code>expires epoch;</code> directive tells the browser to set the expires date to 01 Jan 1970, a date in the past means don&rsquo;t cache this, while the <code>expires modified +90d;</code> tells the browser to set the expires date 90 days from the Last-Modified date.</p>

<p>Another way to see these headers is via Developer Tools in Chrome ( or a comparable tool in any other modern browser ). Open a Dev Tools window while browsing the web page you&rsquo;d like to check, refresh the page, go to the Network tab, and click on any file to see the headers. This approach will give you a better overview of how your Nginx settings are serving and caching each file involved in an http request.</p>

<p>After some thought and study, I decided to change my initial approach to caching static content to one that will help guarentee any content that I modify is served fresh from the server rather that stale from the cache. Here&rsquo;s what I came up with, for now, for a particular business application that I am still developing:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
</span><span class='line'>  add_header Pragma public;
</span><span class='line'>  add_header Cache-Control "public, must-revalidate, proxy-revalidate, max-age=86400";
</span><span class='line'>  etag on;
</span><span class='line'>  gzip  off;
</span><span class='line'>    expires +1d;
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>The users who access this site every day will only need to re-download static content once a day, an additional second or two once a day won&rsquo;t hurt them. In the version of Nginx I&rsquo;m currently using, enabling gzip disables etags. For now, I&rsquo;d rather have etag enabled, so I&rsquo;m disabling gzip for static content, but leaving it enabled for the dynamically generated content that is returned from the proxied app server.</p>

<p>Resources for further reading:</p>

<ol>
<li><a href="https://www.mnot.net/cache_docs/">https://www.mnot.net/cache_docs/</a></li>
<li><a href="http://en.wikipedia.org/wiki/HTTP_ETag">http://en.wikipedia.org/wiki/HTTP_ETag</a></li>
<li><a href="http://stackoverflow.com/questions/499966/etag-vs-header-expires">http://stackoverflow.com/questions/499966/etag-vs-header-expires</a></li>
<li><a href="http://stackoverflow.com/questions/5799906/what-s-the-difference-between-expires-and-cache-control-headers">http://stackoverflow.com/questions/5799906/what-s-the-difference-between-expires-and-cache-control-headers</a></li>
<li><a href="https://www.owasp.org/index.php/List_of_useful_HTTP_headers">https://www.owasp.org/index.php/List_of_useful_HTTP_headers</a></li>
<li><a href="http://cyh.herokuapp.com/cyh">http://cyh.herokuapp.com/cyh</a></li>
</ol>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Getting Railo I/O Functions to Work With Utf-8 File Names]]></title>
    <link href="http://dnando.github.io/blog/2015/01/08/railo-i-o-functions-in-utf-8/"/>
    <updated>2015-01-08T17:36:40+01:00</updated>
    <id>http://dnando.github.io/blog/2015/01/08/railo-i-o-functions-in-utf-8</id>
    <content type="html"><![CDATA[<p>I ran into an issue moving an application from CF9 to Railo 4.2 with file names that use extended utf-8 characters, such as Banner_Küste.jpg for example. The extended characters weren&rsquo;t being correctly interpreted, rendered as ��. Hence in any file operation, Railo couldn&rsquo;t find them, and the application would error out. Railo was also unable to render these images because they were not being found on the file system.</p>

<p>Since I&rsquo;m in Switzerland, and all my clients use extended characters, in French, German and Italian, I needed a solution. Telling them not to use extended characters in their file names wasn&rsquo;t palatable. It seemed particularly odd to me that Railo didn&rsquo;t play well here, since its primary developers are European.</p>

<p>Adjusting the Charset settings panel to ensure UTF-8 was used didn&rsquo;t help, but I found a simple solution in a <a href="https://issues.jboss.org/browse/RAILO-3090">bug report that Michel Gallant filed</a> that did the trick for me.</p>

<p>As per Michel comment in the bug report, I added the following line to the end of the tomcat setenv.sh script, which you will find at <railo install path>/tomcat/bin/setenv.sh :</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>export LC_CTYPE="en_US.UTF-8"</span></code></pre></td></tr></table></div></figure>


<p>and then I restarted Railo to pick up the change. I was delighted it worked. Thanks very much Michel!</p>

<p>This server&rsquo;s OS is Linux CentOS 7, and the above should work for any other Linux install as well. I&rsquo;m not sure where this might be set on a Windows server, but it is the same file used to adjust the Tomcat/Java memory settings ( -Xms512m -Xmx1024m -XX:MaxPermSize=256m ).</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Cannot Find Template CF11]]></title>
    <link href="http://dnando.github.io/blog/2015/01/08/cannot-find-template-cf11/"/>
    <updated>2015-01-08T10:05:36+01:00</updated>
    <id>http://dnando.github.io/blog/2015/01/08/cannot-find-template-cf11</id>
    <content type="html"><![CDATA[<p>Charlie Arehart has a now famous series of talks he presents titled &ldquo;Hidden Gems in ColdFusion xx&rdquo;. I&rsquo;m not sure what the opposite of a &ldquo;gem&rdquo; is. For now, a turd will do. If someone has a better suggestion, let me know.</p>

<h2>Hidden Turd in ColdFusion 11</h2>

<p>I&rsquo;ve recently moved a production application from CF9 to CF11. I didn&rsquo;t catch all the compatibility issues in my testing, so users have been reporting minor bugs and I&rsquo;ve been fixing them and the uploading them to the CF11 server as necessary. Yesterday, late in the afternoon, I uploaded a template with a very minor change to it and got a cannot find template error. Actually it was a cannot find component error. After repeated attempts to replace the file, and careful double checking (it was in the right place, I could find and read the file via the command line) to try and work around it, I changed another template. Now CF couldn&rsquo;t find that one either. Huh???</p>

<p>The bigger problem was that it broke the application - it was no longer possible to login. #$%&amp;@!!!!</p>

<p>Nothing I did for the next 6 hours helped. The template was obviously in the right location. It simply didn&rsquo;t make any sense. I ran through permissions issues, hard disk failure issues, considered cloning the server, wondered how the fact that I had just installed SSL certs might have somehow caused CF to not find a template I had just changed, bizarre as that might seem, thought about updating the JVM or removing the certs from the java keystore, looked at permission issues again, checked and rechecked which user CF was running under, the group it was assigned to, considered whether the server had been hacked somehow, planned how I was going to roll back the entire application to CF9 and shift the data that had changed, thought about switching to Lucee and telling my clients they simply have to bear with me while I work through some compatibility issues. I had to get the server back up by this morning. My clients run their businesses with it. I tried yelling at the server through my monitor. &ldquo;Bloody well just look, open your eyes, dammit!! It&rsquo;s right there in front of your nose!!!&rdquo; Didn&rsquo;t help.</p>

<p>In the end, I got lucky with my Google foo and found someone else who has run into this issue. Turns out the problem was an option in ColdFusion administrator. The &ldquo;Save class files&rdquo; option was checked by default on install. I didn&rsquo;t change any settings in the Caching section on install, assuming that the defaults would be &ldquo;safe&rdquo;, they would not cache anything in a way that would make the server &ldquo;un-updateable&rdquo;. I was wrong. The defaults can easily break your application, and leave you no clue at all as to why.</p>

<p>I needed to uncheck it, restart CF, and then the app worked again.</p>

<p>The text next to the checkbox says this:</p>

<p><em>When you select this option, the class files generated by ColdFusion are saved to disk for reuse after the server restarts. Adobe recommends this for production systems. During development, Adobe recommends that you do not select this option.</em></p>

<p>It should say:</p>

<p><em>When you select this option, any changes you make to your files may break your application. The error messages you will get will give you no clue at all what the underlying cause is - namely this checkbox enabling the poorly designed functionality behind it.</em></p>

<p>I expect options for production systems to make CF more performant, stable or secure. Options that potentially take production applications down with no warning, rhyme or reason are neither expected nor welcome. Given that I now am fully aware of the consequences of checking this box, I would recommend leaving it always unchecked. Otherwise, every time I need to make a minor change to a production server I have to remember to uncheck it, reboot the server, make my change, check it again, and perhaps reboot the server again. How does that improve the experience of my users? And if I somehow forget this arcane procedure, whatever it actually is, and take the app down again with a minor change, perhaps for hours and even days, it&rsquo;s even worse!</p>

<p>Someone will invariably blame me. I should have known this - and remembered it. Well, maybe this blog post will help both me and perhaps others in this regard. That said, I think the fact that this option causes CF to break production applications is a <a href="https://bugbase.adobe.com/index.cfm?event=bug&amp;id=3917793">bug.</a> Feel free to vote for it if you agree.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Using Nginx With ColdFusion or Lucee]]></title>
    <link href="http://dnando.github.io/blog/2015/01/05/advantages-of-nginx/"/>
    <updated>2015-01-05T20:26:47+01:00</updated>
    <id>http://dnando.github.io/blog/2015/01/05/advantages-of-nginx</id>
    <content type="html"><![CDATA[<p>Over the past few weeks I&rsquo;ve installed and experimented with the Nginx webserver. At this point it seems to me there are some significant advantages to using Nginx over Apache, advantages that aren&rsquo;t often highlighted, specifically when using either ColdFusion or Lucee as your application server.</p>

<p>First up, it was very easy to install, start, and enable so that it always starts at boot time. These are the commands I used for CentOS 7, adapt as necessary for your operating system:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
</span><span class='line'>yum install nginx
</span><span class='line'>systemctl start nginx.service
</span><span class='line'>systemctl enable nginx.service</span></code></pre></td></tr></table></div></figure>


<p>I could then browse to the server ip and see the Nginx welcome page.</p>

<p>It then took me a bit of time for me to grok how the configuration setup works. However, compared to Apache&rsquo;s massive conf file, the fact that I could easily see the entire main configuration in a single screen immediately put me at ease. Basically, Nginx has a main config file, located at /etc/nginx/nginx.conf on my CentOS install, which can be extended with includes. Before I started messing with it, the main conf file looked something like this:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>user  nginx;
</span><span class='line'>worker_processes  1;
</span><span class='line'>error_log  /var/log/nginx/error.log warn;
</span><span class='line'>pid        /var/run/nginx.pid;
</span><span class='line'>
</span><span class='line'>events {
</span><span class='line'>    worker_connections  1024;
</span><span class='line'>}
</span><span class='line'>
</span><span class='line'>http {
</span><span class='line'>    include       /etc/nginx/mime.types;
</span><span class='line'>    default_type  application/octet-stream;
</span><span class='line'>
</span><span class='line'>    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
</span><span class='line'>                      '$status $body_bytes_sent "$http_referer" '
</span><span class='line'>                      '"$http_user_agent" "$http_x_forwarded_for"';
</span><span class='line'>
</span><span class='line'>    access_log  /var/log/nginx/access.log  main;
</span><span class='line'>
</span><span class='line'>    include /etc/nginx/conf.d/*.conf;
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>&hellip; and the default site conf file, which is picked up by the include at the bottom of the main conf file above, looked like this:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>server {
</span><span class='line'>    listen       80;
</span><span class='line'>    server_name  localhost;
</span><span class='line'>
</span><span class='line'>    #charset koi8-r;
</span><span class='line'>    #access_log  /var/log/nginx/log/host.access.log  main;
</span><span class='line'>
</span><span class='line'>    location / {
</span><span class='line'>        root   /usr/share/nginx/html;
</span><span class='line'>        index  index.html index.htm;
</span><span class='line'>    }
</span><span class='line'>
</span><span class='line'>    #error_page  404              /404.html;
</span><span class='line'>
</span><span class='line'>    # redirect server error pages to the static page /50x.html
</span><span class='line'>    #
</span><span class='line'>    error_page   500 502 503 504  /50x.html;
</span><span class='line'>    location = /50x.html {
</span><span class='line'>        root   /usr/share/nginx/html;
</span><span class='line'>    }
</span><span class='line'>
</span><span class='line'>    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
</span><span class='line'>    #
</span><span class='line'>    #location ~ \.php$ {
</span><span class='line'>    #    proxy_pass   http://127.0.0.1;
</span><span class='line'>    #}
</span><span class='line'>
</span><span class='line'>    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
</span><span class='line'>    #
</span><span class='line'>    #location ~ \.php$ {
</span><span class='line'>    #    root           html;
</span><span class='line'>    #    fastcgi_pass   127.0.0.1:9000;
</span><span class='line'>    #    fastcgi_index  index.php;
</span><span class='line'>    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
</span><span class='line'>    #    include        fastcgi_params;
</span><span class='line'>    #}
</span><span class='line'>
</span><span class='line'>    # deny access to .htaccess files, if Apache's document root
</span><span class='line'>    # concurs with nginx's one
</span><span class='line'>    #
</span><span class='line'>    #location ~ /\.ht {
</span><span class='line'>    #    deny  all;
</span><span class='line'>    #}
</span><span class='line'>}
</span></code></pre></td></tr></table></div></figure>


<p>Note the asterik syntax in the include at the bottom of the main conf file:
<code>include /etc/nginx/conf.d/*.conf;</code>.
Effectively, any .conf file you drop in that directory becomes part of the configuration ( specifically of the http{} block ).</p>

<p>Note also that there are semicolons at the end of every setting. If you see errors when reloading conf files using the command <code>nginx -s reload</code>, look for missing semicolons.</p>

<p>In a nutshell, Nginx&rsquo;s configuration is a simple nested structure, like this:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>nginx global settings
</span><span class='line'>
</span><span class='line'>events {
</span><span class='line'>
</span><span class='line'>}
</span><span class='line'>
</span><span class='line'>http {
</span><span class='line'>
</span><span class='line'>  server {
</span><span class='line'>      listen 80;   # port to listen on
</span><span class='line'>      server_name domain.com *.domain.com domain.net *.domain.net;
</span><span class='line'>      root /var/www/domain;  #absolute path to root directory of website files
</span><span class='line'>
</span><span class='line'>      location /downloads {
</span><span class='line'>          # specific settings for a file system location relative to the root
</span><span class='line'>          # which in this example would be /var/www/domain/downloads
</span><span class='line'>      }
</span><span class='line'>
</span><span class='line'>      location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
</span><span class='line'>          # specific settings for files ending in suffixes .ico, .css, .js, gif, etc
</span><span class='line'>          # defined using a regex, under the root directory defined in the server block
</span><span class='line'>      }
</span><span class='line'>
</span><span class='line'>      location / {
</span><span class='line'>          # general settings for all files under/var/www/domain in this example
</span><span class='line'>          # in this example only for those files that do not match the more specific location directives above
</span><span class='line'>      }
</span><span class='line'>
</span><span class='line'>      location = / {
</span><span class='line'>          # this directive is triggered when only the domain is specified in the url
</span><span class='line'>          # in this example for the url http://example.com
</span><span class='line'>      }
</span><span class='line'>
</span><span class='line'>  }
</span><span class='line'>
</span><span class='line'>  server {
</span><span class='line'>      # configuration for another virtual server,
</span><span class='line'>      # defined by a unique server_name or listen directive
</span><span class='line'>  }
</span><span class='line'>
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>Each server block defines a virtual server, similar to a virtual host in Apache. The <code>server_name</code> directive takes a space delimited list of domains, which can include an asterisk as a wildcard character, replacing the first or last part of a name, to specify for instance any subdomain or TLD. Note that a directive like <code>server_name example.com *.example.com</code> can be also written with the shorthand expression <code>server_name .example.com</code></p>

<p>Nginx selects and processes locations within a server block using the most specific match, with regexes taking precedence, followed by the longest matching prefix. So in the above example, Nginx would process a file named myImage.jpg using the second location directive, a file in the downloads directory named myInfo.pdf using the first location directive, a file named index.htm ( or index.cfm ) using the third location directive, and a request to the root of the domain, say to <a href="http://domain.com/,">http://domain.com/,</a> with the last location directive, where the addition of the &ldquo;=&rdquo; sign specifies an exact match.</p>

<p>See the <a href="http://nginx.com/resources/admin-guide/web-server/">Nginx Web Server configuration guide</a> for more details.</p>

<p>To use Nginx with either ColdFusion or Lucee, the <code>proxy_pass</code> directive is used, as in the following example:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>server {
</span><span class='line'>  listen 80;   # port to listen on
</span><span class='line'>  server_name domain.com *.domain.com domain.net *.domain.net;
</span><span class='line'>  root /var/www/domain;  #absolute path to root directory of website files
</span><span class='line'>
</span><span class='line'>  location /downloads {
</span><span class='line'>      # specific settings for a file system location relative to the root
</span><span class='line'>      # which in this example would be /var/www/domain/downloads
</span><span class='line'>  }
</span><span class='line'>
</span><span class='line'>  location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
</span><span class='line'>      # specific settings for files ending in suffixes .ico, .css, .js, gif, etc
</span><span class='line'>      # defined using a regex, under the root defined in the server block
</span><span class='line'>  }
</span><span class='line'>
</span><span class='line'>  location / {
</span><span class='line'>      proxy_pass  http://127.0.0.1:8500/domain/;
</span><span class='line'>  }
</span><span class='line'>
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>In the above example, Nginx passes the request to ColdFusion, running on the same server, via port 8500. It gets the response back from CF, immediately terminates the connection to CF so it is available to handle the next request, and then serves the static files using the settings in the second location directive, along with the rendered html from ColdFusion to the user that made the request. Note that this configuration assumes that you&rsquo;ve <a href="http://dnando.github.io/blog/2014/12/04/change-location-of-cf11-webroot/">changed the location of the CF webroot</a>.</p>

<p>The first advantage here is that there is no connector needed between ACF or Lucee and the webserver. We don&rsquo;t need to install a connector as part of the initial server setup, and we avoid any bugs or configuration problems that might crop up with these connectors. We also avoid the necessity to sometimes manually reinstall connectors when updating ACF/Lucee. All that is needed is to add the proxy_pass directive and reload the configuration using <code>nginx -s reload</code>.</p>

<p>The second advantage is that as long as you have a firewall in place that only allows public access via ports 80, ( plus maybe port 443, and whatever port you are using for ssh access), your ACF or Lucee server is secured, simply because without a connector between the webserver and your application server, there is no direct access via port 80 or port 443 to your application server. In our example above, anyone browsing to domain.com/CFIDE/administrator/ will get a 404 error. The CFIDE directory isn&rsquo;t in the root specified. Port 8500 is closed, so ip:8500/CFIDE/administrator/ won&rsquo;t return a response. The ACF admin directory is not contained in the default site Nginx root, so ip:/CFIDE/administrator/, for instance, will simply return a 404.</p>

<p>How do you gain access to the admin areas of ColdFusion or Lucee on a remote server if ports 8500 or port 8888 are closed? Simple. Use <a href="http://dnando.github.io/blog/2014/11/04/ssh-tunneling-coldfusion-lockdown-technique/">SSH Tunneling</a>.</p>

<p>In the event that the CFIDE, WEB-INF, or lucee-context directories are exposed through a particular configuration setup in a particular server block, there is a simple way to handle this using location directives that can be set globally or included in each server block necessary, for example:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>location ~ /WEB-INF/  { access_log off; log_not_found off; deny all; }
</span><span class='line'>location ~ /META-INF/  { access_log off; log_not_found off; deny all; }</span></code></pre></td></tr></table></div></figure>


<p>or</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>location ~ /WEB-INF/  { return 404; }
</span><span class='line'>location ~ /META-INF/  { return 404; }
</span></code></pre></td></tr></table></div></figure>


<p>or</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>location ~ /CFIDE/ {
</span><span class='line'>  deny all;
</span><span class='line'>  allow 127.0.0.1;
</span><span class='line'>  }</span></code></pre></td></tr></table></div></figure>


<p>Very few developers spend significant time configuring servers. Hence, it often may happen that the servers we maintain for our clients are not as secure as they could be. The simplicity with which we can secure a ColdFusion server behind Nginx seems a definite advantage.</p>

<p>However, the biggest advantage, to me, seems to be the ease of configuring strong SSL https security on Nginx. Because Nginx uses a reverse proxy setup, Nginx can be configured to handle the https connection with the requestor in isolation. What this implies is that SSL certificates do not need to be imported into the Java keystore. Nor do your SSL certs need to be reimported every time the JVM is updated. Of course, if you require a very secure setup, in a load balanced configuration to multiple application servers, you might need to ensure an SSL connection between Nginx and ColdFusion / Lucee. But if, for instance, Nginx and ColdFusion / Lucee are located on the same server, or you trust the internal network, this would not be necessary.</p>

<p>Following this <a href="https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html">excellent guide</a> by Remy van Elst, I was able to relatively easily setup SSL for a web application to an A+ level as graded by <a href="https://www.ssllabs.com/ssltest/index.html">Qualys SSL Labs</a>. Here&rsquo;s what the SSL portion of my Nginx configuration looks like:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>server {
</span><span class='line'>  server_name  domain.com;
</span><span class='line'>  listen  443 ssl;
</span><span class='line'>
</span><span class='line'>  ssl_certificate     /etc/ssl/certs/domain_com.crt;
</span><span class='line'>  ssl_certificate_key /etc/ssl/certs/domain_com.key;
</span><span class='line'>
</span><span class='line'>  keepalive_timeout   70;
</span><span class='line'>  ssl_ciphers         'AES256+EECDH:AES256+EDH:!aNULL';
</span><span class='line'>
</span><span class='line'>  ssl_prefer_server_ciphers   on;
</span><span class='line'>  ssl_dhparam         /etc/ssl/certs/dhparam.pem;
</span><span class='line'>
</span><span class='line'>  ssl_session_cache shared:SSL:10m;
</span><span class='line'>  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
</span><span class='line'>
</span><span class='line'>  ssl_stapling on;
</span><span class='line'>  ssl_stapling_verify on;
</span><span class='line'>  resolver 8.8.8.8 8.8.4.4 valid=300s;
</span><span class='line'>  resolver_timeout 5s;
</span><span class='line'>
</span><span class='line'>  add_header Strict-Transport-Security max-age=345600;
</span><span class='line'>  add_header X-Frame-Options DENY;
</span><span class='line'>  add_header X-Content-Type-Options nosniff;
</span><span class='line'>
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>Note that I&rsquo;ve reduced the max-age value of the add_header Strict-Transport-Security directive to four days from what Remy has recommended, over uncertainty how this will play out when certificates are updated. I understand that this directive will force user agents to use https for the duration of the value set. Note that it will be updated into the future every time the header is sent to the browser.</p>

<p>There are 3 aspects of this configuration that require a bit of extra work on your part, besides simply copying, pasting and adjusting the above example. One is that if your SSL certificate provider has also issued intermediate and root certificates, you will need to concatenate these into one file. Your domain certificate must come first, followed by the intermediate certificates, and finally the root certificate at the end. The easiest way to do this is to create a blank text file, and copy and paste the contents of the certificates into it. Save it and upload it to the chosen location on your server, along with the private key. Point to the location of the concatenated cert in the Nginx config file using the ssl_certificate directive. Point to the location of the private key using the ssl_certificate_key directive.</p>

<p>On Linux, you should secure the key by running chmod 600 on the ssl directory that contains the certificate files and chmod 400 on the private key file itself.</p>

<p>To generate the file referred to in the ssl_dhparam directive in the above example, it is necessary to cd to your ssl certs directory and run the following command, as explained in <a href="https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html">Remy&rsquo;s guide</a> in the Forward Secrecy &amp; Diffie Hellman Ephemeral Parameters section:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>cd /etc/ssl/certs
</span><span class='line'>openssl dhparam -out dhparam.pem 4096</span></code></pre></td></tr></table></div></figure>


<p>You will be warned  that &ldquo;this will take awhile&rdquo;. Remy doesn&rsquo;t mention this, but be prepared for it to take a relatively long time, perhaps an hour or so.</p>

<p>Once you have ssl configured and working, you probably want to redirect any traffic trying to access the site via insecure http to secure https. Here&rsquo;s how to configure that:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>server {
</span><span class='line'>  server_name  domain.com;
</span><span class='line'>  listen  80;
</span><span class='line'>  return  301 https://$server_name$request_uri;
</span><span class='line'>}
</span></code></pre></td></tr></table></div></figure>


<p>I already mentioned what I think is the biggest advantage, the ease with which one can configure SSL. However, there is one other advantage I&rsquo;d like to mention that may trump that, the ability to easily configure Nginx for both load balancing and hot swapping of application servers. Here&rsquo;s how to do that using the upstream directive:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>upstream    cf_servers {
</span><span class='line'>  #ip_hash;                   ## uncomment ip_hash for load balancing         
</span><span class='line'>  server          127.0.0.1:8500;
</span><span class='line'>  #server         192.168.0.20:8500;  ## add more application servers for load balancing
</span><span class='line'>  keepalive       32;         ## number of upstream connections to keep alive
</span><span class='line'>}
</span><span class='line'>
</span><span class='line'>upstream    lucee_servers {
</span><span class='line'>  #ip_hash;                   ## uncomment ip_hash for load balancing         
</span><span class='line'>  server          127.0.0.1:8888;
</span><span class='line'>  #server         192.168.0.30:8888;  ## add more application servers for load balancing
</span><span class='line'>  keepalive       32;         ## number of upstream connections to keep alive
</span><span class='line'>}
</span></code></pre></td></tr></table></div></figure>


<p>Then instead of using the localhost IP address in your proxy_pass directive, use the upstream server name instead, like so:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>location / {
</span><span class='line'>  proxy_pass  http://cf_servers/domain/;
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>If you get caught in a bind and can&rsquo;t use ColdFusion for some reason, then hot swapping an application over to Lucee is as simply as changing the above to this:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>location / {
</span><span class='line'>  proxy_pass  http://lucee_servers/domain/;
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>Or if you find one of your web properties suddenly inundated with traffic, using the upstream directive, your webserver is already set up for load balancing. You&rsquo;d simply need to clone a few servers, boot them up, and add them to the upsteam directive. The ip_hash directive is a way to enable sticky sessions, to ensure a visitor is always routed to the same server.</p>

<p>A few more configuration options and details should be mentioned.</p>

<p>One is that it is also possible, and perhaps preferable, to configure the path to a website&rsquo;s files within Tomcat&rsquo;s server.xml file, rather than specifying it in the Nginx proxy_pass directive.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>&lt;Host name="domain.com" appBase="webapps"&gt;
</span><span class='line'>  &lt;Context path="" docBase="/var/sites/domain.com" /&gt;
</span><span class='line'>  &lt;Alias&gt;www.domain.com&lt;/Alias&gt;
</span><span class='line'>&lt;/Host&gt;
</span></code></pre></td></tr></table></div></figure>


<p>With the path to the website&rsquo;s files configured in server.xml, the path to the website&rsquo;s files is not appended to the proxy_pass directive, so it would look like this:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>server {
</span><span class='line'>  listen 80;
</span><span class='line'>  server_name .domain.com;
</span><span class='line'>  root /var/www/domain;
</span><span class='line'>
</span><span class='line'>  location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
</span><span class='line'>      # specific settings for files ending in suffixes .ico, .css, .js, gif, etc
</span><span class='line'>  }
</span><span class='line'>
</span><span class='line'>  location / {
</span><span class='line'>      proxy_pass  http://lucee_servers/;
</span><span class='line'>  }
</span><span class='line'>
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>For this to work, Nginx needs to pass the host name to the app server used, either Lucee or ColdFusion. Your application may also require this information. Here is a suggested set of directives to accomplish this:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>proxy_http_version  1.1;
</span><span class='line'>proxy_set_header    Connection "";
</span><span class='line'>proxy_set_header    Host                $host;
</span><span class='line'>proxy_set_header    X-Forwarded-Host    $host;
</span><span class='line'>proxy_set_header    X-Forwarded-Server  $host;
</span><span class='line'>proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;     ## CGI.REMOTE_ADDR
</span><span class='line'>proxy_set_header    X-Forwarded-Proto   $scheme;                        ## CGI.SERVER_PORT_SECURE
</span><span class='line'>proxy_set_header    X-Real-IP           $remote_addr;
</span><span class='line'>expires             epoch;
</span></code></pre></td></tr></table></div></figure>


<p>&hellip; which could be placed in a separate conf file and included with each proxy_pass directive, like so:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>location / {
</span><span class='line'>  proxy_pass  http://lucee_servers/;
</span><span class='line'>  include     /var/inc/nginx-cf-proxy-settings.conf;
</span><span class='line'>}
</span></code></pre></td></tr></table></div></figure>


<p>If you are using Lucee, adding a host configuration block to server.xml will cause Lucee to create a WEB-INF directory under the docBase path specified along with an additional context. You&rsquo;d then want to block public access to that directory in some way as I&rsquo;ve explained above.</p>

<p>You can also use a regex to ensure you only pass CFML templates to Lucee or ColdFusion, as the following example demonstrates:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>location ~ \.(cfm|cfml|cfc)$ {
</span><span class='line'>  proxy_pass  http://lucee_servers/;
</span><span class='line'>  include     /var/inc/nginx-cf-proxy-settings.conf;
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>You can put whatever file extensions you&rsquo;d like Lucee / ACF to process in the pipe delimited list within the regex, so <code>~ \.(cfm|cfml|cfc)$</code> or <code>~ \.(cfm|cfml|htm|html)$</code> could be used, for example.</p>

<p>A couple of small gotcha&rsquo;s I ran into setting the path to the website&rsquo;s files in the proxy_pass directive. One is that directories with dots in them can confuse mappings. The solution I used was to remove the dots from directory names and use hyphens instead ( my-domain-com ). I also had trouble with redirects in FW/1, since they rely on the value of cgi.script_name. The simple solution was to change the baseURL parameter of FW/1&rsquo;s config to <code>baseURL = ''</code> from the default <code>baseURL = 'useCgiScriptName'</code>. Problems such as these might be avoided by using the server.xml configuration option.</p>

<p>I have 2 production servers running Nginx at the moment, one ACF and one Lucee server, and so far it seems to be working very well. I&rsquo;m particularly happy with the choice because Nginx has a very small memory footprint, which leaves more memory available for the JVM, which indeed yet another advantage.</p>

<p>References:</p>

<ol>
<li><a href="https://www.nginx.com/resources/admin-guide/nginx-web-server/">Nginx Web Server configuration guide</a></li>
<li><a href="https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html">Remy van Elst Strong SSL Security on Nginx</a></li>
<li><a href="https://gist.github.com/igal-getrailo/6981111">Igal&rsquo;s Nginx config example</a></li>
<li><a href="http://www.amazon.com/Mastering-Nginx-Dimitri-Aivaliotis/dp/1849517444">Mastering NGINX by Dimitri Aivaliotis</a></li>
</ol>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Change Location of ColdFusion Webroot]]></title>
    <link href="http://dnando.github.io/blog/2014/12/04/change-location-of-cf11-webroot/"/>
    <updated>2014-12-04T18:12:08+01:00</updated>
    <id>http://dnando.github.io/blog/2014/12/04/change-location-of-cf11-webroot</id>
    <content type="html"><![CDATA[<p>I&rsquo;m in the process of preparing a server to test CF11 with nginx as the front end webserver. Since nginx will act as a reverse proxy for any files that need to be processed by CF, essentially .cfm files, and serve any other assets directly, images, css and js files, etc, I want to relocate the ColdFusion webroot to a directory outside of the cf installation directories. A little googling led me to a <a href="http://blog.bittersweetryan.com/2012/02/changing-webroot-of-coldfusion-zeus.html">old blog post</a> that outlined the process in sufficient detail that I got it working on the first shot. Thanks Ryan! This post is both to refresh the collective knowledge cache and affirm that the technique works on CF11 as well as CF10.</p>

<p>The first step is to locate the server.xml file, which you will find at</p>

<p><cfInstallationDirectory>/cfusion/runtime/conf/server.xml</p>

<p>Make a backup of it. If something goes wrong, you can use the backup to restore CF to a working state again. Note that CF needs to be able to locate the CFIDE and WEB-INF directories to function properly, and these are both located with in the default webroot location. So make a backup of server.xml before proceeding.</p>

<p>Open server.xml for editing, scroll down to the bottom of the file where you should find the following line commented out:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>&lt;!-- &lt;Context path="/" docBase="&lt;cf_home&gt;\wwwroot" WorkDir="&lt;cf_home&gt;\runtime\conf\Catalina\localhost\tmp" &gt;&lt;/Context&gt;  --&gt;</span></code></pre></td></tr></table></div></figure>


<p>Assuming the installation directory is /opt/cf11, so that I can give a concrete example, uncomment that line and adapt it to the following model, which is working on my CF11 installation:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>&lt;Context path="/" docBase="/var/www" WorkDir="/opt/cf11/cfusion/runtime/conf/Catalina/localhost/tmp" aliases="/CFIDE=/opt/cf11/cfusion/wwwroot/CFIDE,/WEB-INF=/opt/cf11/cfusion/wwwroot/WEB-INF"&gt;&lt;/Context&gt;</span></code></pre></td></tr></table></div></figure>


<p>The docBase is the new webroot location, which must already exist, but can be of your choice. WorkDir points to an existing location in the installation directories. The aliases are essential, so that CF can find the CFIDE and WEB-INF directories. Adjust the slant of the slashes depending on your operating system, Windows or Linux. Use absolute paths for these settings, so on a Windows server, they would likely begin with a drive letter.</p>

<p>After you&rsquo;ve edited and saved server.xml, restart ColdFusion, place some cf code in the docBase directory, and browse to it via localhost:8500/ to make sure it works. Also check if you can still access the CF admin panel at localhost:8500/CFIDE/administrator/, which CF should find via the <em>aliases=</em> declaration. If both those tests succeed, you should be good to go!</p>

<p>References:</p>

<ol>
<li><a href="http://blog.bittersweetryan.com/2012/02/changing-webroot-of-coldfusion-zeus.html">http://blog.bittersweetryan.com/2012/02/changing-webroot-of-coldfusion-zeus.html</a></li>
<li><a href="http://blogs.coldfusion.com/post.cfm/getting-started-with-tomcat-in-coldfusion-10">http://blogs.coldfusion.com/post.cfm/getting-started-with-tomcat-in-coldfusion-10</a></li>
</ol>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Exploring CentOS 7 Firewalld]]></title>
    <link href="http://dnando.github.io/blog/2014/12/02/exploring-centos-7-firewalld/"/>
    <updated>2014-12-02T10:41:04+01:00</updated>
    <id>http://dnando.github.io/blog/2014/12/02/exploring-centos-7-firewalld</id>
    <content type="html"><![CDATA[<p>New with CentOS 7 is firewalld, a replacement for iptables to manage the firewall. As with anything new, at first glance it seems confusing, but I&rsquo;m finding I prefer it over iptables.</p>

<p>The first thing to understand about firewalld is that it is has multiple layers. It comes with a predefined set of zones, namely block, dmz, drop, external, home, internal, public, trusted, and work. Each of those zones can be associated with a network device or one or more ip addresses. Essentially, zones define and demarcate the level of trust an admin has decided to place on the devices and traffic within a network.</p>

<p>firewalld also pre-defines a set of services that can be added or removed from a zone. Effectively, when a service is added to a zone, it opens a port and sets any other necessary parameters. Services are defined with XML. Here&rsquo;s what the http service looks like:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>&lt;?xml version="1.0" encoding="utf-8"?&gt;
</span><span class='line'>&lt;service&gt;
</span><span class='line'>  &lt;short&gt;WWW (HTTP)&lt;/short&gt;
</span><span class='line'>  &lt;description&gt;HTTP is the protocol used to serve Web pages. If you plan to make your Web server publicly available, enable this option. ... &lt;/description&gt;
</span><span class='line'>  &lt;port protocol="tcp" port="80"/&gt;
</span><span class='line'>&lt;/service&gt;</span></code></pre></td></tr></table></div></figure>


<p>So to open port 80 via the tcp protocol to serve http requests, as an example, first a zone must be associated with the network device that will handle the traffic, and then the http service added to the zone. As an admin, you can define your own custom services, or customize existing services. Other techniques allow you to open a port directly on a zone, or define more complex rules for access.</p>

<p>To configure the firewall and check its status, a command line client is provided, firewall-cmd. It can be used to make both permanent and temporary config changes. The configuration for firewalld is stored in XML files in /usr/lib/firewalld/ ( the default settings, not to be modified! ) and /etc/firewalld/ ( for user configured settings, which have preference over those in the default location ). These files can be edited, backed up, or used as templates for other server installations.</p>

<p>Now that we have an overview, we can get to work. To check if firewalld is running:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>systemctl status firewalld</span></code></pre></td></tr></table></div></figure>


<p>If you see from the output that firewalld is not running, or you see that the loaded service is disabled, here are the commands needed:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>systemctl enable firewalld
</span><span class='line'>systemctl start firewalld</span></code></pre></td></tr></table></div></figure>


<p>If a service is enabled, it will start on system reboot. Hence it&rsquo;s particularly important to ensure firewalld is enabled on a production server.</p>

<p>Here&rsquo;s how to disable firewalld so it will not start at boot time, and shut it down:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>systemctl disable firewalld
</span><span class='line'>systemctl stop firewalld</span></code></pre></td></tr></table></div></figure>


<p>Now I want to configure the firewall. First, I check for the name of the ethernet interface so that I can refer to it to associate it with a zone:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>nmcli dev status</span></code></pre></td></tr></table></div></figure>


<p>Then I check which zone eno16777736 is currently assigned to:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>firewall-cmd --get-zone-of-interface=eno16777736</span></code></pre></td></tr></table></div></figure>


<p>The result is &ldquo;no zone&rdquo;, so the next step is to add the ethernet interface to the public zone, which is the zone I&rsquo;ve decided to use for http access to the server. It&rsquo;s important to add the &ndash;permanent flag to the command so it is retained permanently, across reboots:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>firewall-cmd --zone=public --add-interface=eno16777736 --permanent</span></code></pre></td></tr></table></div></figure>


<p>Now I have to reload the firewall configuration for the changes to take effect:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>firewall-cmd --reload</span></code></pre></td></tr></table></div></figure>


<p>And then we can double check just to make sure the ethernet interface is now added to the public zone &hellip;</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>firewall-cmd --get-zone-of-interface=eno16777736</span></code></pre></td></tr></table></div></figure>


<p>and the result is &ldquo;public&rdquo;, so that&rsquo;s now set up correctly.</p>

<p>Let&rsquo;s now check how the public zone is currently set up:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>firewall-cmd --zone=public --list-all</span></code></pre></td></tr></table></div></figure>


<p>Here we see again that the ethernet interface is added to the public zone, and that it is both active and the default zone. By default after installing CentOS 7, we have the services dhcpv6-client and ssh added to this zone. Taking a quick look at the description for this service to see what it does by opening /usr/lib/firewalld/services/dhcpv6-client.xml, we see, &ldquo;This option allows a DHCP for IPv6 (DHCPv6) client to obtain addresses and other IPv6 settings from DHCPv6 server.&rdquo; We won&rsquo;t be using IPv6 addresses within our local network to access this machine, so I think it&rsquo;s safe to remove this service, although we may want to leave it in place on a production server:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>firewall-cmd --zone=public --remove-service=dhcpv6-client --permanent</span></code></pre></td></tr></table></div></figure>


<p><strong>Reminder - remember to always add the permanent flag to these commands if you want changes to be persisted!</strong></p>

<p>Now we can add the services for http access to our public zone:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>firewall-cmd --zone=public --add-service=http --permanent
</span><span class='line'>firewall-cmd --zone=public --add-service=https --permanent</span></code></pre></td></tr></table></div></figure>


<p>&hellip; reload the firewall &hellip;</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>firewall-cmd --reload</span></code></pre></td></tr></table></div></figure>


<p>&hellip; and recheck the configuration, using list-services instead of list-all just to try it out:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>firewall-cmd --zone=public --list-services</span></code></pre></td></tr></table></div></figure>


<p>and I see that we now have services http https ssh configured. Excellent. Let&rsquo;s test that in a web browser.</p>

<p>I&rsquo;ve installed nginx web server, but see using systemctl status nginx that it&rsquo;s not yet running or enabled, so first we run</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>systemctl start nginx
</span><span class='line'>systemctl enable nginx</span></code></pre></td></tr></table></div></figure>


<p>And then I go to 192.168.1.16 in a web browser and see <strong>Welcome to nginx!</strong> Good.</p>

<p>As a double check, let&rsquo;s remove the http service and see what happens.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>firewall-cmd --zone=public --remove-service=http --permanent
</span><span class='line'>firewall-cmd --reload</span></code></pre></td></tr></table></div></figure>


<p>Reloading 192.168.1.16, I get a No data received message, so that&rsquo;s exactly what we should expect.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>firewall-cmd --zone=public --add-service=http --permanent
</span><span class='line'>firewall-cmd --reload</span></code></pre></td></tr></table></div></figure>


<p>And adding the http service back to the public zone again allows the <strong>Welcome to nginx!</strong> page to be loaded in my browser. Perfect.</p>

<p>However, I still don&rsquo;t have access to the CF Admin panel at <a href="http://192.168.1.16:8500/CFIDE/administrator/index.cfm,">http://192.168.1.16:8500/CFIDE/administrator/index.cfm,</a> because that&rsquo;s over port 8500. On a production machine, I absolutely would not open port 8500 for this purpose. But since this server is on our local office network, let&rsquo;s see how we can do this.</p>

<p>The first option that comes to mind is to create a custom firewalld service specifically for this purpose. Documentation I&rsquo;ve read recommends using existing services as a template. Custom services go in /etc/firewalld/services/. First let&rsquo;s make a copy of the http service, calling it http8500, and place it in /etc/firewalld/services/:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>cp /usr/lib/firewalld/services/http.xml /etc/firewalld/services/http8500.xml</span></code></pre></td></tr></table></div></figure>


<p>Then we edit /etc/firewalld/services/http8500.xml to use port 8500 instead of port 80. Here&rsquo;s what the modified file looks like:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>&lt;?xml version="1.0" encoding="utf-8"?&gt;
</span><span class='line'>&lt;service&gt;
</span><span class='line'>  &lt;short&gt;CF Admin Access&lt;/short&gt;
</span><span class='line'>  &lt;description&gt;For CF Admin access via port 8500.&lt;/description&gt;
</span><span class='line'>  &lt;port protocol="tcp" port="8500"/&gt;
</span><span class='line'>&lt;/service&gt;</span></code></pre></td></tr></table></div></figure>


<p>Then we add this service to the public zone and reload the firewall:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>firewall-cmd --zone=public --add-service=http8500 --permanent
</span><span class='line'>firewall-cmd --reload</span></code></pre></td></tr></table></div></figure>


<p>And now <a href="http://192.168.1.16:8500/CFIDE/administrator/index.cfm">http://192.168.1.16:8500/CFIDE/administrator/index.cfm</a> works! Again, this is not how I&rsquo;d set up access to the CF administrator on a production machine, but it was an opportunity to experiment with creating custom services. What I like about this option is that I can enable or disable it, independently of the other services enabled. So if I decide I want to lock this server down, I can quickly remove the http8500 service and access the CF Administrator via <a href="http://dnando.github.io/blog/2014/11/04/ssh-tunneling-coldfusion-lockdown-technique/">SSH Tunnelling</a>.</p>

<p>What I usually do is move ssh access to an obscure port. I think we can easily accomplish this using a custom service, but before I do that, I want to take a look at how the localhost interface is set up within the firewall. Again, we use nmcli dev status to get the name of the localhost or loopback interface</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>nmcli dev status</span></code></pre></td></tr></table></div></figure>


<p>It&rsquo;s &ldquo;lo&rdquo;, so let&rsquo;s see if it&rsquo;s set to zone by default:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>firewall-cmd --get-zone-of-interface=lo</span></code></pre></td></tr></table></div></figure>


<p>Nope, the result I get is &ldquo;no zone&rdquo;. Let&rsquo;s also see if there are any services added to the trusted zone, which would be the most appropriate for localhost</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>firewall-cmd --zone=trusted --list-all</span></code></pre></td></tr></table></div></figure>


<p>At this point, nothing is added to this zone, no interfaces, services, sources or ports, etc. And the network interface &ldquo;lo&rdquo; isn&rsquo;t associated with any zone.</p>

<p>Now what I want to see is how the server responds to localhost access with the firewall enabled. This <em>might</em> be important on a production server because I will use ssh tunneling to access any areas I will restrict from public access. So let&rsquo;s logout from the server and login again with the -D flag so that I can tunnel into the test server and test if I have access via localhost with the firewall setup as it is now:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>exit
</span><span class='line'>ssh -D 6100 root@192.168.1.16
</span><span class='line'>root@192.168.1.16's password:
</span></code></pre></td></tr></table></div></figure>


<p>I keep Firefox on my dev machine reserved and set up for ssh tunneling on port 6100, so I simply open Firefox and browse to <a href="http://localhost:8500/CFIDE/administrator/index.cfm,">http://localhost:8500/CFIDE/administrator/index.cfm,</a> and find I can access the CF11 admin page and login. Browsing to <a href="http://localhost/,">http://localhost/,</a> I see the Welcome to nginx! page. So at this point via localhost, I have access. ( Note for anyone without experience using ssh tunnelling,  when I use localhost on Firefox set up for ssh tunneling, logged to the CentOS server using the -D flag, I am browsing the CentOS server next to me, not my dev machine. See <a href="http://dnando.github.io/blog/2014/11/04/ssh-tunneling-coldfusion-lockdown-technique/">SSH Tunnelling</a> for details how to do this. )</p>

<p>Now what happens if I add the &ldquo;lo&rdquo; network interface to the trusted zone, where no access is currently set up?</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>firewall-cmd --zone=trusted --add-interface=lo --permanent
</span><span class='line'>firewall-cmd --reload</span></code></pre></td></tr></table></div></figure>


<p>Adding the &ldquo;lo&rdquo; interface to the trusted zone with no services had no affect at all on tunnelled access to localhost. So it looks like the firewall doesn&rsquo;t interfere there. So to clean up, I will remove the &ldquo;lo&rdquo; interface from the trusted zone and call it a day.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>firewall-cmd --zone=trusted --remove-interface=lo --permanent
</span><span class='line'>firewall-cmd --reload</span></code></pre></td></tr></table></div></figure>


<p>PS - For some reason, &ldquo;lo&rdquo; was not removed from the trusted zone according to firewall-cmd &ndash;zone=trusted &ndash;list-all unless and until I rebooted the server. The strange thing was that the config file was correctly altered, but somehow, firewalld didn&rsquo;t seem to pick up the change. Perhaps this is the intended behavior, to prevent lockout during a current session, but I&rsquo;ll look into filing a bug report later this evening &hellip; ( which I have now filed <a href="https://bugs.centos.org/view.php?id=7957">here</a> ).</p>

<p>References:</p>

<ol>
<li><a href="https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Security_Guide/sec-Using_Firewalls.html">https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Security_Guide/sec-Using_Firewalls.html</a></li>
<li><a href="http://www.certdepot.net/rhel7-get-started-firewalld/">http://www.certdepot.net/rhel7-get-started-firewalld/</a></li>
<li><a href="http://fedoraproject.org/wiki/FirewallD">http://fedoraproject.org/wiki/FirewallD</a></li>
</ol>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Setting Up a Local Testing Server on VMWare]]></title>
    <link href="http://dnando.github.io/blog/2014/12/01/setting-up-a-local-testing-server-on-vmware/"/>
    <updated>2014-12-01T15:55:49+01:00</updated>
    <id>http://dnando.github.io/blog/2014/12/01/setting-up-a-local-testing-server-on-vmware</id>
    <content type="html"><![CDATA[<p>I&rsquo;ve been wondering how to best set up a local testing environment for some time. My production servers are all on CentOS. On the advice of Nolan Erck, whom I met at CFCamp this year, I&rsquo;ve decided to use VMWare to set up a CentOS server on a virtual machine here in the office. This approach allows me to have multiple test environments, and I can easily move them to another machine if needed simply by copying the disk image.</p>

<p>For ease of access, each VM needs a static ip on the local network. It&rsquo;s not hard to do once you figure it out, but getting all the pieces in place took some hours of digging, trial and error. This post, while specific to VMWare and CentOS 7, is intended to help both my future self and anyone else set up networking quickly and easily in such a scenario.  Adapt as necessary for your specific environment.</p>

<p>The obvious first step was to download the ISO image from a <a href="http://www.centos.org/download/mirrors/">CentOS mirror site</a>. I grabbed the minimal install as a nearest approximation to a production environment, and created a VM from it using VMWare on an unused Mac mini we had laying around the office.</p>

<p>On the minimal install, networking isn&rsquo;t enabled by default. So before I could proceed, I had to figure how to enable networking, and get it working via a static IP. Here&rsquo;s a summary of what finally worked for me.</p>

<p>1) Figure out what the ethernet device is named by running the command :</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>nmcli dev status</span></code></pre></td></tr></table></div></figure>


<p><img src="http://dnando.github.io/images/nmcli.gif" alt="nmcli dev status" /></p>

<p>As you can see, mine was named eno16777736, which is not the RedHat default you may find in many examples online.</p>

<p>2) cd to the directory /etc/sysconfig/network-scripts and run ls to display its files</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>cd /etc/sysconfig/network-scripts
</span><span class='line'>ls</span></code></pre></td></tr></table></div></figure>


<p><img src="http://dnando.github.io/images/networkScriptsLs.gif" alt="network-scripts ls" /></p>

<p>3) Look for the configuration file for your ethernet device, mine was named ifcfg-eno16777736 and open it for editing using vm or nano</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>nano ifcfg-eno16777736</span></code></pre></td></tr></table></div></figure>


<p><img src="http://dnando.github.io/images/nano-ifcfg.gif" alt="network-scripts ls" /></p>

<p>The above screenshot was taken after it was edited. The lines to change or add are:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>BOOTPROTO=static
</span><span class='line'>IPADDR=&lt;the static ip address you want to assign to this instance&gt;
</span><span class='line'>NETMASK=255.255.255.0
</span><span class='line'>GATEWAY=&lt;the gateway ip address of your internal network&gt;
</span><span class='line'>NM_CONTROLLED=no
</span><span class='line'>ONBOOT=yes</span></code></pre></td></tr></table></div></figure>


<p>I found that adding the correct gateway ip was essential. NM_CONTROLLED specifies whether or not this device is controlled by the Network Manager. We are setting the parameters manually here, so this must be no. ONBOOT=yes specifies to connect this network device on boot.</p>

<p>Save the file, exit nano, and run the following command to restart the network:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>systemctl restart network</span></code></pre></td></tr></table></div></figure>


<p>Now CentOS 7 should be setup to network via the static local ip of your choice. But the connection isn&rsquo;t bridged outside of the VM. After some fiddling around, here&rsquo;s what worked for me. I went out to the VMWare interface, clicked on the double arrow icon to open the networking menu, and clicked Network Adapter Settings&hellip;</p>

<p><img src="http://dnando.github.io/images/vmWareNAS1.jpg" alt="VMWare Network menu" /></p>

<p>From the menu, I chose Autodetect, as shown below:</p>

<p><img src="http://dnando.github.io/images/vmWareNAS2.jpg" alt="VMWare Network menu" /></p>

<p>Once I had these configuration changes in place, I could access the CentOS instance via SSH and SFTP from my dev machine.</p>

<p>By the way, from my reading, it also seems possible to use the Network Manager to achieve the same end. In this case, you&rsquo;d leave the config file for your network device alone, and instead run the nmtui command. Search Google for more complete instructions. You&rsquo;ll still need to bridge the connection through VMWare tho&#8217;.</p>

<p>Hope this helps somebody.</p>

<p>PS - If you can access the instance via SSH or SFTP, but cannot from a browser, you may need to either disable and stop firewalld:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>systemctl disable firewalld
</span><span class='line'>systemctl stop firewalld</span></code></pre></td></tr></table></div></figure>


<p>or better, figure out how to configure it properly to allow access via a browser, which I cover in the next article, <a href="http://dnando.github.io/blog/2014/12/02/exploring-centos-7-firewalld/">Exploring CentOS 7 firewalld</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[SSH Tunneling - ColdFusion Lockdown Technique]]></title>
    <link href="http://dnando.github.io/blog/2014/11/04/ssh-tunneling-coldfusion-lockdown-technique/"/>
    <updated>2014-11-04T14:40:42+01:00</updated>
    <id>http://dnando.github.io/blog/2014/11/04/ssh-tunneling-coldfusion-lockdown-technique</id>
    <content type="html"><![CDATA[<p>The ColdFusion and Lucee Lockdown Guides recommend that access is restricted to all administrative areas of the server. This is especially important to do because many security vulnerabilities have been discovered that exploit open access to admin directories. It is fairly easy to accomplish, using a directive in the Apache configuration for example. It would look something like this on ACF:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>&lt;Location /CFIDE&gt;
</span><span class='line'>  Order Deny,Allow
</span><span class='line'>  Deny from All
</span><span class='line'>&lt;/Location&gt;
</span></code></pre></td></tr></table></div></figure>


<p>or this on Lucee:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>&lt;Location /lucee-context&gt;
</span><span class='line'>  Order Deny,Allow
</span><span class='line'>  Deny from all
</span><span class='line'>&lt;/Location&gt;</span></code></pre></td></tr></table></div></figure>


<p>So far so good, but now anyone needing to administer the server can&rsquo;t login. They will be denied access by the web server. There are various recommendations for allowing only selective access, for instance from a given fixed IP address at the office of the administrator:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>&lt;Location /lucee-context&gt;
</span><span class='line'>  Order Deny,Allow
</span><span class='line'>  Deny from all
</span><span class='line'>  Allow from 84.16.156.99
</span><span class='line'>&lt;/Location&gt;</span></code></pre></td></tr></table></div></figure>


<p>But what if the server administrator(s) is/are out of the office when they need access to the server? Away at a conference, at a client&rsquo;s office, or at home? And what if your office doesn&rsquo;t have a fixed IP address? Should you get one &hellip; and then have to remember to change the &ldquo;allow from&rdquo; IP address in all of your server configuration files if and when that IP address changes? For a variety of reasons, this doesn&rsquo;t seem ideal.</p>

<p>There&rsquo;s another &ldquo;small&rdquo; problem here. Best security practice dictates that all access to admin areas should be over an encrypted connection. I cannot ensure that the modem installed here in my office, or wherever else I happen to be when needing to admin my servers, a hotel for instance, is not compromised by a packet sniffer. In fact, I recently installed an update on our modem here specifically for a packet sniffing vulnerability, and I only ran across it by chance. No idea how long that remained unpatched, and I&rsquo;m simply not prepared to invest the time to learn how to monitor this sort of thing. This implies that I <em>definitely should</em> install SSL certificates and set up secure https access for all administrative areas on each server I maintain. That&rsquo;s painful.</p>

<p>Put all that together, and it helps to explain why ACF and Lucee servers are often not locked down.</p>

<p>Here&rsquo;s where SSH tunneling comes to the rescue. In a nutshell, it allows you to securely browse a remote server as localhost, as if the server was under your desk and your keyboard and monitor where connected to it, even if it&rsquo;s located halfway around the world. The icing on the cake is it is very simple to set up, and the same setup will work for every server you admin!</p>

<p>To use SSH tunneling to gain access to admin areas of your server, the first step to restrict access to any admin area to only localhost, for example:</p>

<p>For ACF:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>&lt;Location /CFIDE&gt;
</span><span class='line'>  Order Deny,Allow
</span><span class='line'>  Deny from All
</span><span class='line'>  Allow from localhost
</span><span class='line'>&lt;/Location&gt;
</span></code></pre></td></tr></table></div></figure>


<p>or for Lucee:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>&lt;Location /lucee-context&gt;
</span><span class='line'>  Order Deny,Allow
</span><span class='line'>  Deny from all
</span><span class='line'>  Allow from localhost
</span><span class='line'>&lt;/Location&gt;</span></code></pre></td></tr></table></div></figure>


<p>( While you are at it, restrict port access to only those ports you need to leave exposed, for instance 80, 443 and whatever port you are using for SSH access ).</p>

<p>There are detailed instructions for SSH tunneling all over the web if you want to find out more, but the instructions below should work fine for our purposes.</p>

<ol>
<li><p>In your web browser, configure the proxy settings to point to &ldquo;localhost&rdquo;, a free port on your local machine (we&rsquo;ll use 60001), using SOCKS5. This should work with any browser. Using Firefox as an example, here&rsquo;s how to do that:</p>

<ul>
<li>Go to Preferences</li>
<li>Click the Advanced icon</li>
<li>Click the Network tab</li>
<li>Click the Settings button, across from where it says &ldquo;Configure how Firefox connects to the Internet</li>
<li>Select Manual proxy configuration</li>
<li>In the SOCKS Host field put &ldquo;localhost&rdquo; without the quotation marks</li>
<li>In the Port field put the port number you will use, 60001 in our example</li>
<li>Select SOCKS v5</li>
<li>Click OK</li>
</ul>
</li>
<li><p>ssh into any server you admin using Terminal or Putty, etc.  Use the -D flag set to the same port as above, example: ssh -D 60001 <a href="&#109;&#97;&#105;&#x6c;&#116;&#111;&#58;&#117;&#x73;&#101;&#x72;&#x40;&#49;&#x30;&#x32;&#x2e;&#x31;&#48;&#x33;&#x2e;&#49;&#x30;&#x38;&#x2e;&#x33;&#57;">&#117;&#115;&#x65;&#114;&#x40;&#x31;&#48;&#x32;&#x2e;&#x31;&#x30;&#x33;&#x2e;&#49;&#48;&#56;&#x2e;&#51;&#x39;</a></p></li>
<li><p>You can now access admin areas of the server in this browser using localhost urls such as <a href="http://127.0.0.1/CFIDE/administrator/enter.cfm,">http://127.0.0.1/CFIDE/administrator/enter.cfm,</a> as long as you remain logged in via SSH. The connection is through an SSH &ldquo;tunnel&rdquo;, so between your local machine and the server, all traffic is encypted.</p></li>
</ol>


<p>Note that the port chosen is arbitrary. It only has to be available and match in both the -D flag and SOCKS port setting. To revert the browser to normal behavior, simply choose No Proxy in the Network Settings dialog.</p>

<p>What I usually do is leave Firefox configured in this way and reserve it only for SSH tunnelling sessions. And again, once a browser is configured with these proxy settings, you can securely browse any server as localhost by SSH&#8217;ing into it with the -D port setting.</p>

<p>Now say you have Fusion Reactor installed and want to ensure access is also restricted. Just leave your firewall configured to leave the ports Fusion Reactor uses closed, and access it, securely, via your SSH tunnel!</p>

<p>Thanks to <a href="https://www.linkedin.com/in/davidjstockton">David Stockton</a>, who until recently worked with the fusion reactor team, for sharing this tip with me.</p>

<p><strong>IMPORTANT NOTE:</strong> If you have difficulty logging in, or maintaining a login, particularly to the ACF admin panel, clear the cookies in the browser you are using for SSH tunneling and try again.</p>

<p>In my case, I ran into this after using this technique to manage multiple instance of ACF, particularly on ACF 11. I could log in to the admin panel successfully, but if I tried to modify anything, set a datasource for instance, I was logged out and the action did not complete. The error log contained the message &ldquo;There was an error while verifying the token. Either the session timed out or un-authenticated access is suspected.&rdquo;</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How to Rollback Yum Updates on CentOS]]></title>
    <link href="http://dnando.github.io/blog/2014/10/24/how-to-rollback-yum-updates-on-centos/"/>
    <updated>2014-10-24T16:26:50+02:00</updated>
    <id>http://dnando.github.io/blog/2014/10/24/how-to-rollback-yum-updates-on-centos</id>
    <content type="html"><![CDATA[<p>1) Open the yum config file:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>vi /etc/yum.conf</span></code></pre></td></tr></table></div></figure>


<p>and ensure the following line is included in the config settings</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>tsflags=repackage</span></code></pre></td></tr></table></div></figure>


<p>2) Open the rpm macro file ( or create it if it doesn&rsquo;t exist ):</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>vi /etc/rpm/macros</span></code></pre></td></tr></table></div></figure>


<p>And ensure the following line is included:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>%_repackage_all_erasures 1</span></code></pre></td></tr></table></div></figure>


<p>Now the rollback flag can be used on the rpm command as shown in the examples below to roll back updates to any point in the past:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>rpm -Uvh –rollback ’21:00′
</span><span class='line'>rpm -Uvh –rollback ’3 hours ago’
</span><span class='line'>rpm -Uvh –rollback ‘august 13′
</span><span class='line'>rpm -Uvh –rollback ‘yesterday’</span></code></pre></td></tr></table></div></figure>


<p>Simple.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Is This Acceptable?]]></title>
    <link href="http://dnando.github.io/blog/2014/10/17/is-this-acceptable/"/>
    <updated>2014-10-17T14:09:18+02:00</updated>
    <id>http://dnando.github.io/blog/2014/10/17/is-this-acceptable</id>
    <content type="html"><![CDATA[<p>A few days ago, Adobe released <a href="http://blogs.coldfusion.com/post.cfm/updates-for-coldfusion-11-coldfusion-10-and-coldfusion-9-released">updates</a> for CF 9, 10 and 11. I&rsquo;ve been following comments raised about them since, and I&rsquo;m disturbed to see some developers struggling to get their servers patched, especially when applying the update has taken the server down. I don&rsquo;t know if these cases are isolated or might be more widespread, but I find this unacceptable.</p>

<p>I run several instances of ACF on CentOS. I&rsquo;m subscribed to the CentOS-announce Digest mailing list, as I&rsquo;m sure most CentOS server admins are. For many years now, whenever an update is released, perhaps once or twice a week, I ssh directly onto our servers, run yum update, and generally within less than a minute, the update completes. Never once has the process failed. Never once have I seen an incoming email on the CentOS mailing list that someone experienced a server crash, or any other issue for that matter, because of an update.</p>

<p>This is how ColdFusion updates <strong>should</strong> function, flawlessly.</p>

<p>In stark contrast, CF developers have become wary of applying updates. There is a risk that their server will compromised because of the security vulnerability the update is meant to patch, and there seems to be an equal if not greater risk that their server will be compromised, in one way or another, in the update process. CF 10 introduced automated updates, but as we see, the automated update process remains error prone.</p>

<p>It should not be like this. Rather than focusing on new features, the CF dev team needs to focus on getting the update process as flawless as it is on CentOS. What they seem to have lost track of is that, for a start, developers have families to support. Our clients expect us to keep their servers up and running 24/7. Our clients depend on the applications we build to run their businesses. As developers, we <em>cannot</em> afford to experiment on our clients. And yet, when Adobe releases a flawed update that takes servers down, effectively experimenting on us and our clients, <em>oh, look, they are trapped between a security vulerability and a flawed update</em>, the implicit statement received on our end is &ldquo;We don&rsquo;t care if you keep your clients. It does not matter to us at all.&rdquo; Really?</p>

<p>What is even more disturbing is the way the Adobe dev team now uses us as their QA department, as if ColdFusion server was loosely organized open source project among wannabe hackers. It is not disturbing because the CF devs are actively reaching out trying to solve problems that are occurring, asking for logs, error message screenshots, suggesting the possible need to copy and paste jar files from here to there if some functionality is broken, instructing us to manually install the updates one at a time if the automated updater doesn&rsquo;t work, etc. It is because these interchanges should never occur in the first place regarding an update. The update process needs to be flawless, as near to it as possible, so that we can rely on it. Like it is on CentOS. If they can do it, the CF dev team can do it.</p>

<p>The worst, however, is <a href="http://blogs.coldfusion.com/post.cfm/updates-for-coldfusion-11-coldfusion-10-and-coldfusion-9-released#comment-2A6D270F-CEF1-319F-EDCFF7262E950FC0">this</a>, linked for reference but replicated below, an Adobe engineer asking a developer, a paying customer, to effectively crash his server &ldquo;in off peak hours&rdquo; so that he can get at the log files that might reveal what the problem is.</p>

<blockquote><p>Hi Mark,</p><p>Of all the things connector logs with debug_level=debug are the most important one&#8217;s. Till now with all the information you have shared I can tell that there is some problem with shared memory access between worker threads. But to exactly pin point the problem I will be needing the connector logs. I understand it will be difficult for you to do something on production server but it is a must for this problem to be resolved.</p><p>If possible in off-peak hours, apply the update14 and reconfigure the connector. Once the connector is installed go to connector directory c:\coldfusion10\config\wsconfig\magicnumber\ and open isapi_redirect.properties in notepad.<br/>Edit the line &#8220;log_level= info&#8221; and change it to &#8220;log_level= debug&#8221; and save the changes. Restart IIS, hit any cfm page and wait for app pool to crash. Once it is crashed take a backup of isapi_redirect.log(created in connector directory) in some other directory like c:\connector_logs\ directory. After the backup you can revert back the changes.<br/>Lastly you have to share this backed up logs with us.</p><p>Thanks,<br/>Milan.</p></blockquote>


<p>When I say this is unacceptable, I mean that it is not acceptable for Adobe to use CF developers and their clients as their QA team, especially in that Milan says &ldquo;I understand it will be difficult for you to do something on production server but it is a <em>must</em> for this problem to be resolved.&rdquo; No, it is <strong>not</strong> a must to take down our servers, possibly endangering our client relationships, to fix your bugs.</p>

<p>Yes, this is very complex stuff. But in today&rsquo;s world, that simply means Adobe needs to employ a vastly improved QA strategy than the one they have in place today for ColdFusion releases, especially for the update process itself.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Check Digit Computation for Swiss Pay Slips]]></title>
    <link href="http://dnando.github.io/blog/2014/09/23/check-digit-computation-swiss-pay-slips/"/>
    <updated>2014-09-23T13:50:02+02:00</updated>
    <id>http://dnando.github.io/blog/2014/09/23/check-digit-computation-swiss-pay-slips</id>
    <content type="html"><![CDATA[<p>I&rsquo;m working on a business application that generates invoices and pay slips for a company in Switzerland. Instead of checks, the Swiss banking system uses a pay slip, and these have an account number, a reference number and of course the total which should be paid, all with check digits, similar to what is found on credit card numbers. At first I thought the check digit was generated by the <a href="http://en.wikipedia.org/wiki/Luhn_algorithm">Luhn algorithm</a>, for which I could find plentiful examples, even in ColdFusion, such as <a href="http://www.danvega.org/blog/2009/9/3/Using-ColdFusion-to-generate-credit-card-numbers">Dan Vega&rsquo;s post</a> explaining how to generate credit card numbers with correct check digits. The meat of his implementation is here, which expects an array, ccnumber, with the card number in it and and cclen, which is of course <code>arrayLen( ccnumber )</code></p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class='cfc'><span class='line'><span class="o">&lt;</span><span class="nv">cfscript</span><span class="o">&gt;</span>
</span><span class='line'>  <span class="cm">/* the luhn Algorithm is used to create the check digit number */</span>
</span><span class='line'>  <span class="k">var</span> <span class="nv">sum</span> <span class="o">=</span> <span class="m">0</span><span class="p">;</span>
</span><span class='line'>  <span class="k">for</span><span class="p">(</span><span class="nv">j</span><span class="o">=</span><span class="m">1</span><span class="p">;</span> <span class="nv">j</span> <span class="o">&lt;</span> <span class="nv">cclen</span><span class="p">;</span> <span class="nv">j</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="k">var</span> <span class="nv">digit</span> <span class="o">=</span> <span class="nv">ccnumber</span><span class="p">[</span><span class="nv">j</span><span class="p">];</span>
</span><span class='line'>      <span class="c1">// length of 16 for Visa|Mastercard|Discover &amp;&amp; length of 15 for Amex</span>
</span><span class='line'>      <span class="k">if</span><span class="p">(</span> <span class="p">(</span><span class="nv">cclen</span> <span class="o">==</span> <span class="m">16</span> <span class="o">&amp;&amp;</span> <span class="nv">j</span> <span class="err">%</span> <span class="m">2</span> <span class="o">!=</span> <span class="m">0</span><span class="p">)</span> <span class="o">||</span> <span class="p">(</span><span class="nv">cclen</span> <span class="o">==</span> <span class="m">15</span> <span class="o">&amp;&amp;</span> <span class="nv">j</span> <span class="err">%</span> <span class="m">2</span> <span class="o">==</span> <span class="m">0</span><span class="p">)</span> <span class="p">){</span>
</span><span class='line'>          <span class="nv">digit</span> <span class="o">=</span> <span class="nv">digit</span> <span class="o">*</span> <span class="m">2</span><span class="p">;</span>
</span><span class='line'>          <span class="k">if</span><span class="p">(</span><span class="nv">digit</span> <span class="o">&gt;</span> <span class="m">9</span><span class="p">){</span>
</span><span class='line'>              <span class="nv">digit</span> <span class="o">=</span> <span class="p">(</span> <span class="nf">left</span><span class="p">(</span><span class="nv">digit</span><span class="p">,</span><span class="m">1</span><span class="p">)</span> <span class="o">+</span> <span class="nf">right</span><span class="p">(</span><span class="nv">digit</span><span class="p">,</span><span class="m">1</span><span class="p">)</span> <span class="p">);</span>
</span><span class='line'>          <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>              <span class="nv">digit</span> <span class="o">=</span> <span class="nv">digit</span><span class="p">;</span>
</span><span class='line'>          <span class="p">}</span>
</span><span class='line'>      <span class="p">}</span>
</span><span class='line'>      <span class="nv">sum</span> <span class="o">+=</span> <span class="nv">digit</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="k">var</span> <span class="nv">check_digit</span> <span class="o">=</span> <span class="p">[</span><span class="m">0</span><span class="p">,</span><span class="m">9</span><span class="p">,</span><span class="m">8</span><span class="p">,</span><span class="m">7</span><span class="p">,</span><span class="m">6</span><span class="p">,</span><span class="m">5</span><span class="p">,</span><span class="m">4</span><span class="p">,</span><span class="m">3</span><span class="p">,</span><span class="m">2</span><span class="p">,</span><span class="m">1</span><span class="p">];</span>
</span><span class='line'>  <span class="nv">ccnumber</span><span class="p">[</span><span class="nv">cclen</span><span class="p">]</span> <span class="o">=</span> <span class="nv">check_digit</span><span class="p">[(</span><span class="nv">sum</span> <span class="err">%</span> <span class="m">10</span> <span class="o">+</span> <span class="m">1</span><span class="p">)];</span>
</span><span class='line'><span class="o">&lt;/</span><span class="nv">cfscript</span><span class="o">&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>I was hoping I could quickly adapt the above for my use case. However, I was disappointed to learn that Swiss pay slips use a non-standard algorithm to calculculate check digits. And genuinely disheartened when I was left staring at this explanation of the algorithm, the only one that seems to be provided by the banking sector.</p>

<p><img src="http://dnando.github.io/images/CheckDigit.gif" alt="Check digit computation module 10, recursive" /></p>

<p>If you study it for a few minutes, you&rsquo;ll see how the check digit is calculated, using the chart provided. But it doesn&rsquo;t give much of a clue what algorithm should be used to generate the check digit, except in the title, which seems to suggest it might use mod 10, recursively, if you assume that it has been translated from German incorrectly, module instead of modulo or modulus.</p>

<p>After a few sessions of Googling, I found an <a href="http://delphi.cjcsoft.net/viewthread.php?tid=48934">example someone wrote in Delphi</a> that seemed to demonstate it could be tackled rather simply, with a single array representing the entire chart. Unfortunately I couldn&rsquo;t grok some of the nuances of the syntax.</p>

<p>Then I ran across <a href="http://www.hosang.ch/modulo10.aspx">another set of examples</a> variations of C and Visual Basic. His comment at the top of the page reads:</p>

<p>Haben Sie sich auch schon über die nicht sehr programmiergerechte Beschreibung in den Unterlagen der PostFinance und der Telekurs geärgert? &hellip; which my Swiss client on this project translated as &ldquo;The descriptions from PostFinance and Telekurs are shit&hellip;&rdquo; - not at all useful for programmers.</p>

<p>The VB example looked familiar enough, and after a bit of mucking around, came up with this CFML function that seems to work to generate the check digit, passing every test I&rsquo;ve thown at it from the pay slips I have laying around.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='cfc'><span class='line'><span class="o">&lt;</span><span class="nv">cfscript</span><span class="o">&gt;</span>
</span><span class='line'>  <span class="nv">public</span> <span class="k">numeric</span> <span class="k">function</span> <span class="nf">calCheckDigit</span><span class="p">(</span> <span class="k">string</span> <span class="nv">number</span> <span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="k">var</span> <span class="nv">arrTable</span> <span class="o">=</span> <span class="p">[</span><span class="m">0</span><span class="p">,</span><span class="m">9</span><span class="p">,</span><span class="m">4</span><span class="p">,</span><span class="m">6</span><span class="p">,</span><span class="m">8</span><span class="p">,</span><span class="m">2</span><span class="p">,</span><span class="m">7</span><span class="p">,</span><span class="m">1</span><span class="p">,</span><span class="m">3</span><span class="p">,</span><span class="m">5</span><span class="p">];</span>
</span><span class='line'>      <span class="k">var</span> <span class="nv">carry</span> <span class="o">=</span> <span class="m">0</span><span class="p">;</span>
</span><span class='line'>      <span class="k">var</span> <span class="nv">i</span> <span class="o">=</span> <span class="m">1</span><span class="p">;</span>
</span><span class='line'>      <span class="k">for</span> <span class="p">(</span> <span class="nv">i</span> <span class="o">=</span> <span class="m">1</span><span class="p">;</span> <span class="nv">i</span> <span class="o">&lt;=</span> <span class="k">len</span><span class="p">(</span> <span class="nv">number</span> <span class="p">);</span> <span class="nv">i</span><span class="o">++</span> <span class="p">)</span> <span class="p">{</span>
</span><span class='line'>          <span class="nv">carry</span> <span class="o">=</span> <span class="nv">arrTable</span><span class="p">[</span> <span class="p">(</span> <span class="p">(</span> <span class="nv">carry</span> <span class="o">+</span> <span class="nf">mid</span><span class="p">(</span> <span class="nv">number</span><span class="p">,</span> <span class="nv">i</span><span class="p">,</span> <span class="m">1</span> <span class="p">)</span> <span class="p">)</span> <span class="err">%</span> <span class="m">10</span> <span class="p">)</span> <span class="o">+</span> <span class="m">1</span> <span class="p">];</span>
</span><span class='line'>      <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>      <span class="k">return</span> <span class="p">(</span> <span class="m">10</span> <span class="o">-</span> <span class="nv">carry</span> <span class="p">)</span> <span class="err">%</span> <span class="m">10</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'> <span class="o">&lt;/</span><span class="nv">cfscript</span><span class="o">&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>If you compare the VB solution with the above, you&rsquo;ll see I&rsquo;m adding 1 to each calculated index value. That&rsquo;s because ColdFusion arrays are 1-based rather than 0-based. If you happen to be using this example to build a similar function in another language that has 0 based arrays, remove the <code>+ 1</code> from line 7.</p>

<p>This function expects a string with consecutive numeric digits 0-9 only. It will blow up if any other characters are passed into it.</p>

<p>Here are some reference links for solving the more general problem of generating Swiss payment slips:</p>

<p><a href="https://www.postfinance.ch/binp/postfinance/public/dam.M26m_i6_6ceYcN2XtAN4w8OHMynQG7FKxJVK8TtQzr0.spool/content/dam/pf/de/doc/consult/manual/dlserv/inpayslip_isr_man_en.pdf">Manual ISR - Orange Inpayment Slip with reference number</a> - the clearest explanation I&rsquo;ve found regarding how the data is structured and placed on the pay slip.</p>

<p><a href="https://www.postfinance.ch/binp/postfinance/public/dam.kDeM1NfdktHxsoPgqxBgbWOwXjqUmZZMUW52ZpIhfU0.spool/content/dam/pf/de/doc/consult/manual/dldata/efin_recdescr_man_en.pdf">Record Description Electronic services</a> - the only information currently here is reproduced in the logic diagram above.</p>
]]></content>
  </entry>
  
</feed>
