<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="http://blog.lavoie.sl/feed.xml" rel="self" type="application/atom+xml" /><link href="http://blog.lavoie.sl/" rel="alternate" type="text/html" /><updated>2026-04-30T18:16:05-04:00</updated><id>http://blog.lavoie.sl/feed.xml</id><title type="html">Computers and stuff</title><subtitle>Software Engineering, People Management, and other things I find interesting.</subtitle><author><name>Sebastien Lavoie</name></author><entry><title type="html">Override Doctrine ODM mapping for Symfony FOSUserBundle</title><link href="http://blog.lavoie.sl/2015/01/symfony-override-doctrine-mapping" rel="alternate" type="text/html" title="Override Doctrine ODM mapping for Symfony FOSUserBundle" /><published>2015-01-06T13:44:00-05:00</published><updated>2015-01-06T13:44:00-05:00</updated><id>http://blog.lavoie.sl/2015/01/symfony-override-doctrine-mapping</id><content type="html" xml:base="http://blog.lavoie.sl/2015/01/symfony-override-doctrine-mapping"><![CDATA[<p>In Symfony Cookbook <a href="http://symfony.com/doc/current/cookbook/bundles/override.html#entities-entity-mapping">How to Override any Part of a Bundle</a>, it is written that you cannot override entity mappings and only attributes can be modified in superclasses. However, it is possible to hack you way through and <a href="http://symfony.com/doc/current/bundles/DoctrineMongoDBBundle/index.html#registering-event-listeners-and-subscribers">register an Event Listener</a> on loadClassMetadata that will rewrite the mapping on-the-fly. I would not qualify this as a good approach, but it is the only way I found.</p>

<p>A similar solution can be used for Doctrine ORM.</p>

<p>Here is an example, removing the uniqueness on emailCanonical of FOSUserBundle:</p>

<figure class="highlight"><pre><code class="language-php" data-lang="php"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
</pre></td><td class="code"><pre><span class="cp">&lt;?php</span>
<span class="c1"># ClassMetadataListener.php</span>

<span class="kn">namespace</span> <span class="nn">Acme\UserBundle\EventListener</span><span class="p">;</span>

<span class="kn">use</span> <span class="nc">Doctrine\ODM\MongoDB\Event\LoadClassMetadataEventArgs</span><span class="p">;</span>

<span class="cd">/**
 * Ran when Mongo metadata is loaded.
 */</span>
<span class="kd">class</span> <span class="nc">ClassMetadataListener</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">loadClassMetadata</span><span class="p">(</span><span class="kt">LoadClassMetadataEventArgs</span> <span class="nv">$eventArgs</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nv">$classMetadata</span> <span class="o">=</span> <span class="nv">$eventArgs</span><span class="o">-&gt;</span><span class="nf">getClassMetadata</span><span class="p">();</span>

        <span class="c1">// Override FOS to not have unique emails</span>
        <span class="k">if</span> <span class="p">(</span><span class="nv">$classMetadata</span><span class="o">-&gt;</span><span class="n">reflClass</span><span class="o">-&gt;</span><span class="n">name</span> <span class="o">==</span> <span class="s1">'FOS\UserBundle\Model\User'</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">foreach</span> <span class="p">(</span><span class="nv">$classMetadata</span><span class="o">-&gt;</span><span class="n">indexes</span> <span class="k">as</span> <span class="nv">$i</span> <span class="o">=&gt;</span> <span class="nv">$index</span><span class="p">)</span> <span class="p">{</span>
                <span class="k">if</span> <span class="p">(</span><span class="nb">count</span><span class="p">(</span><span class="nv">$index</span><span class="p">[</span><span class="s1">'keys'</span><span class="p">])</span> <span class="o">===</span> <span class="mi">1</span> <span class="o">&amp;&amp;</span> <span class="k">isset</span><span class="p">(</span><span class="nv">$index</span><span class="p">[</span><span class="s1">'keys'</span><span class="p">][</span><span class="s1">'emailCanonical'</span><span class="p">]))</span> <span class="p">{</span>
                    <span class="nv">$classMetadata</span><span class="o">-&gt;</span><span class="n">indexes</span><span class="p">[</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'options'</span><span class="p">][</span><span class="s1">'unique'</span><span class="p">]</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
                    <span class="k">break</span><span class="p">;</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></td></tr></tbody></table></code></pre></figure>

<figure class="highlight"><pre><code class="language-yaml" data-lang="yaml"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
</pre></td><td class="code"><pre><span class="c1"># services.yml</span>
<span class="na">services</span><span class="pi">:</span>
    <span class="na">acme.user.metadata_listener</span><span class="pi">:</span>
        <span class="na">class</span><span class="pi">:</span> <span class="s">Acme\UserBundle\EventListener\ClassMetadataListener</span>
        <span class="na">tags</span><span class="pi">:</span>
            <span class="pi">-</span>  <span class="pi">{</span> <span class="nv">name</span><span class="pi">:</span> <span class="nv">doctrine_mongodb.odm.event_listener</span><span class="pi">,</span> <span class="nv">event</span><span class="pi">:</span> <span class="nv">loadClassMetadata</span> <span class="pi">}</span>
</pre></td></tr></tbody></table></code></pre></figure>

<p><a href="https://gist.github.com/lavoiesl/0ac2d841b07ea122bfd0">View Gist</a></p>]]></content><author><name>Sebastien Lavoie</name></author><category term="FOSUserBundle" /><category term="Mongo" /><category term="Symfony2" /><category term="Doctrine" /><summary type="html"><![CDATA[In Symfony Cookbook How to Override any Part of a Bundle, it is written that you cannot override entity mappings and only attributes can be modified in superclasses. However, it is possible to hack you way through and register an Event Listener on loadClassMetadata that will rewrite the mapping on-the-fly. I would not qualify this as a good approach, but it is the only way I found.]]></summary></entry><entry><title type="html">Preventing cache stampede when using Doctrine Cache</title><link href="http://blog.lavoie.sl/2014/12/preventing-cache-stampede-using-doctrine-cache" rel="alternate" type="text/html" title="Preventing cache stampede when using Doctrine Cache" /><published>2014-12-04T11:28:00-05:00</published><updated>2014-12-04T11:28:00-05:00</updated><id>http://blog.lavoie.sl/2014/12/preventing-cache-stampede-using-doctrine-cache</id><content type="html" xml:base="http://blog.lavoie.sl/2014/12/preventing-cache-stampede-using-doctrine-cache"><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Cache_stampede">Wikipedia has short and clear article</a> on the matter, cache stampede can be quite deadly, especially when you are rebooting your server, clearing your cache or having a midnight maintenance (cronjob).</p>

<p>Cache stampede, put simply, is when your process is trying to fetch an expensive cache entry, it is not there, and tries to build it, but a simultaneous process comes and does the same thing. This results in resource waste because of processes all trying to do the same thing, uselessly.</p>

<p>The trick is to put a lock on the cache entry and make the other processes wait. I use the trick of having a TTL for the cache calculation. This way, even if the server crashes or there is an exception, the lock will expire and another process will take over. This estimation is also used to calculate how much time to sleep while waiting.</p>

<p>This example uses Doctrine Cache as a global variable, but this should definitely be refactored (or change to another system).</p>

<figure class="highlight"><pre><code class="language-php" data-lang="php"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
</pre></td><td class="code"><pre><span class="cp">&lt;?php</span>
<span class="c1"># cacheGetDefault.php</span>

<span class="cd">/**
 * Get a value from the cache or compute it using a callback
 * Includes cache stampede protection
 * @link http://en.wikipedia.org/wiki/Cache_stampede
 * @link http://blog.lavoie.sl/2014/12/preventing-cache-stampede-using-doctrine-cache
 * @global cache Doctrine\Common\Cache\Cache
 *
 * @param  string  $key         Cache key
 * @param  Closure $callback    Computing function
 * @param  float   $ttl         Seconds
 * @param  float   $stampedeTtl Seconds before cache stampede expires
 *                              Should be about 2-3 times the estimated time to build the cache
 * @return mixed
 */</span>
<span class="k">function</span> <span class="n">cacheGetDefault</span><span class="p">(</span><span class="nv">$key</span><span class="p">,</span> <span class="kt">Closure</span> <span class="nv">$callback</span><span class="p">,</span> <span class="nv">$ttl</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nv">$stampedeTtl</span> <span class="o">=</span> <span class="kc">null</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">global</span> <span class="nv">$cache</span><span class="p">;</span>

    <span class="nv">$data</span> <span class="o">=</span> <span class="nv">$cache</span><span class="o">-&gt;</span><span class="nf">fetch</span><span class="p">(</span><span class="nv">$key</span><span class="p">);</span>

    <span class="k">if</span> <span class="p">(</span><span class="kc">false</span> <span class="o">!==</span> <span class="nv">$data</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nv">$data</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">if</span> <span class="p">(</span><span class="kc">null</span> <span class="o">!==</span> <span class="nv">$stampede</span><span class="p">)</span> <span class="p">{</span>
        <span class="nv">$stampede</span> <span class="o">=</span> <span class="nb">max</span><span class="p">((</span><span class="n">double</span><span class="p">)</span> <span class="nv">$stampede</span><span class="p">,</span> <span class="mf">0.001</span><span class="p">);</span> <span class="c1">// prevention for infinite ttl</span>
        <span class="c1">// data is being computed, wait</span>
        <span class="k">while</span> <span class="p">(</span><span class="s1">'__STAMPEDE__'</span> <span class="o">===</span> <span class="nv">$data</span><span class="p">)</span> <span class="p">{</span>
            <span class="c1">// wait 1/20th of the stampede TTL, to give the CPU a chance</span>
            <span class="nb">sleep</span><span class="p">(</span><span class="nv">$stampede</span> <span class="o">/</span> <span class="mi">20</span><span class="p">);</span>
            <span class="nv">$data</span> <span class="o">=</span> <span class="nv">$cache</span><span class="o">-&gt;</span><span class="nf">fetch</span><span class="p">(</span><span class="nv">$key</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="k">if</span> <span class="p">(</span><span class="nv">$data</span> <span class="o">===</span> <span class="kc">false</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="kc">null</span> <span class="o">!==</span> <span class="nv">$stampedeTtl</span><span class="p">)</span> <span class="p">{</span>
            <span class="c1">// acquire lock</span>
            <span class="nv">$cache</span><span class="o">-&gt;</span><span class="nf">save</span><span class="p">(</span><span class="nv">$key</span><span class="p">,</span> <span class="s1">'__STAMPEDE__'</span><span class="p">,</span> <span class="nv">$stampedeTtl</span><span class="p">);</span>
        <span class="p">}</span>
        <span class="c1">// compute the actual data</span>
        <span class="nv">$data</span> <span class="o">=</span> <span class="nv">$callback</span><span class="p">();</span>
    <span class="p">}</span>

    <span class="nv">$cache</span><span class="o">-&gt;</span><span class="nf">save</span><span class="p">(</span><span class="nv">$key</span><span class="p">,</span> <span class="nv">$data</span><span class="p">,</span> <span class="nv">$ttl</span><span class="p">);</span>

    <span class="k">return</span> <span class="nv">$data</span><span class="p">;</span>
<span class="p">}</span>
</pre></td></tr></tbody></table></code></pre></figure>

<figure class="highlight"><pre><code class="language-php" data-lang="php"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre><span class="cp">&lt;?php</span>
<span class="c1"># useCache.php</span>

<span class="nv">$cacheTtl</span> <span class="o">=</span> <span class="mi">3600</span><span class="p">;</span> <span class="c1">// an hour</span>
<span class="nv">$stampedeTtl</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span> <span class="c1">// seconds before releasing lock</span>

<span class="nf">cacheGetDefault</span><span class="p">(</span><span class="s1">'recent_tweets'</span><span class="p">,</span> <span class="k">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nb">file_get_contents</span><span class="p">(</span><span class="s1">'https://api.twitter.com/1.1/search/tweets.json?q=@lavoiesl'</span><span class="p">);</span>
<span class="p">},</span> <span class="nv">$cacheTtl</span><span class="p">,</span> <span class="nv">$stampedeTtl</span><span class="p">);</span>
</pre></td></tr></tbody></table></code></pre></figure>

<p><a href="https://gist.github.com/lavoiesl/9cdc5893a71c53e16b47">View Gist</a></p>]]></content><author><name>Sebastien Lavoie</name></author><category term="Caching" /><category term="PHP" /><category term="Doctrine" /><category term="Performance" /><summary type="html"><![CDATA[Wikipedia has short and clear article on the matter, cache stampede can be quite deadly, especially when you are rebooting your server, clearing your cache or having a midnight maintenance (cronjob).]]></summary></entry><entry><title type="html">Load Doctrine Fixtures when using Migrations in Symfony</title><link href="http://blog.lavoie.sl/2014/12/load-doctrine-fixtures-when-using" rel="alternate" type="text/html" title="Load Doctrine Fixtures when using Migrations in Symfony" /><published>2014-12-02T13:55:00-05:00</published><updated>2014-12-02T13:55:00-05:00</updated><id>http://blog.lavoie.sl/2014/12/load-doctrine-fixtures-when-using</id><content type="html" xml:base="http://blog.lavoie.sl/2014/12/load-doctrine-fixtures-when-using"><![CDATA[<p>Using app/console doctrine:migrations:migrate is really easy and trouble free for everybody, but those tables are often empty and they need some data to be of any use. A common example is a table of countries or user roles.</p>

<p>However, once a project is started, it is often hard to use fixtures because it messes with your data. The trick here is to load only the fixtures you need, only when needed by the migration. This way, a new developer starting with the project could simply run the migrations and have a database ready for testing.</p>

<p>Here is a simple way of loading those fixtures on postUp. You need to pass an array of initialized fixture classes, Doctrine will figure the way to order them by itself.</p>

<p>This is only a proof of concept, it would need some refactoring and testing to be production ready, but you can get the idea.</p>

<figure class="highlight"><pre><code class="language-php" data-lang="php"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
</pre></td><td class="code"><pre><span class="cp">&lt;?php</span>
<span class="c1"># AbstractFixtureMigration.php</span>

<span class="kn">use</span> <span class="nc">Doctrine\Common\DataFixtures\Executor\ORMExecutor</span><span class="p">;</span>
<span class="kn">use</span> <span class="nc">Doctrine\Common\DataFixtures\Purger\ORMPurger</span><span class="p">;</span>
<span class="kn">use</span> <span class="nc">Doctrine\DBAL\Migrations\AbstractMigration</span><span class="p">;</span>
<span class="kn">use</span> <span class="nc">Symfony\Bridge\Doctrine\DataFixtures\ContainerAwareLoader</span> <span class="k">as</span> <span class="nc">Loader</span><span class="p">;</span>
<span class="kn">use</span> <span class="nc">Symfony\Component\Console\Output\ConsoleOutput</span><span class="p">;</span>
<span class="kn">use</span> <span class="nc">Symfony\Component\DependencyInjection\ContainerAwareInterface</span><span class="p">;</span>
<span class="kn">use</span> <span class="nc">Symfony\Component\DependencyInjection\ContainerInterface</span><span class="p">;</span>

<span class="k">abstract</span> <span class="kd">class</span> <span class="nc">AbstractFixtureMigration</span> <span class="kd">extends</span> <span class="nc">AbstractMigration</span> <span class="kd">implements</span> <span class="nc">ContainerAwareInterface</span>
<span class="p">{</span>
    <span class="kn">use</span> <span class="nc">FixtureMigrationTrait</span><span class="p">;</span>

    <span class="k">private</span> <span class="nv">$container</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">setContainer</span><span class="p">(</span><span class="kt">ContainerInterface</span> <span class="nv">$container</span> <span class="o">=</span> <span class="kc">null</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">container</span> <span class="o">=</span> <span class="nv">$container</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">loadFixtures</span><span class="p">(</span><span class="kt">array</span> <span class="nv">$fixtures</span><span class="p">,</span> <span class="nv">$append</span> <span class="o">=</span> <span class="kc">true</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nv">$em</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">container</span><span class="o">-&gt;</span><span class="nf">get</span><span class="p">(</span><span class="s1">'doctrine.orm.entity_manager'</span><span class="p">);</span>

        <span class="nv">$loader</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Loader</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">container</span><span class="p">);</span>
        <span class="nb">array_map</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="nv">$loader</span><span class="p">,</span> <span class="s1">'addFixture'</span><span class="p">),</span> <span class="nv">$fixtures</span><span class="p">);</span>

        <span class="nv">$purger</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
        <span class="k">if</span> <span class="p">(</span><span class="nv">$append</span> <span class="o">===</span> <span class="kc">false</span><span class="p">)</span> <span class="p">{</span>
            <span class="nv">$purger</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ORMPurger</span><span class="p">(</span><span class="nv">$em</span><span class="p">);</span>
            <span class="nv">$purger</span><span class="o">-&gt;</span><span class="nf">setPurgeMode</span><span class="p">(</span><span class="nc">ORMPurger</span><span class="o">::</span><span class="no">PURGE_MODE_DELETE</span><span class="p">);</span>
        <span class="p">}</span>

        <span class="nv">$executor</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ORMExecutor</span><span class="p">(</span><span class="nv">$em</span><span class="p">,</span> <span class="nv">$purger</span><span class="p">);</span>

        <span class="nv">$output</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ConsoleOutput</span><span class="p">;</span>
        <span class="nv">$executor</span><span class="o">-&gt;</span><span class="nf">setLogger</span><span class="p">(</span><span class="k">function</span><span class="p">(</span><span class="nv">$message</span><span class="p">)</span> <span class="k">use</span> <span class="p">(</span><span class="nv">$output</span><span class="p">)</span> <span class="p">{</span>
            <span class="nv">$output</span><span class="o">-&gt;</span><span class="nf">writeln</span><span class="p">(</span><span class="nb">sprintf</span><span class="p">(</span><span class="s1">'  &lt;comment&gt;&gt;&lt;/comment&gt; &lt;info&gt;%s&lt;/info&gt;'</span><span class="p">,</span> <span class="nv">$message</span><span class="p">));</span>
        <span class="p">});</span>

        <span class="nv">$executor</span><span class="o">-&gt;</span><span class="nf">execute</span><span class="p">(</span><span class="nv">$loader</span><span class="o">-&gt;</span><span class="nf">getFixtures</span><span class="p">(),</span> <span class="nv">$append</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></td></tr></tbody></table></code></pre></figure>

<figure class="highlight"><pre><code class="language-php" data-lang="php"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
</pre></td><td class="code"><pre><span class="cp">&lt;?php</span>
<span class="c1"># Version1.php</span>

<span class="kn">use</span> <span class="nc">Doctrine\DBAL\Schema\Schema</span><span class="p">;</span>
<span class="kn">use</span> <span class="no">AcmeBundle\DataFixtures\ORM</span> <span class="k">as</span> <span class="nc">Fixtures</span><span class="p">;</span>

<span class="kd">class</span> <span class="nc">Version1</span> <span class="kd">extends</span> <span class="nc">AbstractFixtureMigration</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">up</span><span class="p">(</span><span class="kt">Schema</span> <span class="nv">$schema</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="c1">// ...</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">down</span><span class="p">(</span><span class="kt">Schema</span> <span class="nv">$schema</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="c1">// ...</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="n">postUp</span><span class="p">(</span><span class="kt">Schema</span> <span class="nv">$schema</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">loadFixtures</span><span class="p">(</span><span class="k">array</span><span class="p">(</span>
            <span class="k">new</span> <span class="nc">Fixtures\LoadMyData</span><span class="p">,</span>
            <span class="k">new</span> <span class="nc">Fixtures\LoadMyOtherData</span><span class="p">,</span>
        <span class="p">));</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></td></tr></tbody></table></code></pre></figure>

<p><a href="https://gist.github.com/lavoiesl/77375da08b3274aa6440">View Gist</a></p>]]></content><author><name>Sebastien Lavoie</name></author><category term="Data Fixtures" /><category term="Development tool" /><category term="Symfony2" /><category term="PHP" /><category term="Doctrine" /><summary type="html"><![CDATA[Using app/console doctrine:migrations:migrate is really easy and trouble free for everybody, but those tables are often empty and they need some data to be of any use. A common example is a table of countries or user roles.]]></summary></entry><entry><title type="html">MySQL 5.7 and Wordpress problem</title><link href="http://blog.lavoie.sl/2014/12/mysql-57-and-wordpress-problem" rel="alternate" type="text/html" title="MySQL 5.7 and Wordpress problem" /><published>2014-12-01T14:58:00-05:00</published><updated>2014-12-01T14:58:00-05:00</updated><id>http://blog.lavoie.sl/2014/12/mysql-57-and-wordpress-problem</id><content type="html" xml:base="http://blog.lavoie.sl/2014/12/mysql-57-and-wordpress-problem"><![CDATA[<p>If you upgrade to MySQL 5.7, you may encounter bugs with legacy software. Wordpress, which I also consider some kind of legacy software, does not handle this very well with its default settings.</p>

<p>You may encounter the “Submit for review” bug where you cannot add new posts. It may be related to <a href="https://wordpress.org/support/topic/submit-for-review-4">permissions, auto_increment and other stuff</a>, but here is another case: bad date formats and invalid data altogether.</p>

<p>In MySQL &lt;= 5.6, by default, invalid values are coalesced into valid ones when needed. For example, attempting to set a field NULL on a non-null string will result in empty string. Starting with MySQL 5.7, this is not permitted.</p>

<p>Hence, if you want to upgrade to 5.7 and use all the goodies, you should consider putting it in a more compatible mode, adding this to your <code class="language-plaintext highlighter-rouge">/etc/my.cnf</code>:</p>

<figure class="highlight"><pre><code class="language-ini" data-lang="ini"><span class="nn">[mysqld]</span>
<span class="c"># Default:
# sql_mode = ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION
</span><span class="py">sql_mode</span> <span class="p">=</span> <span class="s">ALLOW_INVALID_DATES,NO_ENGINE_SUBSTITUTION</span></code></pre></figure>

<p>See <a href="http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sql-mode-important">official documentation</a> for complete information</p>]]></content><author><name>Sebastien Lavoie</name></author><category term="Wordpress" /><category term="hosting" /><category term="MySQL" /><category term="sysadmin" /><summary type="html"><![CDATA[If you upgrade to MySQL 5.7, you may encounter bugs with legacy software. Wordpress, which I also consider some kind of legacy software, does not handle this very well with its default settings.]]></summary></entry><entry><title type="html">Starting a text editor from inside a Virtual Machine</title><link href="http://blog.lavoie.sl/2014/11/starting-text-editor-from-inside" rel="alternate" type="text/html" title="Starting a text editor from inside a Virtual Machine" /><published>2014-11-05T17:24:00-05:00</published><updated>2014-11-05T17:24:00-05:00</updated><id>http://blog.lavoie.sl/2014/11/starting-text-editor-from-inside</id><content type="html" xml:base="http://blog.lavoie.sl/2014/11/starting-text-editor-from-inside"><![CDATA[<p>Using Vagrant, Docker or other virtual development environment is becoming quite popular. However, a drawback of this is that you cannot start a visual text editor on your main machine because heh, the files are not there. Purist may tell you that you should be using Vim or Emacs, but I like Sublime, I want to keep using it.</p>

<p>A simple trick I came up with it to call my text editor by SSH using path translation. Of course, you will need to translate the paths and otherwise adapt it to your needs, but this should get you started:</p>

<figure class="highlight"><pre><code class="language-shell" data-lang="shell"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><pre><span class="c"># subl.sh</span>
<span class="c">#!/bin/bash</span>

<span class="c"># Starting Sublime Text from inside a Virtual Machine</span>
<span class="c"># @link https://gist.github.com/lavoiesl/c01b16b5f875906a6d82</span>

<span class="c"># You may require to install realpath</span>

<span class="nv">path</span><span class="o">=</span><span class="s2">"</span><span class="si">$(</span><span class="nb">realpath</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span><span class="si">)</span><span class="s2">"</span>

<span class="k">if </span><span class="nb">echo</span> <span class="s2">"</span><span class="k">${</span><span class="nv">path</span><span class="k">}</span><span class="s2">"</span> | <span class="nb">grep</span> <span class="nt">-q</span> <span class="s2">"^/media/data/projects"</span><span class="p">;</span> <span class="k">then
  </span><span class="nv">path</span><span class="o">=</span><span class="s2">"</span><span class="si">$(</span><span class="nb">echo</span> <span class="s2">"</span><span class="k">${</span><span class="nv">path</span><span class="k">}</span><span class="s2">"</span> | <span class="nb">sed</span> <span class="s1">'s/^\/media\/data\/projects\//~\/projects\//'</span><span class="si">)</span><span class="s2">"</span>
<span class="k">elif </span><span class="nb">echo</span> <span class="s2">"</span><span class="k">${</span><span class="nv">path</span><span class="k">}</span><span class="s2">"</span> | <span class="nb">grep</span> <span class="nt">-q</span> <span class="s2">"^/media/home"</span><span class="p">;</span> <span class="k">then
  </span><span class="nv">path</span><span class="o">=</span><span class="s2">"</span><span class="si">$(</span><span class="nb">echo</span> <span class="s2">"</span><span class="k">${</span><span class="nv">path</span><span class="k">}</span><span class="s2">"</span> | <span class="nb">sed</span> <span class="s1">'s/^\/media\/home\//~\//'</span><span class="si">)</span><span class="s2">"</span>
<span class="k">else
  </span><span class="nb">echo</span> <span class="s2">"Only paths inside /media/data/projects and /media/home are supported"</span> <span class="o">&gt;</span>&amp;2
  <span class="nb">exit </span>1
<span class="k">fi

</span>ssh seb@10.10.10.1 subl <span class="s2">"</span><span class="k">${</span><span class="nv">path</span><span class="k">}</span><span class="s2">"</span>
</pre></td></tr></tbody></table></code></pre></figure>

<p><a href="https://gist.github.com/lavoiesl/c01b16b5f875906a6d82">View Gist</a></p>

<p>In this example, <code class="language-plaintext highlighter-rouge">/media/data/projects</code> on the Guest exists as <code class="language-plaintext highlighter-rouge">~/projects</code> on the <code class="language-plaintext highlighter-rouge">Host</code> and <code class="language-plaintext highlighter-rouge">~</code> on the <code class="language-plaintext highlighter-rouge">Host</code> exists as <code class="language-plaintext highlighter-rouge">/media/home</code> on the <code class="language-plaintext highlighter-rouge">Guest</code>.</p>

<p>Make sure you have <code class="language-plaintext highlighter-rouge">~/.ssh/authorized_keys</code> and <code class="language-plaintext highlighter-rouge">ForwardAgent</code> properly setup to avoid password prompts each time.</p>

<p>You could also use this trick to open a webpage by using the “open” program on Mac. Equivalent exists on most Linux distros.</p>]]></content><author><name>Sebastien Lavoie</name></author><category term="Development tool" /><category term="Vagrant" /><summary type="html"><![CDATA[Using Vagrant, Docker or other virtual development environment is becoming quite popular. However, a drawback of this is that you cannot start a visual text editor on your main machine because heh, the files are not there. Purist may tell you that you should be using Vim or Emacs, but I like Sublime, I want to keep using it.]]></summary></entry><entry><title type="html">Creating a static private network on VMWare Fusion with Ubuntu</title><link href="http://blog.lavoie.sl/2014/10/static-private-network-vmware-fusion-ubuntu" rel="alternate" type="text/html" title="Creating a static private network on VMWare Fusion with Ubuntu" /><published>2014-10-08T11:58:00-04:00</published><updated>2014-10-08T11:58:00-04:00</updated><id>http://blog.lavoie.sl/2014/10/static-private-network-vmware-fusion-ubuntu</id><content type="html" xml:base="http://blog.lavoie.sl/2014/10/static-private-network-vmware-fusion-ubuntu"><![CDATA[<p>This tutorial is using VMWare Fusion 7, Ubuntu 14.04.1 server and OSX 10.9</p>

<p>The goal here is to create a private network shared with selected VMs and the host, while offering NATing to connect to the Internet. VMWare offers some <a href="https://pubs.vmware.com/fusion-7/index.jsp?topic=%2Fcom.vmware.fusion.help.doc%2FGUID-DEB1FB99-0E44-4AAA-9693-6C2687098F13.html">documentation</a>, which works great with DHCP, but I needed to specify everything static for custom needs.</p>

<h3 id="creating-a-private-network">Creating a private network</h3>

<ol>
  <li>Go to the Network tab of general settings (⌘,)</li>
  <li>Unlock the screen by clicking on the lock.</li>
  <li>Add a custom network by clicking on the +.</li>
  <li>Make sure all options are checked (see screenshot).</li>
  <li>Specify a subnet IP, I will be using 192.168.200.0.
Activating the DHCP here is needed for the host to connect to it, even though our VMs will be using static IPs.</li>
</ol>

<figure class=""><a href="/assets/images/posts/static-private-network-vmware-fusion-ubuntu/Screen+Shot+2014-10-08+at+11.43.17+AM.png" class="image-popup"><img src="/assets/images/posts/static-private-network-vmware-fusion-ubuntu/Screen+Shot+2014-10-08+at+11.43.17+AM.png" alt="" /></a></figure>

<h3 id="configure-the-vms-network-adapter">Configure the VM’s network adapter</h3>

<ol>
  <li>Make sure your VM is powered off.</li>
  <li>Go to the VM’s settings (⌘E)</li>
  <li>Click on Network Adapter.</li>
  <li>Select your newly created network (for me it was <code class="language-plaintext highlighter-rouge">vmnet2</code>).</li>
</ol>

<figure class=""><a href="/assets/images/posts/static-private-network-vmware-fusion-ubuntu/Screen+Shot+2014-10-08+at+11.35.28+AM.png" class="image-popup"><img src="/assets/images/posts/static-private-network-vmware-fusion-ubuntu/Screen+Shot+2014-10-08+at+11.35.28+AM.png" alt="" /></a></figure>

<h3 id="configure-the-oss-network-adapter">Configure the OS’s network adapter</h3>

<ol>
  <li>Edit the network interfaces:
    <div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo </span>nano /etc/network/interfaces
   
<span class="c"># The loopback network interface</span>
auto lo
iface lo inet loopback
   
<span class="c"># The primary network interface</span>
auto eth0
iface eth0 inet static
  address 192.168.200.100
  netmask 255.255.255.0
  gateway 192.168.200.2
  dns-nameservers 192.168.200.2
</code></pre></div>    </div>
  </li>
  <li>Reboot</li>
  <li>Check to see if Internet works:
    <div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ping google.com
</code></pre></div>    </div>
  </li>
  <li>Check to see if you can see your host:
    <div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ping 192.168.200.1
</code></pre></div>    </div>
  </li>
  <li>Try SSHing to your VM from your host:
    <div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh 192.168.200.100
</code></pre></div>    </div>
  </li>
</ol>

<p>You can add more VMs to this private network, just remember to change the IP from <code class="language-plaintext highlighter-rouge">192.168.200.100</code> to something else from <code class="language-plaintext highlighter-rouge">192.168.200.3</code> to <code class="language-plaintext highlighter-rouge">192.168.200.253</code>.</p>]]></content><author><name>Sebastien Lavoie</name></author><category term="VMWare" /><category term="Ubuntu" /><summary type="html"><![CDATA[This tutorial is using VMWare Fusion 7, Ubuntu 14.04.1 server and OSX 10.9]]></summary></entry><entry><title type="html">Adding newlines in a SQL mysqldump to split extended inserts</title><link href="http://blog.lavoie.sl/2014/06/split-mysqldump-extended-inserts" rel="alternate" type="text/html" title="Adding newlines in a SQL mysqldump to split extended inserts" /><published>2014-06-20T15:27:00-04:00</published><updated>2014-06-20T15:27:00-04:00</updated><id>http://blog.lavoie.sl/2014/06/split-mysqldump-extended-inserts</id><content type="html" xml:base="http://blog.lavoie.sl/2014/06/split-mysqldump-extended-inserts"><![CDATA[<p>The official <a href="http://dev.mysql.com/doc/refman/5.6/en/mysqldump.html">mysqldump</a> supports more or less two output styles: separate INSERTs (one insert statement per row) or extended INSERTs (one insert per table). Extended INSERTs are much faster, but MySQL write them all in one line, the result being a SQL very hard to read. Can we get the best of both worlds ?</p>

<h4 id="separate-inserts">Separate INSERTs</h4>

<figure class="highlight"><pre><code class="language-sql" data-lang="sql"><span class="k">INSERT</span> <span class="k">INTO</span> <span class="n">mytable</span> <span class="p">(</span><span class="n">id</span><span class="p">)</span> <span class="k">VALUES</span> <span class="p">(</span><span class="mi">1</span><span class="p">);</span>
<span class="k">INSERT</span> <span class="k">INTO</span> <span class="n">mytable</span> <span class="p">(</span><span class="n">id</span><span class="p">)</span> <span class="k">VALUES</span> <span class="p">(</span><span class="mi">2</span><span class="p">);</span></code></pre></figure>

<h4 id="extended-inserts">Extended INSERTs</h4>

<p><code class="language-plaintext highlighter-rouge">INSERT INTO mytable (id) VALUES (1),(2);</code></p>

<h4 id="new-and-improvedinserts">New-And-Improved™ INSERTs</h4>

<figure class="highlight"><pre><code class="language-sql" data-lang="sql"><span class="k">INSERT</span> <span class="k">INTO</span> <span class="n">mytable</span> <span class="p">(</span><span class="n">id</span><span class="p">)</span> <span class="k">VALUES</span>
<span class="p">(</span><span class="mi">1</span><span class="p">),</span>
<span class="p">(</span><span class="mi">2</span><span class="p">);</span></code></pre></figure>

<h3 id="current-solutions">Current solutions</h3>

<h4 id="using-sed">Using sed</h4>

<figure class="highlight"><pre><code class="language-sh" data-lang="sh">mysqldump <span class="nt">--extended-insert</span> | <span class="nb">sed</span> <span class="s1">'s/),(/),\n(/g'</span></code></pre></figure>

<p>Only problem is, lines will be split, even in the middle of strings, altering your data.</p>

<h4 id="using-net_buffer_length">Using net_buffer_length</h4>

<figure class="highlight"><pre><code class="language-sh" data-lang="sh">mysqldump <span class="nt">--extended-insert</span> <span class="nt">--net_buffer_length</span><span class="o">=</span>5000</code></pre></figure>

<p>mysqldump will make sure lines are not longer than 5000 (or whatever), starting a new INSERT when needed. The problem is that the behaviour is kinda random, diffs are hard to analyze and it may break your data if you are storing columns longer than this.</p>

<h3 id="writing-a-parser">Writing a parser</h3>

<p>This question has been <a href="http://stackoverflow.com/questions/1293529/how-to-deal-with-enormous-line-lengths-created-by-mysqldump">often</a> <a href="http://forums.mysql.com/read.php?28,420002,420002">asked</a> without a proper <a href="http://serverfault.com/questions/142588/mysql-dump-output-each-table-row-on-a-new-line-whilst-using-extended-insert">reply</a>, so I decided to write a simple parser. Precisely, we need to check for quotes, parenthesis, and escape characters.</p>

<p>I first wrote it in PHP:</p>

<figure class="highlight"><pre><code class="language-php" data-lang="php"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
</pre></td><td class="code"><pre><span class="cp">&lt;?php</span>
<span class="c1"># process-mysqldump.php</span>

<span class="c1">// Usage: cat dump.sql | php process-mysqldump.php</span>

<span class="nv">$input</span> <span class="o">=</span> <span class="nb">fopen</span><span class="p">(</span><span class="s1">'php://stdin'</span><span class="p">,</span> <span class="s1">'r'</span><span class="p">);</span>

<span class="k">while</span><span class="p">(</span><span class="o">!</span><span class="nb">feof</span><span class="p">(</span><span class="nv">$input</span><span class="p">))</span> <span class="p">{</span>
    <span class="nv">$line</span> <span class="o">=</span> <span class="nb">fgets</span><span class="p">(</span><span class="nv">$input</span><span class="p">);</span>
    <span class="k">if</span> <span class="p">(</span><span class="nb">substr</span><span class="p">(</span><span class="nv">$line</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">6</span><span class="p">)</span> <span class="o">==</span> <span class="s1">'INSERT'</span><span class="p">)</span> <span class="p">{</span>
        <span class="nf">process_line</span><span class="p">(</span><span class="nv">$line</span><span class="p">);</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="k">echo</span> <span class="nv">$line</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">function</span> <span class="n">process_line</span><span class="p">(</span><span class="nv">$line</span><span class="p">)</span> <span class="p">{</span>
    <span class="nv">$length</span> <span class="o">=</span> <span class="nb">strlen</span><span class="p">(</span><span class="nv">$line</span><span class="p">);</span>

    <span class="nv">$pos</span> <span class="o">=</span> <span class="nb">strpos</span><span class="p">(</span><span class="nv">$line</span><span class="p">,</span> <span class="s1">' VALUES '</span><span class="p">)</span> <span class="o">+</span> <span class="mi">8</span><span class="p">;</span>
    <span class="k">echo</span> <span class="nb">substr</span><span class="p">(</span><span class="nv">$line</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nv">$pos</span><span class="p">);</span>

    <span class="nv">$parenthesis</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
    <span class="nv">$quote</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
    <span class="nv">$escape</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>

    <span class="k">for</span> <span class="p">(</span><span class="nv">$i</span> <span class="o">=</span> <span class="nv">$pos</span><span class="p">;</span> <span class="nv">$i</span> <span class="o">&lt;</span> <span class="nv">$length</span><span class="p">;</span> <span class="nv">$i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">switch</span><span class="p">(</span><span class="nv">$line</span><span class="p">[</span><span class="nv">$i</span><span class="p">])</span> <span class="p">{</span>
            <span class="k">case</span> <span class="s1">'('</span><span class="o">:</span>
                <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nv">$quote</span><span class="p">)</span> <span class="p">{</span>
                    <span class="k">if</span> <span class="p">(</span><span class="nv">$parenthesis</span><span class="p">)</span> <span class="p">{</span>
                        <span class="k">throw</span> <span class="k">new</span> <span class="nc">Exception</span><span class="p">(</span><span class="s1">'double open parenthesis'</span><span class="p">);</span>
                    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                        <span class="k">echo</span> <span class="kc">PHP_EOL</span><span class="p">;</span>
                        <span class="nv">$parenthesis</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
                    <span class="p">}</span>
                <span class="p">}</span>
                <span class="nv">$escape</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
                <span class="k">break</span><span class="p">;</span>

            <span class="k">case</span> <span class="s1">')'</span><span class="o">:</span>
                <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nv">$quote</span><span class="p">)</span> <span class="p">{</span>
                    <span class="k">if</span> <span class="p">(</span><span class="nv">$parenthesis</span><span class="p">)</span> <span class="p">{</span>
                        <span class="nv">$parenthesis</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
                    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                        <span class="k">throw</span> <span class="k">new</span> <span class="nc">Exception</span><span class="p">(</span><span class="s1">'closing parenthesis without open'</span><span class="p">);</span>
                    <span class="p">}</span>
                <span class="p">}</span>
                <span class="nv">$escape</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
                <span class="k">break</span><span class="p">;</span>

            <span class="k">case</span> <span class="s1">'\':
                $escape = !$escape;
                break;

            case "'</span><span class="s2">":
                if (</span><span class="nv">$escape</span><span class="s2">) {
                    </span><span class="nv">$escape</span><span class="s2"> = false;
                } else {
                    </span><span class="nv">$quote</span><span class="s2"> = !</span><span class="nv">$quote</span><span class="s2">;
                }
                break;

            default:
                </span><span class="nv">$escape</span><span class="s2"> = false;
                break;
        }

        echo </span><span class="nv">$line[$i]</span><span class="s2">;
    }
}

fclose(</span><span class="nv">$input</span><span class="s2">);</span>
</pre></td></tr></tbody></table></code></pre></figure>

<p><a href="https://gist.github.com/lavoiesl/9a08e399fc9832d12794">View Gist</a></p>

<p>But then I realized it was too slow, so I rewrote it in C, using strcspn to find string occurence:</p>

<figure class="highlight"><pre><code class="language-c" data-lang="c"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
</pre></td><td class="code"><pre><span class="c1">// process-mysqldump.c</span>
<span class="c1">// gcc -O2 -Wall -pedantic process-mysqldump.c -o process-mysqldump</span>
<span class="c1">// Usage: cat dump.sql | process-mysqldump</span>
<span class="c1">//   Or : process-mysqldump dump.sql</span>

<span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;stdlib.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;stdbool.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;string.h&gt;</span><span class="cp">
</span>
<span class="cp">#define BUFFER 100000
</span>
<span class="n">bool</span> <span class="nf">is_escaped</span><span class="p">(</span><span class="kt">char</span><span class="o">*</span> <span class="n">string</span><span class="p">,</span> <span class="kt">int</span> <span class="n">offset</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">offset</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nb">false</span><span class="p">;</span>
    <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">string</span><span class="p">[</span><span class="n">offset</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="err">'\'</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="o">!</span><span class="n">is_escaped</span><span class="p">(</span><span class="n">string</span><span class="p">,</span> <span class="n">offset</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nb">false</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="n">bool</span> <span class="nf">is_commented</span><span class="p">(</span><span class="kt">char</span><span class="o">*</span> <span class="n">string</span><span class="p">)</span> <span class="p">{</span>
    <span class="kt">char</span> <span class="n">buffer</span><span class="p">[</span><span class="mi">4</span><span class="p">];</span>

    <span class="n">sprintf</span><span class="p">(</span><span class="n">buffer</span><span class="p">,</span> <span class="s">"%.3s"</span><span class="p">,</span> <span class="n">string</span><span class="p">);</span>

    <span class="k">return</span> <span class="n">strcmp</span><span class="p">(</span><span class="n">buffer</span><span class="p">,</span> <span class="s">"-- "</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>

<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">argv</span><span class="p">[])</span>
<span class="p">{</span>
    <span class="kt">FILE</span><span class="o">*</span> <span class="n">file</span> <span class="o">=</span> <span class="n">argc</span> <span class="o">&gt;</span> <span class="mi">1</span> <span class="o">?</span> <span class="n">fopen</span><span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="s">"r"</span><span class="p">)</span> <span class="o">:</span> <span class="n">stdin</span><span class="p">;</span>

    <span class="kt">char</span> <span class="n">buffer</span><span class="p">[</span><span class="n">BUFFER</span><span class="p">];</span>
    <span class="kt">char</span><span class="o">*</span> <span class="n">line</span><span class="p">;</span>
    <span class="kt">int</span> <span class="n">pos</span><span class="p">;</span>
    <span class="kt">int</span> <span class="n">parenthesis</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
    <span class="n">bool</span> <span class="n">quote</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
    <span class="n">bool</span> <span class="n">escape</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
    <span class="n">bool</span> <span class="n">comment</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>

    <span class="k">while</span> <span class="p">(</span><span class="n">fgets</span><span class="p">(</span><span class="n">buffer</span><span class="p">,</span> <span class="n">BUFFER</span><span class="p">,</span> <span class="n">file</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">line</span> <span class="o">=</span> <span class="n">buffer</span><span class="p">;</span>

        <span class="c1">// skip commented</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">comment</span> <span class="o">||</span> <span class="n">is_commented</span><span class="p">(</span><span class="n">line</span><span class="p">))</span> <span class="p">{</span>
            <span class="n">comment</span> <span class="o">=</span> <span class="n">line</span><span class="p">[</span><span class="n">strlen</span><span class="p">(</span><span class="n">line</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">!=</span> <span class="sc">'\n'</span><span class="p">;</span>
            <span class="n">fputs</span><span class="p">(</span><span class="n">line</span><span class="p">,</span> <span class="n">stdout</span><span class="p">);</span>
        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
            <span class="n">pos</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>

            <span class="nl">nullchar:</span>
            <span class="k">while</span> <span class="p">(</span><span class="n">line</span><span class="p">[</span><span class="n">pos</span><span class="p">]</span> <span class="o">!=</span> <span class="sc">'\0'</span><span class="p">)</span> <span class="p">{</span>
                <span class="c1">// if we are still in escape state, we need to check first char.</span>
                <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">escape</span><span class="p">)</span> <span class="p">{</span>
                    <span class="c1">// find any character in ()'</span>
                    <span class="n">pos</span> <span class="o">=</span> <span class="n">strcspn</span><span class="p">(</span><span class="n">line</span><span class="p">,</span> <span class="s">"()'</span><span class="se">\\</span><span class="s">"</span><span class="p">);</span>
                <span class="p">}</span>

                <span class="k">if</span> <span class="p">(</span><span class="n">pos</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
                    <span class="c1">// print before match</span>
                    <span class="n">printf</span><span class="p">(</span><span class="s">"%.*s"</span><span class="p">,</span> <span class="n">pos</span><span class="p">,</span> <span class="n">line</span><span class="p">);</span>
                <span class="p">}</span>

                <span class="k">switch</span> <span class="p">(</span><span class="n">line</span><span class="p">[</span><span class="n">pos</span><span class="p">])</span> <span class="p">{</span>
                    <span class="k">case</span> <span class="sc">'('</span><span class="p">:</span>
                        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">quote</span><span class="p">)</span> <span class="p">{</span>
                            <span class="k">if</span> <span class="p">(</span><span class="n">parenthesis</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
                                <span class="n">putchar</span><span class="p">(</span><span class="sc">'\n'</span><span class="p">);</span>
                            <span class="p">}</span>
                            <span class="n">parenthesis</span><span class="o">++</span><span class="p">;</span>
                        <span class="p">}</span>
                        <span class="k">if</span> <span class="p">(</span><span class="n">escape</span><span class="p">)</span> <span class="p">{</span>
                            <span class="n">escape</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
                        <span class="p">}</span>
                        <span class="k">break</span><span class="p">;</span>

                    <span class="k">case</span> <span class="sc">')'</span><span class="p">:</span>
                        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">quote</span><span class="p">)</span> <span class="p">{</span>
                            <span class="k">if</span> <span class="p">(</span><span class="n">parenthesis</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
                                <span class="n">parenthesis</span><span class="o">--</span><span class="p">;</span>
                            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                                <span class="c1">// whoops</span>
                                <span class="n">puts</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
                                <span class="n">fputs</span><span class="p">(</span><span class="n">line</span><span class="p">,</span> <span class="n">stdout</span><span class="p">);</span>
                                <span class="n">fputs</span><span class="p">(</span><span class="s">"Found closing parenthesis without opening one.</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">stderr</span><span class="p">);</span>
                                <span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
                            <span class="p">}</span>
                        <span class="p">}</span>
                        <span class="k">if</span> <span class="p">(</span><span class="n">escape</span><span class="p">)</span> <span class="p">{</span>
                            <span class="n">escape</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
                        <span class="p">}</span>
                        <span class="k">break</span><span class="p">;</span>

                    <span class="k">case</span> <span class="sc">'\\'</span><span class="p">:</span>
                        <span class="n">escape</span> <span class="o">=</span> <span class="o">!</span><span class="n">escape</span><span class="p">;</span>
                        <span class="k">break</span><span class="p">;</span>

                    <span class="k">case</span> <span class="sc">'\''</span><span class="p">:</span>
                        <span class="k">if</span> <span class="p">(</span><span class="n">escape</span><span class="p">)</span> <span class="p">{</span>
                            <span class="n">escape</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
                        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                            <span class="n">quote</span> <span class="o">=</span> <span class="o">!</span><span class="n">quote</span><span class="p">;</span>
                        <span class="p">}</span>
                        <span class="k">break</span><span class="p">;</span>

                    <span class="k">case</span> <span class="sc">'\0'</span><span class="p">:</span>
                        <span class="k">goto</span> <span class="n">nullchar</span><span class="p">;</span>

                    <span class="nl">default:</span>
                        <span class="k">if</span> <span class="p">(</span><span class="n">escape</span><span class="p">)</span> <span class="p">{</span>
                            <span class="n">escape</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
                        <span class="p">}</span>
                        <span class="k">break</span><span class="p">;</span>
                <span class="p">}</span>

                <span class="c1">// print char then skip it (to make sure we don’t double match)</span>
                <span class="n">putchar</span><span class="p">(</span><span class="n">line</span><span class="p">[</span><span class="n">pos</span><span class="p">]);</span>
                <span class="n">line</span> <span class="o">=</span> <span class="n">line</span> <span class="o">+</span> <span class="n">pos</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
                <span class="n">pos</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></td></tr></tbody></table></code></pre></figure>

<p><a href="https://gist.github.com/lavoiesl/9a08e399fc9832d12794">View Gist</a></p>

<p>The only flaw that I can think of is that the parser will fail if the 10001st character of a line is an escaped quote, it will see it as an unescaped quote.</p>

<p>Happy dumping !</p>]]></content><author><name>Sebastien Lavoie</name></author><category term="MySQL" /><category term="sysadmin" /><summary type="html"><![CDATA[The official mysqldump supports more or less two output styles: separate INSERTs (one insert statement per row) or extended INSERTs (one insert per table). Extended INSERTs are much faster, but MySQL write them all in one line, the result being a SQL very hard to read. Can we get the best of both worlds ?]]></summary></entry><entry><title type="html">Using PHP’s mb_detect_encoding to cleanup your data</title><link href="http://blog.lavoie.sl/2014/06/using-phps-mbdetectencoding-to-cleanup" rel="alternate" type="text/html" title="Using PHP’s mb_detect_encoding to cleanup your data" /><published>2014-06-16T14:29:00-04:00</published><updated>2014-06-16T14:29:00-04:00</updated><id>http://blog.lavoie.sl/2014/06/using-phps-mbdetectencoding-to-cleanup</id><content type="html" xml:base="http://blog.lavoie.sl/2014/06/using-phps-mbdetectencoding-to-cleanup"><![CDATA[<p>Ever heard of <code class="language-plaintext highlighter-rouge">iso-8859-1</code> ? Yeah… that nightmare… With it, my name ends up more often than not… SÃ©bastien. The <a href="https://www.youtube.com/watch?v=MijmeoH9LT4">computers gurus came up one day with UTF-8</a> and all our problems should have been solved; one encoding to rule them all.</p>

<p>Sweet, let’s all switch to UTF-8 ! Oh wait… legacy projects… PHP internal encoding is still not UTF-8 and functions like strlen() are still not able to properly process multi-bytes strings. It is being said that <a href="http://philsturgeon.co.uk/blog/2013/01/php-6-pissing-in-the-wind">UTF-8 should land in PHP 6</a>, but in the mean time, we still have to do something.</p>

<p>I am currently working on a big project with a lot of spaghetti-legacy code with <em>a lot</em> of entry points to the database. Almost all the data is stored in one big table, but not encoded uniformly. When I started working on it, tables had fields with a combinaison of  ascii_bin, utf8<em>general_ci, latin_general_ci and latin</em><strong>swedish</strong>_ci … and we are in Canada ! In all those fields, data was stored with absolutely no guaranty of its encoding. Data was retrieved and passed through a series of UTF-8 encode/decode and stuff like this:</p>

<figure class="highlight"><pre><code class="language-php" data-lang="php"><span class="k">if</span> <span class="p">(</span><span class="nb">strpos</span><span class="p">(</span><span class="nv">$string</span><span class="p">,</span> <span class="s1">'Ã©'</span><span class="p">)</span> <span class="o">!==</span> <span class="kc">false</span><span class="p">)</span> <span class="p">{</span>
<span class="err"> </span> <span class="err"> </span><span class="nv">$string</span> <span class="o">=</span> <span class="nb">utf8_decode</span><span class="p">(</span><span class="nv">$string</span><span class="p">);</span>
<span class="p">}</span></code></pre></figure>

<p>I eventually managed to change every field, change all database connections and remove and traces of encode/decode. However, I still had the problem of having data not encoded properly in <em>some</em> rows/columns. You may or may not be familiar with mb_detect_encoding, here is a very simple trick:</p>

<figure class="highlight"><pre><code class="language-php" data-lang="php"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
</pre></td><td class="code"><pre><span class="cp">&lt;?php</span>
<span class="c1"># check-utf8-db.php</span>

<span class="c1">// $pdo = new PDO(...)</span>

<span class="nv">$charsets</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span><span class="s1">'UTF-8'</span><span class="p">,</span> <span class="s1">'ISO-8859-1'</span><span class="p">);</span>

<span class="nv">$tables</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span>
    <span class="s1">'events'</span> <span class="o">=&gt;</span> <span class="k">array</span><span class="p">(</span>
        <span class="s1">'title'</span><span class="p">,</span>
        <span class="s1">'description'</span><span class="p">,</span>
    <span class="p">),</span>
    <span class="s1">'locations'</span> <span class="o">=&gt;</span> <span class="k">array</span><span class="p">(</span>
        <span class="s1">'title'</span><span class="p">,</span>
        <span class="s1">'description'</span><span class="p">,</span>
    <span class="p">),</span>
<span class="p">);</span>

<span class="k">foreach</span> <span class="p">(</span><span class="nv">$tables</span> <span class="k">as</span> <span class="nv">$table</span> <span class="o">=&gt;</span> <span class="nv">$fields</span><span class="p">)</span> <span class="p">{</span>
    <span class="nv">$result</span> <span class="o">=</span> <span class="nv">$pdo</span><span class="o">-&gt;</span><span class="nf">query</span><span class="p">(</span><span class="s1">'SELECT id, '</span> <span class="mf">.</span> <span class="nb">implode</span><span class="p">(</span><span class="s1">', '</span><span class="p">,</span> <span class="nv">$fields</span><span class="p">)</span> <span class="mf">.</span> <span class="s1">' FROM '</span> <span class="mf">.</span> <span class="nv">$table</span><span class="p">);</span>
    
    <span class="k">while</span> <span class="p">(</span><span class="nv">$row</span> <span class="o">=</span> <span class="nv">$result</span><span class="o">-&gt;</span><span class="nf">fetch</span><span class="p">())</span> <span class="p">{</span>
        <span class="k">foreach</span> <span class="p">(</span><span class="nv">$fields</span> <span class="k">as</span> <span class="nv">$field</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">if</span> <span class="p">((</span><span class="nv">$encoding</span> <span class="o">=</span> <span class="nb">mb_detect_encoding</span><span class="p">(</span><span class="nv">$row</span><span class="p">[</span><span class="nv">$field</span><span class="p">],</span> <span class="nv">$charsets</span><span class="p">,</span> <span class="kc">true</span><span class="p">))</span> <span class="o">!=</span> <span class="s1">'UTF-8'</span><span class="p">)</span> <span class="p">{</span>
                <span class="k">echo</span> <span class="nv">$table</span> <span class="mf">.</span> <span class="s1">'['</span> <span class="mf">.</span> <span class="nv">$row</span><span class="p">[</span><span class="s1">'id'</span><span class="p">]</span> <span class="mf">.</span> <span class="s1">']'</span> <span class="mf">.</span> <span class="s1">'.'</span> <span class="mf">.</span> <span class="nv">$field</span> <span class="mf">.</span> <span class="s1">': '</span> <span class="mf">.</span> <span class="nv">$encoding</span> <span class="mf">.</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">;</span>

                <span class="nv">$converted</span> <span class="o">=</span> <span class="nb">iconv</span><span class="p">(</span><span class="nv">$encoding</span><span class="p">,</span> <span class="s1">'UTF-8'</span><span class="p">,</span> <span class="nv">$row</span><span class="p">[</span><span class="nv">$field</span><span class="p">]);</span>
                <span class="nv">$stmt</span> <span class="o">=</span> <span class="nv">$pdo</span><span class="o">-&gt;</span><span class="nf">prepare</span><span class="p">(</span><span class="s1">'UPDATE '</span> <span class="mf">.</span> <span class="nv">$table</span> <span class="mf">.</span> <span class="s1">' SET '</span> <span class="mf">.</span> <span class="nv">$field</span> <span class="mf">.</span> <span class="s1">' = ? WHERE id = ?'</span><span class="p">);</span>
                <span class="nv">$stmt</span><span class="o">-&gt;</span><span class="nf">execute</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="nv">$converted</span><span class="p">,</span> <span class="nv">$row</span><span class="p">[</span><span class="s1">'id'</span><span class="p">]));</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></td></tr></tbody></table></code></pre></figure>

<p><a href="https://gist.github.com/lavoiesl/d7a41597c8023978cab7">View Gist</a></p>

<p>Once you have detected the encoding, use iconv to convert it. This crunched through my 1GB database in no time and I was then sure that everything was in UTF-8.</p>

<p>Of course, this is an example with a database, it can work with any data. This script could also be faster if all updates where done at the same time for each row.</p>

<p>Please, save yourself some trouble, make sure all user content is in UTF-8.</p>]]></content><author><name>Sebastien Lavoie</name></author><category term="UTF-8" /><category term="PHP" /><summary type="html"><![CDATA[Ever heard of iso-8859-1 ? Yeah… that nightmare… With it, my name ends up more often than not… SÃ©bastien. The computers gurus came up one day with UTF-8 and all our problems should have been solved; one encoding to rule them all.]]></summary></entry><entry><title type="html">Simple custom CSS checkboxes with Font Awesome</title><link href="http://blog.lavoie.sl/2014/05/simple-custom-css-checkboxes-with-font-awesome" rel="alternate" type="text/html" title="Simple custom CSS checkboxes with Font Awesome" /><published>2014-05-23T15:55:00-04:00</published><updated>2014-05-23T15:55:00-04:00</updated><id>http://blog.lavoie.sl/2014/05/simple-custom-css-checkboxes-with-font-awesome</id><content type="html" xml:base="http://blog.lavoie.sl/2014/05/simple-custom-css-checkboxes-with-font-awesome"><![CDATA[<p>Browsers make it notoriously hard to modify the default form elements like dropdowns and checkboxes. For ages, the only way to add a custom style was to use images and <a href="http://www.csscheckbox.com/">CSS Checkbox</a> gives a very good example of this. However, using images is more of a hack than anything else, developers usually prefer to avoid them for good reason: hard to modify, adds to the loading time, flicker when hovering unless you preload or you use sprites, and resolution issues when scaling.</p>

<p>Then came the Javascript solutions. I personally like <a href="http://harvesthq.github.io/chosen/">Chosen</a> for custom dropdowns. These solutions are usually well supported cross-browser and are highly customizable and reliable, but they have the downside of being… Javascript. This means additional libraries, loading time, etc.</p>

<p>The holy grail is to use native CSS: you can customize it as you like, it can be built on top of your site’s stylesheet, inheriting the colours, the fonts, etc. There are a lot of examples out there that will show you working solutions, but they are usually complex. Here is a quick tutorial:</p>

<h3 id="the-basics">The basics</h3>

<p>The concept is to define a custom element that will have a different style based on the state of the input element. No javascript and barely any extra markup. We will hide the original input, but it will continue to work as intended.</p>

<h4 id="base-html">Base HTML</h4>

<figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt">&lt;label&gt;</span>
  <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"checkbox"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;span</span> <span class="na">class=</span><span class="s">"icon"</span><span class="nt">&gt;&lt;/span&gt;</span>
  My label
<span class="nt">&lt;/label&gt;</span></code></pre></figure>

<h4 id="base-css">Base CSS</h4>

<figure class="highlight"><pre><code class="language-css" data-lang="css"><span class="nt">input</span> <span class="p">{</span>
  <span class="nl">display</span><span class="p">:</span> <span class="nb">none</span><span class="p">;</span>
<span class="p">}</span>
<span class="nc">.icon</span> <span class="p">{</span>
  <span class="nl">visibility</span><span class="p">:</span> <span class="nb">hidden</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt">input</span><span class="nd">:checked</span> <span class="o">+</span> <span class="nc">.icon</span> <span class="p">{</span>
  <span class="nl">visibility</span><span class="p">:</span> <span class="nb">visible</span><span class="p">;</span>
<span class="p">}</span></code></pre></figure>

<p>This way, the input is always hidden and the .icon is hidden only when the input is not checked.</p>

<p>** The :checked selector is not available for IE8 and lower.</p>

<h3 id="working-demo">Working demo</h3>

<p>For a basic demonstration: <a href="http://codepen.io/lavoiesl/pen/rjcIx">http://codepen.io/lavoiesl/pen/rjcIx</a>. The CSS is divided in section to clearly see what is essential. This demo uses <a href="http://fortawesome.github.io/Font-Awesome/">Font Awesome</a> to have a nice and clean checkmark.</p>

<p>For more complex examples, see <a href="http://cssdeck.com/labs/css-checkbox-styles">http://cssdeck.com/labs/css-checkbox-styles</a>.</p>]]></content><author><name>Sebastien Lavoie</name></author><category term="tutorial" /><category term="codepen" /><category term="CSS" /><category term="checkbox" /><summary type="html"><![CDATA[Browsers make it notoriously hard to modify the default form elements like dropdowns and checkboxes. For ages, the only way to add a custom style was to use images and CSS Checkbox gives a very good example of this. However, using images is more of a hack than anything else, developers usually prefer to avoid them for good reason: hard to modify, adds to the loading time, flicker when hovering unless you preload or you use sprites, and resolution issues when scaling.]]></summary></entry><entry><title type="html">Secure your SSL/TLS server</title><link href="http://blog.lavoie.sl/2014/04/secure-your-ssltls-server" rel="alternate" type="text/html" title="Secure your SSL/TLS server" /><published>2014-04-09T10:55:00-04:00</published><updated>2014-04-09T10:55:00-04:00</updated><id>http://blog.lavoie.sl/2014/04/secure-your-ssltls-server</id><content type="html" xml:base="http://blog.lavoie.sl/2014/04/secure-your-ssltls-server"><![CDATA[<h3 id="heartbleed">Heartbleed</h3>

<p>Recently the <a href="http://heartbleed.com/">Heartbleed bug</a> came to light. It is a bug in the OpenSSL library that causes information to leak from the server. It is an undetectable backdoor that allows to gain the private key of your server. Let’s just say it is VERY important to fix it. Most distros have been very quick to propagate the OpenSSL update, so running your favorite update manager should fix it in no time.</p>

<p>To verify if you have protected, run this command and check for built on to be greater or equal to April 7th, 2014:</p>

<figure class="highlight"><pre><code class="language-shell" data-lang="shell"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
</pre></td><td class="code"><pre><span class="nv">$ </span>openssl version <span class="nt">-a</span>

OpenSSL 1.0.1e 11 Feb 2013
built on: Mon Apr 7 20:33:19 UTC 2014
platform: debian-amd64
</pre></td></tr></tbody></table></code></pre></figure>

<h3 id="disable-weak-ciphers">Disable weak ciphers</h3>

<p>The way SSL/TLS works is that the client and the server must agree on a cipher to use for encryption. If you were to attack a server, you would obviously use the least secure cipher. To protect against this, simply disable ciphers to be known as weak or those which flaws have been discovered.</p>

<p>I am using this configuration for Apache:</p>

<figure class="highlight"><pre><code class="language-shell" data-lang="shell"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
</pre></td><td class="code"><pre>SSLCipherSuite ALL:!ADH:!AECDH:RC4+RSA:+HIGH:+MEDIUM:!LOW:!SSLv2:!EXPORT
</pre></td></tr></tbody></table></code></pre></figure>

<p>For Nginx, see their <a href="http://wiki.nginx.org/NginxHttpSslModule#ssl_ciphers">configuration reference</a>. Since 1.0.5, they are using a sensible default. Otherwise, you can use the same as above.</p>

<h3 id="do-not-use-a-too-weak-or-too-strong-private-key">Do not use a too weak or too strong private key</h3>

<p>The private key must never be discovered. Otherwise, anyone could decrypt the content and could perpetrate a <a href="http://en.wikipedia.org/wiki/Man-in-the-middle_attack">MITM attack</a>. If the private key is too weak, it could eventually be guessed given enough data. However, SSL/TLS handshakes are very CPU intensive for both the server and the client. Using a key too long will considerably slow down your website. In most cases, 2048 is perfect.</p>

<h3 id="test-your-own-server">Test your own server</h3>

<p>SSL Labs provides a free test suite that will test your ciphers and for known attacks including BEAST and Heartbleed. This is a must: <a href="https://www.ssllabs.com/ssltest/">https://www.ssllabs.com/ssltest/</a></p>

<h3 id="further-reading">Further reading</h3>

<p>I am not a security expert, I simply happen to have done hosting for quite a time. I suggest you do not take my word blindly and go check this <a href="https://www.ssllabs.com/downloads/SSL_TLS_Deployment_Best_Practices_1.3.pdf">very pertinent paper from SSL Labs</a>.</p>]]></content><author><name>Sebastien Lavoie</name></author><category term="Security" /><category term="Apache" /><category term="Nginx" /><summary type="html"><![CDATA[Heartbleed]]></summary></entry></feed>