<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="en-US">
  <id>tag:blog.segment7.net,2005:/articles</id>
  <link type="text/html" rel="alternate" href="http://blog.segment7.net" />
  
  <title>Segment7</title>
  <subtitle type="html">The Blog</subtitle>
  <updated>2012-02-20T17:18:20-08:00</updated>
  <generator uri="http://www.typosphere.org" version="5.x">Typo</generator>
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/Segment7" /><feedburner:info uri="segment7" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-sa/3.0/" /><entry>
    <id>tag:blog.segment7.net,2005:Article/1329</id>
    <published>2012-02-20T17:18:20-08:00</published>
    <updated>2012-02-20T17:18:20-08:00</updated>
    <link type="text/html" rel="alternate" href="http://feedproxy.google.com/~r/Segment7/~3/TZXDtcXnlyU/mechanize-2-3" />
    <author>
      <name>drbrain</name>
    </author>
    <title type="html">mechanize 2.3</title>
    <category term="software" label="Software" scheme="http://blog.segment7.net/category/software" />
    <content type="html">&lt;ul&gt;&lt;li&gt;
&lt;p&gt;&lt;a href="http://mechanize.rubyforge.org"&gt;mechanize.rubyforge.org&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;&lt;a
href="https://github.com/tenderlove/mechanize"&gt;github.com/tenderlove/mechanize&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;The Mechanize library is used for automating interaction with websites.
Mechanize automatically stores and sends cookies, follows redirects, and
can follow links and submit forms.  Form fields can be populated and
submitted.  Mechanize also keeps track of the sites that you have visited
as a history.&lt;/p&gt;

&lt;h3 id="label-2.3+%2F+2012-02-20"&gt;2.3 / 2012-02-20&lt;/h3&gt;
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;Minor enhancement&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;Add support for the Max-Age attribute in the Set-Cookie header.&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Added Mechanize::Download#body for compatibility with Mechanize::File when
using Mechanize#get_file with Mechanize::Image or other Download-based
pluggable parser.  Issue #202 by angas&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Mechanize#max_file_buffer may be set to nil to disable creation of
Tempfiles.&lt;/p&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Bug fixes&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;Applied Mechanize#max_file_buffer to the Content-Encoding handlers as well
to prevent extra Tempfiles for small gzip or deflate response&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Increased the default Mechanize#max_file_buffer to 100,000 bytes.  This
gives ~5MB of response bodies in memory with the default history setting of
50 pages (depending on GC behavior).&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Ignore empty path/domain attributes.&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Cookies with an empty Expires attribute value were stored as session
cookies but cookies without the Expires attribute were not.  Issue #78&lt;/p&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;&lt;/ul&gt;


&lt;img src="http://feeds.feedburner.com/~r/Segment7/~4/TZXDtcXnlyU" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.segment7.net/2012/02/20/mechanize-2-3</feedburner:origLink></entry>
  <entry>
    <id>tag:blog.segment7.net,2005:Article/1328</id>
    <published>2012-02-16T13:39:01-08:00</published>
    <updated>2012-02-16T13:39:01-08:00</updated>
    <link type="text/html" rel="alternate" href="http://feedproxy.google.com/~r/Segment7/~3/iHoZBaMUPu0/ten-years-of-seattle-rb" />
    <author>
      <name>drbrain</name>
    </author>
    <title type="html">Ten Years of Seattle.rb</title>
    <category term="seattle-rb" label="Seattle.rb" scheme="http://blog.segment7.net/category/seattle-rb" />
    <content type="html">&lt;p&gt;We're throwing a part for the tenth anniversary of the &lt;a href="http://seattlerb.org"&gt;Seattle Ruby Brigade&lt;/a&gt;&amp;#8252;

&lt;p&gt;The party will be on February 28th from 7PM to 10PM at &lt;a href="http://substantial.com/"&gt;Substantial&lt;/a&gt;'s offices.  You can get your ticket for the low, low price of just $10 &lt;a href="http://rubybrigade10-zvents.eventbrite.com/"&gt;right here&lt;/a&gt;&amp;#8252;

&lt;p&gt;If you would like to learn more about the history of Seattle.rb, check out &lt;a href="http://www.youtube.com/watch?v=ICVdf4WidkY"&gt;Aaron's presentation from RubyConf 2008&lt;/a&gt;.

&lt;img src="http://feeds.feedburner.com/~r/Segment7/~4/iHoZBaMUPu0" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.segment7.net/2012/02/16/ten-years-of-seattle-rb</feedburner:origLink></entry>
  <entry>
    <id>tag:blog.segment7.net,2005:Article/1327</id>
    <published>2012-02-13T16:00:22-08:00</published>
    <updated>2012-02-13T16:00:22-08:00</updated>
    <link type="text/html" rel="alternate" href="http://feedproxy.google.com/~r/Segment7/~3/8SHvTpqgjzc/mechanize-2-2" />
    <author>
      <name>drbrain</name>
    </author>
    <title type="html">mechanize 2.2</title>
    <category term="software" label="Software" scheme="http://blog.segment7.net/category/software" />
    <content type="html">&lt;ul&gt;&lt;li&gt;
&lt;p&gt;&lt;a href="http://mechanize.rubyforge.org"&gt;mechanize.rubyforge.org&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;&lt;a
href="http://github.com/tenderlove/mechanize/tree/master"&gt;github.com/tenderlove/mechanize/tree/master&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;The Mechanize library is used for automating interaction with websites.
Mechanize automatically stores and sends cookies, follows redirects, can
follow links, and submit forms.  Form fields can be populated and
submitted.  Mechanize also keeps track of the sites that you have visited
as a history.&lt;/p&gt;

&lt;h3 id="label-2.2+%2F+2012-02-12"&gt;2.2 / 2012-02-12&lt;/h3&gt;
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;API changes&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;MetaRefresh#href is not normalized to an absolute URL, but set to the
original value and resolved later.  It is even set to nil when the Refresh
URL is unspecified or empty.&lt;/p&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Minor enhancements&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;Expose ssl_version from net-http-persistent.  Patch by astera.&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;SSL parameters and proxy may now be set at any time.  Issue #194 by
dsisnero.&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Improved Mechanize::Page with #image_with and #images_with and
Mechanize::Page::Image various img element attribute accessors, #caption,
#extname, #mime_type and #fetch.  Pull request #173 by kitamomonga&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Added MIME type parsing for content-types in Mechanize::PluggableParser for
fine-grained parser choices.  Parsers will be chosen based on exact match,
simplified type or media type in that order.  See
Mechanize::PluggableParser#[]=.&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Added Mechanize#download which downloads a response body to an IO-like or
filename.&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Added Mechanize::DirectorySaver which saves responses in a single
directory.  Issue #187 by yoshie902a.&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Added Mechanize::Page::Link#noreferrer?&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;The documentation for Mechanize::Page#search and #at now show that both
XPath and CSS expressions are allowed.  Issue #199 by Shane Becker.&lt;/p&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Bug fixes&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;Fixed handling of a HEAD request with Accept-Encoding: gzip.  Issue #198 by
Oleg Dashevskii&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Use #resolve for resolving a Location header value.  fixes #197&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;A Refresh value can have whitespaces around the semicolon and equal sign.&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;MetaRefresh#click no longer sends out Referer.&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;A link with an empty href is now resolved correctly where previously the
query part was dropped.&lt;/p&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;&lt;/ul&gt;


&lt;img src="http://feeds.feedburner.com/~r/Segment7/~4/8SHvTpqgjzc" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.segment7.net/2012/02/13/mechanize-2-2</feedburner:origLink></entry>
  <entry>
    <id>tag:blog.segment7.net,2005:Article/1326</id>
    <published>2012-02-07T15:47:19-08:00</published>
    <updated>2012-02-07T15:47:19-08:00</updated>
    <link type="text/html" rel="alternate" href="http://feedproxy.google.com/~r/Segment7/~3/5rUk8kCeMl0/net-http-persistent-2-5" />
    <author>
      <name>drbrain</name>
    </author>
    <title type="html">net-http-persistent 2.5</title>
    <category term="software" label="Software" scheme="http://blog.segment7.net/category/software" />
    <content type="html">
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;&lt;a
href="http://docs.seattlerb.org/net-http-persistent"&gt;docs.seattlerb.org/net-http-persistent&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;&lt;a
href="https://github.com/drbrain/net-http-persistent"&gt;github.com/drbrain/net-http-persistent&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Manages persistent connections using Net::HTTP plus a speed fix for Ruby
1.8. It&amp;rsquo;s thread-safe too!&lt;/p&gt;

&lt;p&gt;Using persistent HTTP connections can dramatically increase the speed of
HTTP. Creating a new HTTP connection for every request involves an extra
TCP round-trip and causes TCP congestion avoidance negotiation to start
over.&lt;/p&gt;

&lt;p&gt;Net::HTTP supports persistent connections with some API methods but does
not handle reconnection gracefully.  Net::HTTP::Persistent supports
reconnection and retry according to RFC 2616.&lt;/p&gt;

&lt;h3 id="label-2.5+%2F+2012-02-07"&gt;2.5 / 2012-02-07&lt;/h3&gt;
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;Minor enhancements&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;The proxy may be changed at any time.&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;The allowed SSL version may now be set via #ssl_version. Issue #16 by
astera&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Added Net::HTTP::Persistent#override_headers which allows overriding&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Net::HTTP default headers like User-Agent.  See
Net::HTTP::Persistent@Headers for details.  Issue #17 by andkerosine&lt;/p&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Bug fixes&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;The ruby 1.8 speed monkeypatch now handles EAGAIN for windows users. Issue
#12 by Alwyn Schoeman&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Fixed POST example in README.  Submitted by injekt.&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Fixed various bugs in the shutdown of connections especially cross-thread
(which you shouldn&amp;rsquo;t be doing anyways).&lt;/p&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;&lt;/ul&gt;


&lt;img src="http://feeds.feedburner.com/~r/Segment7/~4/5rUk8kCeMl0" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.segment7.net/2012/02/07/net-http-persistent-2-5</feedburner:origLink></entry>
  <entry>
    <id>tag:blog.segment7.net,2005:Article/1325</id>
    <published>2012-02-03T17:57:15-08:00</published>
    <updated>2012-02-03T17:57:15-08:00</updated>
    <link type="text/html" rel="alternate" href="http://feedproxy.google.com/~r/Segment7/~3/Ti4FKbI_9aE/mechanize-2-1-1" />
    <author>
      <name>drbrain</name>
    </author>
    <title type="html">mechanize 2.1.1</title>
    <category term="software" label="Software" scheme="http://blog.segment7.net/category/software" />
    <content type="html">
&lt;p&gt;mechanize version 2.1.1 has been released!&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;&lt;a href="http://mechanize.rubyforge.org"&gt;mechanize.rubyforge.org&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;&lt;a
href="http://github.com/tenderlove/mechanize/tree/master"&gt;github.com/tenderlove/mechanize/tree/master&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;The Mechanize library is used for automating interaction with websites.
Mechanize automatically stores and sends cookies, follows redirects, can
follow links, and submit forms.  Form fields can be populated and
submitted.  Mechanize also keeps track of the sites that you have visited
as a history.&lt;/p&gt;

&lt;h3 id="label-2.1.1+%2F+2010-02-03"&gt;2.1.1 / 2010-02-03&lt;/h3&gt;
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;Bug fixes&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;Set missing idle_timeout default.  Issue #196&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Meta refresh URIs are now escaped (excluding %).  Issue #177&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Fix charset name extraction.  Issue #180&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;A Referer URI sent on request no longer includes user information or
fragment part.&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Tempfiles for storing response bodies are unlinked upon creation to avoid
possible lack of finalization.  Issue #183&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;The default maximum history size is now 50 pages to avoid filling up a disk
with tempfiles accidentally.  Related to Issue #183&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Errors in bodies with deflate and gzip responses now result in a
Mechanize::Error instead of silently being ignored and causing future
errors.  Issue #185&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Mechanize now raises an UnauthorizedError instead of crashing when a 403
response does not contain a www-authenticate header.  Issue #181&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Mechanize gives a useful exception when attempting to click buttons across
pages.  Issue #186&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Added note to Mechanize#cert_store describing how to add certificates in
case your system does not come with a default set.  Issue #179&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Invalid content-disposition headers are now ignored.  Issue #191&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Fix NTLM by recognizing the &amp;ldquo;Negotiation&amp;rdquo; challenge instead of
endlessly looping.  Issue #192&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Allow specification of the NTLM domain through Mechanize#auth.  Issue #193&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Documented how to convert a Mechanize::ResponseReadError into a File or
Page, along with a new method #force_parse.  Issue #176&lt;/p&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;&lt;/ul&gt;


&lt;img src="http://feeds.feedburner.com/~r/Segment7/~4/Ti4FKbI_9aE" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.segment7.net/2012/02/03/mechanize-2-1-1</feedburner:origLink></entry>
  <entry>
    <id>tag:blog.segment7.net,2005:Article/1324</id>
    <published>2012-02-03T17:55:59-08:00</published>
    <updated>2012-02-03T17:55:59-08:00</updated>
    <link type="text/html" rel="alternate" href="http://feedproxy.google.com/~r/Segment7/~3/hI6cg8G-ghY/net-http-persistent-2-4-1" />
    <author>
      <name>drbrain</name>
    </author>
    <title type="html">net-http-persistent 2.4.1 </title>
    <category term="software" label="Software" scheme="http://blog.segment7.net/category/software" />
    <content type="html">&lt;ul&gt;&lt;li&gt;
&lt;p&gt;&lt;a
href="http://docs.seattlerb.org/net-http-persistent"&gt;docs.seattlerb.org/net-http-persistent&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;&lt;a
href="https://github.com/drbrain/net-http-persistent"&gt;github.com/drbrain/net-http-persistent&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Manages persistent connections using Net::HTTP plus a speed fix for Ruby
1.8. It&amp;rsquo;s thread-safe too!&lt;/p&gt;

&lt;p&gt;Using persistent HTTP connections can dramatically increase the speed of
HTTP. Creating a new HTTP connection for every request involves an extra
TCP round-trip and causes TCP congestion avoidance negotiation to start
over.&lt;/p&gt;

&lt;p&gt;Net::HTTP supports persistent connections with some API methods but does
not handle reconnection gracefully.  Net::HTTP::Persistent supports
reconnection and retry according to RFC 2616.&lt;/p&gt;

&lt;h3 id="label-2.4.1+%2F+2012-02-03"&gt;2.4.1 / 2012-02-03&lt;/h3&gt;
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;Bug fixes&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;When FakeWeb or WebMock are loaded SSL sessions will not be reused to
prevent breakage of testing frameworks.  Issue #13 by Matt Brictson, pull
request #14 by Zachary Scott&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;SSL connections are reset when the SSL parameters change. Mechanize issue
#194 by dsisnero&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Last-use times are now cleaned up in #shutdown.&lt;/p&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;&lt;/ul&gt;


&lt;img src="http://feeds.feedburner.com/~r/Segment7/~4/hI6cg8G-ghY" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.segment7.net/2012/02/03/net-http-persistent-2-4-1</feedburner:origLink></entry>
  <entry>
    <id>tag:blog.segment7.net,2005:Article/1323</id>
    <published>2012-01-31T15:58:10-08:00</published>
    <updated>2012-01-31T15:58:10-08:00</updated>
    <link type="text/html" rel="alternate" href="http://feedproxy.google.com/~r/Segment7/~3/F07nkPBF60g/net-http-persistent-2-4" />
    <author>
      <name>drbrain</name>
    </author>
    <title type="html">net-http-persistent 2.4</title>
    <category term="software" label="Software" scheme="http://blog.segment7.net/category/software" />
    <content type="html">
&lt;p&gt;net-http-persistent version 2.4 has been released!&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;&lt;a
href="http://docs.seattlerb.org/net-http-persistent"&gt;docs.seattlerb.org/net-http-persistent&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;&lt;a
href="https://github.com/drbrain/net-http-persistent"&gt;github.com/drbrain/net-http-persistent&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;Manages persistent connections using Net::HTTP plus a speed fix for Ruby
1.8. It&amp;rsquo;s thread-safe too!&lt;/p&gt;

&lt;p&gt;Using persistent HTTP connections can dramatically increase the speed of
HTTP. Creating a new HTTP connection for every request involves an extra
TCP round-trip and causes TCP congestion avoidance negotiation to start
over.&lt;/p&gt;

&lt;p&gt;Net::HTTP supports persistent connections with some API methods but does
not handle reconnection gracefully.  Net::HTTP::Persistent supports
reconnection and retry according to RFC 2616.&lt;/p&gt;

&lt;h3 id="label-2.4+%2F+2012-01-31"&gt;2.4 / 2012-01-31&lt;/h3&gt;
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;Minor Enhancement&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;net-http-persistent now complains if OpenSSL::SSL::VERIFY_PEER is equal to
OpenSSL::SSL::VERIFY_NONE.  If you have a platform that is broken this way
you must define the constant:&lt;/p&gt;

&lt;pre&gt;I_KNOW_THAT_OPENSSL_VERIFY_PEER_EQUALS_VERIFY_NONE_IS_WRONG = nil&lt;/pre&gt;

&lt;p&gt;at the top level of your application to disable the warning.&lt;/p&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Bug fix&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;Fix persisting SSL sessions through HTTP proxies.  Mechanize issue #178 by
Robert Poor, net-http-persistent issues #10, #11.&lt;/p&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;&lt;/ul&gt;


&lt;img src="http://feeds.feedburner.com/~r/Segment7/~4/F07nkPBF60g" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.segment7.net/2012/01/31/net-http-persistent-2-4</feedburner:origLink></entry>
  <entry>
    <id>tag:blog.segment7.net,2005:Article/1322</id>
    <published>2012-01-11T14:04:16-08:00</published>
    <updated>2012-01-11T17:18:33-08:00</updated>
    <link type="text/html" rel="alternate" href="http://feedproxy.google.com/~r/Segment7/~3/_p4LYyt4nB4/forever-valid-ssl-certificates" />
    <author>
      <name>drbrain</name>
    </author>
    <title type="html">Forever-valid SSL certificates</title>
    <category term="misc" label="Misc" scheme="http://blog.segment7.net/category/misc" />
    <category term="ruby" label="Ruby" scheme="http://blog.segment7.net/category/ruby" />
    <content type="html">&lt;p&gt;If your library uses X509 cryptography, naturally your tests will need a key and valid certificate to test against.  Creating a key and certificate frequently can quickly drain your entropy pool which slows down your tests.

&lt;p&gt;Instead of creating the key for every test startup you can create it once and load it off the disk like this:

&lt;pre&gt;&lt;code&gt;class TestMyGem &lt; MyGem::TestCase
  private_key = File.expand_path '../../../test/private_key.pem', __FILE__
  private_key = File.read private_key
  PRIVATE_KEY = OpenSSL::PKey::RSA.new private_key

  # &amp;#8230;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Sure, you can rebuild the certificate every time with a validity time of an hour, but why not create a forever-valid certificate to go with it?  No reasonable person would ever use a key shipped with an open project anyhow.  Here's how to generate such a key and certificate:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'openssl'

# purposefully short key length
key = OpenSSL::PKey::RSA.new 512

# bogus subject and issuer
name = OpenSSL::X509::Name.parse 'CN=nobody/DC=example'
cert = OpenSSL::X509::Certificate.new
cert.subject = name
cert.issuer = name
cert.version = 2
cert.serial = 1
cert.not_before = Time.now

# lasts as long as X509 allows
cert.not_after = Time.gm 9999, 12, 31, 23, 59, 59
cert.public_key = key.public_key

cert.sign key, OpenSSL::Digest::SHA1.new

open 'private_key.pem', 'w' do |io| io.write key.to_pem end
open 'public_cert.pem', 'w' do |io| io.write cert.to_pem end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can load this certificate just like the key as described above:

&lt;pre&gt;&lt;code&gt;  public_cert = File.expand_path '../../../test/public_cert.pem', __FILE__
  public_cert = File.read public_cert
  PUBLIC_CERT = OpenSSL::X509::Certificate.new public_cert&lt;/code&gt;&lt;/pre&gt;


&lt;img src="http://feeds.feedburner.com/~r/Segment7/~4/_p4LYyt4nB4" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.segment7.net/2012/01/11/forever-valid-ssl-certificates</feedburner:origLink></entry>
  <entry>
    <id>tag:blog.segment7.net,2005:Article/1321</id>
    <published>2012-01-10T10:37:50-08:00</published>
    <updated>2012-01-10T10:37:50-08:00</updated>
    <link type="text/html" rel="alternate" href="http://feedproxy.google.com/~r/Segment7/~3/bY3oFtzWdtA/replace-your-test-helpers-with-reusable-api" />
    <author>
      <name>drbrain</name>
    </author>
    <title type="html">Replace your test helpers with reusable API</title>
    <category term="ruby" label="Ruby" scheme="http://blog.segment7.net/category/ruby" />
    <category term="testing" label="Testing" scheme="http://blog.segment7.net/category/testing" />
    <content type="html">&lt;p&gt;&lt;code&gt;test/test_helper.rb&lt;/code&gt; is a great idea Rails brought to the Ruby world as a place for functionality that helps you write better tests.  There's now a standard place for you to implement common setup/teardown, shortcuts and custom assertions.  However, a test helper is not the best place to store this functionality for a Ruby library.

&lt;p&gt;One of the benefits you get out of writing tests is knowing where your API is clumsy and inadequate.  If you have a test helper file full of methods to make your library easy to use in a test why is that not part of your library's API?  Wouldn't your users also want a bunch of methods that make your library easier to use in their applications?

&lt;p&gt;For example, in RubyGems we have a test helper that does this: &lt;code&gt;gem_file = Gem::Builder.new(spec).build&lt;/code&gt; which is a little silly.  Every time you create a &lt;code&gt;Gem::Builder&lt;/code&gt; you want to build a gem.  You don't create a Gem::Builder object for fun!  To help out RubyGems users I added a new method: &lt;code&gt;gem_file = Gem::Builder.build spec&lt;/code&gt; which immediately creates and builds them gem which is much nicer for everyone (but really, you should &lt;a href="http://blog.segment7.net/2011/12/09/packaging-from-a-gemspec-is-not-the-best-way"&gt;use Gem::PackageTask&lt;/a&gt; when building gems).

&lt;p&gt;Whether you're writing a library or a Rails app, this kind of functionality belongs in your library (or application) code, not in the test helper where only your tests can benefit from it.

&lt;p&gt;Even after you improve your API by moving helpful functionality back into your library there's still going to be some things that only make sense for tests.  For example, you probably don't want to type &lt;code&gt;t = Some::Deeply::Namespaced::Thing.new 1, 2, 3&lt;/code&gt; many, many times in your tests, so you write a short wrapper method you can call like this: &lt;code&gt;t = thing 1, 2, 3&lt;/code&gt;.  Your tests may need setup and teardown to maintain a clean environment between tests, custom assertions for readability or you may want to include a pre-built stub or mock.

&lt;p&gt;While this having this functionality in a test helper is fine for a Rails app, it shouldn't go in a library's test helper.  When you keep testing functionality hidden in the test directory a user who wants to write a third-party extension for your gem can't access them.  Why force a happy user to re-implement (possibly poorly or incorrectly) the work you've done to have nice, clean tests that are easy to read and write?

&lt;p&gt;Instead of having a private test helper I have a public test case like &lt;code&gt;MyGem::TestCase&lt;/code&gt; that lives in &lt;code&gt;lib/my_gem/test_case.rb&lt;/code&gt;.  This gives anyone who wants to extend my libraries a documented, ready-to-go API for writing tests for their extension.

&lt;p&gt;My gem-specific test case typically contains all the requires needed to load the library (ideally &lt;code&gt;require 'my_gem'&lt;/code&gt;), proper setup and teardown to sandbox the tests, any utility methods that don't belong in the library itself and possibly some custom assertions.  This makes a brand new test easy to start:

&lt;pre&gt;&lt;code&gt;require 'my_gem/test_case'

class TestMyGemSomeClass &lt; MyGem::TestCase
  def setup
    super

    # &amp;#8230;
  end

  def test_something
    # &amp;#8230;
  end
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There is the minor downside that an extension writer must use minitest (my preferred testing library) to test their extension.  Perhaps this inconvenience could be solved by a module providing setup, teardown and shortcuts that is included in the proper place for the extension writer's favorite testing library.

&lt;p&gt;PS: Actually, &lt;code&gt;Gem::Builder.build&lt;/code&gt; is &lt;code&gt;Gem::Package.build&lt;/code&gt; since Gem::Format, Gem::Builder and Gem::Package are getting merged into one convenient class that deals with reading and writing gem files for RubyGems 2.0.  This means there will only be one place to look for the API of messing with packages and it reduces the implementation of &lt;code&gt;Gem::Installer&lt;/code&gt; a bit.

&lt;img src="http://feeds.feedburner.com/~r/Segment7/~4/bY3oFtzWdtA" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.segment7.net/2012/01/10/replace-your-test-helpers-with-reusable-api</feedburner:origLink></entry>
  <entry>
    <id>tag:blog.segment7.net,2005:Article/1320</id>
    <published>2011-12-20T16:52:48-08:00</published>
    <updated>2011-12-20T16:52:48-08:00</updated>
    <link type="text/html" rel="alternate" href="http://feedproxy.google.com/~r/Segment7/~3/Z8kVS7DZWts/return_bang-1-0" />
    <author>
      <name>drbrain</name>
    </author>
    <title type="html">return_bang 1.0</title>
    <category term="software" label="Software" scheme="http://blog.segment7.net/category/software" />
    <content type="html">
&lt;p&gt;return_bang version 1.0 has been released!&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;&lt;a
href="http://docs.seattlerb.org/return_bang"&gt;docs.seattlerb.org/return_bang&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;&lt;a
href="https://github.com/drbrain/return_bang"&gt;github.com/drbrain/return_bang&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;return_bang implements non-local exits from methods.  Use return_bang to
exit back to a processing loop from deeply nested code, or just to confound
your enemies &lt;strong&gt;and&lt;/strong&gt; your friends!  What could possibly go
wrong?&lt;/p&gt;

&lt;h3 id="label-Features"&gt;Features&lt;/h3&gt;
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;Implements non-local exits for methods&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Nestable&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Named and stack-based exit points, go exactly where you need to be&lt;/p&gt;
&lt;/li&gt;&lt;li&gt;
&lt;p&gt;Ignores pesky ensure blocks for when you really, really need to return&lt;/p&gt;
&lt;/li&gt;&lt;/ul&gt;

&lt;h3 id="label-Synopsis"&gt;Synopsis&lt;/h3&gt;

&lt;pre class="ruby"&gt;&lt;span class="ruby-identifier"&gt;require&lt;/span&gt; &lt;span class="ruby-string"&gt;'return_bang/everywhere'&lt;/span&gt;

&lt;span class="ruby-keyword"&gt;def&lt;/span&gt; &lt;span class="ruby-identifier"&gt;some_method&lt;/span&gt;
  &lt;span class="ruby-identifier"&gt;deeply_nested&lt;/span&gt;
  &lt;span class="ruby-comment"&gt;# never reached&lt;/span&gt;
&lt;span class="ruby-keyword"&gt;end&lt;/span&gt;

&lt;span class="ruby-keyword"&gt;def&lt;/span&gt; &lt;span class="ruby-identifier"&gt;deeply_nested&lt;/span&gt;
  &lt;span class="ruby-identifier"&gt;return!&lt;/span&gt;
&lt;span class="ruby-keyword"&gt;end&lt;/span&gt;

&lt;span class="ruby-identifier"&gt;return_here&lt;/span&gt; &lt;span class="ruby-keyword"&gt;do&lt;/span&gt;
  &lt;span class="ruby-identifier"&gt;some_method&lt;/span&gt;
&lt;span class="ruby-keyword"&gt;end&lt;/span&gt;
&lt;span class="ruby-comment"&gt;# resumes here&lt;/span&gt;
&lt;/pre&gt;

&lt;h3 id="label-Testimonials"&gt;Testimonials&lt;/h3&gt;

&lt;p&gt;&amp;ldquo;you&amp;rsquo;ll wind up with your cock in /dev/null somehow&amp;rdquo; &amp;#8211; slyphon&lt;/p&gt;

&lt;p&gt;&amp;ldquo;Haha! Right! This skips ensure&amp;#8230; SO EVIL&amp;#8252;&amp;#8252;&amp;rdquo; &amp;#8211; drbrain&lt;/p&gt;

&lt;p&gt;&amp;ldquo;This is so evil that 6 def test_&amp;#8230; have turned into: 16 tests, 65
assertions, 18 failures, 7 errors&amp;rdquo; &amp;#8211; drbrain&lt;/p&gt;

&lt;h3 id="label-Install"&gt;Install&lt;/h3&gt;

&lt;pre&gt;sudo gem install return_bang&lt;/pre&gt;


&lt;img src="http://feeds.feedburner.com/~r/Segment7/~4/Z8kVS7DZWts" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://blog.segment7.net/2011/12/20/return_bang-1-0</feedburner:origLink></entry>
</feed>

