Wednesday, September 02, 2009

If your Ruby app using https or some other form of SSL is complaining about:

net/http.rb:567: warning: can't set verify locations

Then you probably passed in a bogus path to your CA file or path. In my case I had:

http.ca_file = '/etc/pki/tls/certs/ca-bundle.crt'
http.verify_mode = OpenSSL::SSL::VERIFY_PEER

That path is right on Red Hat, but I was running the script on my Mac laptop. Whoops. Fixed the path to something valid and the error went away.

Monday, August 31, 2009

I've been using the workaround shown at http://blog.zenspider.com/2008/05/httpsssl-warning-cleanup.html for a while now to eliminate the "using default DH parameters" warning you get when using https in Ruby. However, I recently tried to reference two of my libraries which contained the same workaround in a script and ran into a "stack level too deep" error as the two sets of code both tried to alias the use_ssl= method. I spent some time working on this today and I think I've come up with a better method.

Net::HTTP.ssl_context_accessor(:tmp_dh_callback)
http = Net::HTTP.new('www.example.com', 443)
http.tmp_dh_callback = proc {
OpenSSL::PKey::DH.new(IO.read('dhparams')) }
http.use_ssl = true

There are a few options for how you create the Diffie-Hellman params. The code above assumes you've got a file with pre-generated params (this is perfectly acceptable from a security standpoint). You can create the file with the "openssl dhparam" command, or a little Ruby script. You could also generate the DH params on the fly, although this can be quite slow:

Net::HTTP.ssl_context_accessor(:tmp_dh_callback)
http = Net::HTTP.new('www.example.com', 443)
http.tmp_dh_callback = proc { OpenSSL::PKey::DH.new(2048) }
http.use_ssl = true

Or if you just want the warning to go away and aren't concerned about the security implications you can just use as empty proc as zenspider did. I've tried to look at the Ruby OpenSSL library source and figure out what happens when the proc doesn't return anything but the code is a bit too obtuse for me to figure out.

Net::HTTP.ssl_context_accessor(:tmp_dh_callback)
http = Net::HTTP.new('www.example.com', 443)
http.tmp_dh_callback = proc {}
http.use_ssl = true

Tuesday, August 25, 2009

Excel on the Mac defaults to portrait mode. Nearly all spreadsheets I create I want in landscape and finally tracked down how to set this as the default.

  • Open up a new document
  • Set it to landscape via File -> Page Setup
  • Go to File -> Save As
  • Switch to the /Applications/Microsoft Office 2008/Office/Startup/Excel folder
  • Set the filename to Workbook
  • Uncheck the Append file extension checkbox
  • Save
  • Quit and restart Excel

Your workbooks should now be landscape by default.

You can find this in the Excel help. Don't use the Help menu item on the main Mac menu bar, Excel's help isn't available there. Instead click the Help button on the toolbar in an Excel document to bring up the Excel help system and look for the "Control how workbooks and sheets are created" document, available under Contents -> Customizing Excel.

Friday, July 24, 2009

How to insert a new line above the current line in TextMate? A la capital O in vi? I couldn't find it in the TextMate book, nor searching around online. A few seconds of fiddling on the keyboard turned it up though: command-option-return

This makes sense, as command-return inserts a new line below the current line. Having now looked around some more this command-option-return key sequence is documented as "move to end of line and insert end-of-line symbol", e.g. a semicolon in C or Perl. Conveniently, in Ruby and presumably other languages with no end-of-line symbol it has been redefined to the "new line above current line behavior". It's disappointing that there isn't a universal shortcut.

Thursday, June 18, 2009

Update: SourceForge no longer offers the Wikispaces wiki, this post is left up for historical curiosity.

The default wiki for SourceForge projects is used to be called Wikispaces. The CSS stylesheet configuration on the SourceForge Wikispaces is such that list items (HTML "li") are smaller than normal, and shrink as they are nested. Top level list items are smaller than I would care for, and by three or four levels of nesting they are unreadable. This has bugged me for a while, but today I was trying to create a page which had up to five or so levels of nesting (to represent a directory tree) and decided to see if I could fix this.

Using the wonderful Web Developer extension for Firefox I was able to pinpoint the source of this shrinkage, this line of http://static.sourceforge.net/css/sfx.php?secure=0&20080417-1657:

#frame li, #fadbtm li { font-size: 82.3%; }

Wikispaces uses about five CSS stylesheets including sfx.php, and they allow you to edit one of the other CSS stylesheets under Manage Space -> Look and Feel -> Edit your wiki stylesheet.

When editing that stylesheet Wikispaces restricts you to applying styles to the "wiki" class. Your wiki content is placed in an HTML div of class "wiki" and id "content_view". So I tried to add a line to the stylesheet which sets the font size for list items in class "wiki":

.wiki li { font-size: 100% }

However, there is a higher level div with id "frame" which the Wikispaces-provided CSS line applies to. Per the CSS specification styles applied to a specific id (#frame) take precedence over styles applied to a class (.wiki). As such the style for the id "frame" overrides my style for the "wiki" class.

Another read through the CSS spec reveals the important flag to override the normal priorities. And that did the trick, adding the following line eliminates the shrinking list items:

.wiki li { font-size: 100% ! important }

Monday, May 04, 2009

With the Oracle client 10.2.0.1.0 installer if you are automating the install with a response file, set UNIX_GROUP_NAME to something like say 'dba', then run the install but you are not in the dba group the install will fail with:

SEVERE:S_OWNER_SYSTEM_EPERM

I found nothing useful via a search for that error so I thought I'd post something. It would seem that you need to set UNIX_GROUP_NAME to a group you are in. Oddly none of the files that are written out end up owned by that group, so it doesn't seem like the installer really needs those privileges.

I'm trying to package the Oracle client for our internal packaging system, I'm not a DBA and wouldn't normally be a member of the dba group.

Friday, April 24, 2009

I was working on building the mysql ruby gem. My mysql install is in a non-standard location. I could get the gem to build with syntax like:

gem install mysql -- --with-mysql-config=/path/to/bin/mysql_config

However, I noticed that the resulting library did not embed the path to the mysql library, ldd on the mysql.so indicated:

libmysqlclient.so.16 => not found

I did not want to have to fiddle with setting an LD_LIBRARY_PATH at runtime. The way to address this is to pass -R or -rpath to the linker at compile time to embed the path to the library. The mysql gem uses the standard extconf.rb to build a Makefile to build the library. extconf.rb uses the standard Ruby mkmf library to do the heavy lifting. Thanks to the woeful lack of documentation for mkmf it took me several hours to figure out how to convince mkmf to include the proper option in the compiler flags. The answer is:

gem install mysql -- --with-mysql-config=/path/to/bin/mysql_config --with-dldflags="-Wl,-rpath,/path/to/lib/mysql"

--with-dldflags appends anything you specify to the DLDFLAGS variable in the generated Makefile. FYI, --with-ldflags overwrites DLDFLAGS with what you specify, possibly wiping out other linker flags you want to keep. Also FYI, the -Wl,-rpath,etc. syntax is required to pass the linker option through the compiler.

ldd now shows that the path is embeded in the resulting mysql.so:

libmysqlclient.so.16 => /path/to/lib/mysql/libmysqlclient.so.16 (0x00002ad5e81d1000)

Thursday, March 12, 2009

Speaking of Perl, Ruby and sorting, sort in both Perl and Ruby allow you to specify a code block to implement your own arbitrary sorting routine. Perl's documentation shows you how you can define this as a subroutine and just reference the subroutine when you call sort. This is handy both for re-use and when your sort routine is complex and doesn't easily fit on one line. Ruby's sort documentation? Eh, no mention of such a thing.

In fact it is possible, but delves into a whole area of Ruby that is somewhat under-documented. The trick is that sort wants a code block, but code blocks are not first class entities. You can't name and reference a code block. However, Ruby has a couple of similar entities, Proc and lambda, that can be converted to/from code blocks and can be named and referenced. The unary ampersand operator will convert a Proc or lambda to a code block. The syntax works like this:

names = [
  {:fname => 'John', :lname => 'Smith'},
  {:fname => 'Jane', :lname => 'Smith'} ]


sorter = lambda do |a,b|
  [a[:lname], a[:fname]] <=> [b[:lname], b[:fname]]
end

names.sort(&sorter)

Wednesday, March 11, 2009

When sorting complex structures in Perl is is common to use syntax like:

sort { $lname{$a} <=> $lname{$b} || $fname{$a} <=> $fname{$b} } @names

The Perl sort documentation lists examples with this syntax. True to form the Ruby sort documentation doesn't show examples of anything that complex. Best I can tell anything like this doesn't work in Ruby:

a <=> b || c <=> d

Any way I write that I get back the result of the first comparison, even if the result is zero (which should trigger a fall-through to the second comparison).

Since Ruby's Array implements <=> you can achieve the desired result with:

[a, c] <=> [b, d]

Wednesday, March 04, 2009

A couple of MacPorts errors I just encountered:

Error: Unable to execute port: can't read "frameworks_dir": no such variable

I had version 1.6 and it seems the recommendation to fix this is to update to 1.7 (via port selfupdate). I started port in interactive mode, ran selfupdate, then tried my install again and got:

Error: Unable to open port: can't read "porturl": no such variable

I wasn't sure if it was necessary, so I ran 'sync' at this point. The install then failed with:

Error: Unable to execute port: can't read "PortInfo(name)": no such element in array

Couldn't find any info about that online, so on a lark I exited port and restarted it, after which the install proceeded.

Thursday, January 15, 2009

It's a mystery to me why the FreeBSD folks don't publish this better (for example, a mention on http://www.freebsd.org/security/ doesn't seem unreasonable), but FreeBSD has an easy to use system for updating the base system:

# freebsd-update fetch

Review the changes to be applied, then

# freebsd-update install

If there's a new kernel in there then you should reboot. That's it. Not quite sure when this was fully integrated into the base OS, I'm only an occasional FreeBSD user, you used to have to install a few ports to get this working.

Even their official security advisories don't mention this, instead referring to PITA methods of patching and building from source. I installed the OS via pre-built binaries, why would I then update by patching the source? Sigh.

Tuesday, January 06, 2009

Went looking around today for a way to generate charts/graphs in my Rails apps. Wow are there a lot of choices.

The executive summary is that I'm going to use the first Open Flash Chart plugin listed. I'm adding charts mainly for the "wow, neat" effect and the Flash charts max out that aspect. It seems like I might be able to work around the problems with printing. My second choice would probably be the ProtoChart Javascript library.

Plugins that generate images and/or SVG files:

Gruff
Scruffy

There are a couple of problems with these. Both use the RMagick library to generate images. RMagick is a Ruby wrapper around ImageMagick. So you're stuck with installing native dependencies (ImageMagick and all its dependencies) outside of Rails/Gems. And because you're providing the chart as a separate file you have to deal with sending the client a URL for the chart that comes back to your controller to generate the chart. There are probably neat Rails ways to handle that cleanly, but neither plugin seems to offer any best practices in their docs. I've also heard rumors that the RMagick/ImageMagick combo leaks memory like a sieve, but can't confirm that.

Plugins that use the Google Chart API:

Googlecharts
gchartrb
Google Charts on Rails

These all leave you dependent on connectivity and latency to Google.

Plugins that generate graphs using CSS/HTML:

css_graphs

There's only so much you can do in pure CSS/HTML, so this approach is fairly limited. If your needs are confined to basic bar charts this is a minimal-headache approach.

JavaScript libraries, particularly ones that work with Prototype since it is included with Rails:

Plotr
Flotr
ProtoChart

These are all pure JavaScript, so you're stuck dinking around in that instead of Ruby. There's a Rails wrapper for Plotr:

Chartr

Development of the JavaScript libraries and the Ruby library all seems largely stalled.

Plugins that generate Flash charts:

Wrappers for Open Flash Chart:

Open Flash Chart II Plugin for Ruby on Rails
Open Flash Chart Lazy
OFC2 4 Rails

These flash charts are the most visually interesting, as they are often animated and interactive, doing various cute (and maybe useful) things on mouse-over, etc. However, they leave you dependent on the client supporting/enabling Flash. It is also difficult/impossible to print the chart. You might also have the same issues as the image/SVG charts of having to generate a unique URL for the chart, although the author of the first plugin listed has a blog post that shows how to handle that in a very clean, Rails-like fashion.

Wrapper for XML/SWF:

ZiYa

Wrapper for amCharts:

Ambling

XML/SWF and amCharts are both demoware so I did not pursue these options.