Report inadequate content

Development in Harecoded

Configure Compass,Sass,Less... in PHPStorm

 -

PHPStorm 6 bundles a new feature called "File watchers" which enables Sass, LESS, SCSS, CoffeeScript, TypeScript transpilation. This option will compile your compass/scss/whatever files when the source file is saved (this is when you lose the focus or manually save).

So, for the basic stuff you can stop using external programs and watchers likeCodeKit or LESS.app now. But of course unexpensive software like CodeKit is a must have if you are a frontend developer.

Our frontend guy decided to use Compass using SCSS source files so, the following example illustrates how to configure Compass in PHPStorm under Mac OS X, but this is something reusable for the rest of the languages supported by watchers. The procedure is basically the same for the others.

First of all, you have to install Compass. To do so open the Terminal and type:

sudo gem install compass

Then go to PHPStorm and open any of the SCSS files in your project and you'll see after a second or two a message inviting you to use File watchers. This is going to add under Preferences -> File Watchers a new entry that you can edit as follows:

Program: /usr/bin/compass
Arguments (If you compile files one by one): compile  $FilePath$
Arguments: (If you have SCSS in groups with ruby configurations):
compile  $ProjectFileDir$/relative/path/to/css/

 -

Now save the settings and every time you save one of these files you'll have the compiled SCSS file. Of course you can pass all the parameters you want in the section arguments to fit your needs. 

Ah, and this black theme is the Darcula theme that comes now bundled with the version 6.

Features in PHP 5.4

 -

We had to create a file upload form that allows a user to upload big files. In order to keep a good experience for the user we decided to show the progress bars.

There are several ways of doing that but it came to my mind that PHP 5.4 had an improvement on file upload, making it easier now and wondered if I had the last excuse to upgrade the servers from 5.3 to 5.4.

This is a list of some of the features PHP 5.4 comes with. There are more, but I came here with the intention of speaking about the ones that they care to me. This is not a 5.4 review, but examples.

Session upload progress

I already mentioned it, PHP 5.4 will be handy because now you can ask the server in realtime how the upload progress is going. Mixed with HTML5 you can have a kicking-ass upload form.

Speed

It seems that PHP 5.4 is faster than its ancestry, and I say that it seems because even there are plenty of sites claiming that I still have not run any benchmarks with my app.

Traits

Kids deserve  a candy sometime. We have regret many times using PHP because unlike other languages there has never been multiple inheritance. Now PHP gives us a sugar-free candy to mitigate this. Traits are not the multiple inheritane but might help you out sharing common functionallity between classes. And traits can use traits. This is an example of how a simple trait would work:

<?php
namespace Mammal\Primate;

trait Feeding
{
        public function getDiet( $age )
        {
                if ( $age < 3 )
                {
                        return [ 'breastfed' ];
                }
                else
                {
                        return [ 'fruit', 'leaves', 'flowers', 'buds', 'nectar', 'seeds', 'insects', 'bird eggs' ];
                }               
        }
}

Then your trait can be attached to any class like this, no matter if your class already extends something else:

class Gorilla extends VertebrateKingdom implements Animalia
{
        use \Mammal\Primate\Feeding;
        // ...
}

Now you can use the trait methods directly:

$gorilla = new Gorilla();
$gorilla->getDiet( 5 );

Python-alike stuff: lists and anonymous functions

Being a former pythonist I'm glad to have these two back in town:

Anonymous functions

Create functions on the fly: 

$dump = function( $var ) { var_dump( $var ) ; };
$dump( $gorilla->getDiet( 5 ) ); // Array containing 'fruit', 'leaves'...

Short array syntax

This is the same format than python lists, and the ability to get rid of temporary variables:

// Before: PHP < 5.3:

function getMammals()
{
        return array( 'monkey', 'zebra', 'dolphin', 'cat', 'John' );
}

$mammals = getMammals();
echo $mammals[0];

// Now: PHP 5.4+
function getMammals()
{
        $mammals = [ 'monkey', 'zebra', 'dolphin', 'cat', 'John' ];
}

echo getMammals()[0]; // Look that you don't need the temp variable anymore

Webserver

Finally, now you can run a debugging server without the need apache:

 php -S localhost:8080 -t /var/www/tests 

Not very useful in my case scenario where I have a full virtual environment with puppet and so on, but maybe for running temporary scripts might be useful. With earlier versions remind that you can always execute inline PHP from command line like this:

php -r "phpinfo();"

Yeah!!!

A life explained in HTTP status codes

This is a made-up story of a life explained with HTTP status code. It was written up to down at once without much thinking, feel free to improve it!

Status Code Event HTTP meaning
100 You are curious about her Continue
101 First time sex Switching Protocols
200 Love OK
201 She's pregnant Created
202 And you are the father Accepted
203 Were you looking forward it? Non-Authoritative Information
204 Think of a name  No Content
205 Baby is born. Your life starts again  Reset Content
206 Changing diapers Partial Content
300 Kids education Multiple Choices
301 New place to live  Moved Permanently
302 Your relation is elsewhere Found
303 She has an adventure See Other
304 At least is not pregnant  Not Modified
305 They used condom Use Proxy
306 Your toolbox remains... ( Unused )
307 Back to your parent's Temporary Redirect
400 Call your old girl friends Bad Request
401 Shit, all married Unauthorized
402 Maybe Hookers? Payment Required
403 You are bankrupt Forbidden
404 Reconsidering sexuality Not Found
405 In your ass Method Not Allowed
406 Confused Not Acceptable
407 Back to your wife's Proxy Authentication Required
408 Too late to say I miss you Request Timeout
409 I want the kids! Conflict
410 Custody trial Gone
411 Penis enlargement Length Required
412 That was not the problem Precondition Failed
413 That does not fit in Request Entity Too Large
414 Too long Request-URI Too Long
415 Try the other gender Unsupported Media Type
416 Not a good idea Requested Range Not Satisfiable
417 Not enjoying it Expectation Failed
500 You feel like crap: Psychiatrist Internal Server Error
501 No cure found yet Not Implemented
502 Bingos, hookers and alcohol  Bad Gateway
503 You are getting old Service Unavailable
504 Viagra Gateway Timeout
505 Mental institution HTTP Version Not Supported

HTTP specification can be found here

Llamadas cURL a través de distintas interfaces


 - Si tu servidor web dispone de varias interfaces de red y quieres que ciertas peticiones que haces con cURL salgan a través de una IP específica puedes modificar el flag CURLOPT_INTERFACE de cURL pásandole la IP.

Un ejemplo tonto podría ser:

...
// Todas mis interfaces de red:
$interfaces = array(
        '91.121.157.41',
        '178.33.161.225',
        '188.165.128.67',
        '178.33.166.125',
        '178.33.163.125',
);
// Salir aleatoriamente por una de ellas:
$rand_interface = $interfaces[rand(0,count($interfaces)-1)];
curl_setopt($curl_handle, CURLOPT_INTERFACE, $rand_interface );
...

Esto te puede servir tanto para balancear carga, como para forzar que una petición venga de un orígen único. Especialmente útil para hacer cosas feas en servidores con IP failover.

En una máquina con IP Failover la lista de interface de red puede ser:

cat /etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
        address 91.121.157.41
        netmask 255.255.255.0
        network 91.121.157.0
        broadcast 91.121.157.255
        gateway 91.121.157.254


auto eth0:0
iface eth0:0 inet static
        address 178.33.161.225
        netmask 255.255.255.255

auto eth0:1
iface eth0:1 inet static
        address 188.165.128.67
        netmask 255.255.255.255


auto eth0:2
iface eth0:2 inet static
        address 178.33.166.125
        netmask 255.255.255.255

auto eth0:3
iface eth0:3 inet static
        address 178.33.163.125
        netmask 255.255.255.255

Copy/clone/duplicate a mysql database script

 TAGS:This is a simple script that duplicates your entire database. There are many ways in which you can take advantage of having an exact replica of your production database.

In short, the behaviour of the script is the following (in this order, all piped):

  1. Delete the COPY database if possible to start with a fresh one
  2. Create the COPY database
  3. Dump the PRODUCTION database
  4. Inject the output of the dump into the COPY database
Read more

Varnish allow/reject connections with IPs list (ACL)

 TAGS:In a web server you can use directives to deny the unwanted eye to look at your content. This is an example of how Apache would handle a virtual host that only accepts connections from a series of IPs, but in Varnish that won't work.

        Order Deny,Allow
        Deny from all
        # Barcelona IPs
        Allow from 89.140.xxx.xxx/27
        # Japan IP
        Allow from 222.229.xxx.xxx/32

The reason that this won't work in Varnish is because the IP Apache is receiving is 127.0.0.1. (Varnish is the one connecting to Apache, not the client). The real client IP comes in the header X-HTTP-FORWARDED-FOR. If you want to fix this situation with Varnish in the middle you have basically two options:

Read more

Evitar que Chrome lance a Google tu url como búsqueda

El problema

Como desarrollador cada vez me siento más cómodo trabajando con Google Chrome pero hay una cosa que muchas veces me hace perder algo de tiempo:

En ocasiones, al intentar buscar una url poco "normal", como puede ser en un dominio típico en un entorno de desarrollo, Chrome detecta que no es una url válida y la lanza contra Google en forma de búsqueda.

Un ejemplo

Queremos acceder a nuestra working copy con una url como ésta: development_area/test_script.php

 TAGS:

 

 

Cuando pulsamos Enter, Chrome nos lleva a esta pantalla por tratarse de un dominio que, bajo su opinión, es inválido:

 TAGS:

 

 

 

 

 

La solución

La solución pasa por cambiar el buscador por defecto de Chrome.

Vayamos a chrome://chrome/settings/ y pulsemos en "Administrar motores de búsqueda..."

 TAGS:

 

 

 

 

 

 

 Ahora, elige cualquiera de los que hay y lo modificamos escribiendo 'null' en el campo del medio y http://%s en el de la derecha. Para poder editarlo sólo hay que pulsar sobre lo que ya hay escrito.

Ahora pulsa en "Establecer como predeterminado". 

 TAGS:

 

Lo sé!, es una de esas pequeñas cosas que mejorán tu vida ;).

 

Fuente: http://superuser.com/questions/354338/force-chrome-to-open-urls-as-urls-instead-of-searching

Varnish VCL: Delete ALL cookies and other magic

This morning Javi Callón gave me a great introduction in few minutes to the Varnish in steroids world, I really appreciate it.  I'd like to share this snippet which might be very interesting for you if you are new to the Varnish magic too.

This has been my first contact with Varnish ever, and I have to say I am quite amazed on how the application is responding now in terms of performance. Do not take this snippet as a definitive solution to your problems.

I wrote an article yesterday on how to install Varnish. Truth is that if you install Varnish and you do not tune the VCL file chances are that Varnish is not caching anything because of the cookies. In a dynamic application there are a lot of factors that have to be taken (headers, user-agents, variations...)

This sample VCL tries to address the following problems:

  • Ignore a specific host (do not cache)
  • Remove ALL the cookies in the caching (the application does not need any of them)
  • Change the varnish cache of the images to 5 minutes
  • Special case when the URL contains a GET parameter ?rev=
  • Add in the response headers number of hits and if was a HIT or a MISS

Open the file/etc/varnish/default.vcl and add the following. It is recommended to leave the rest of the comments as they are for future reference of what Varnish does by default.

The code is commented so you properly understand what it does and you can remove any pieces you don't need.

# You already have a block like this one when you installed Varnish, keep it safe:
backend default {
  .host = "127.0.0.1";
  .port = "8080";
}

# ADD THE FOLLOWING
# -----------------

# 2 things are done here:
# First, ignore any request to a specific host. For instance, you don't want Varnish on a specific host.
# Second, remove cookies, because my application does not rely on cookies at all.
sub vcl_recv {

     # Varnish will Ignore any request to this host  (e.g: xx.mydomain.com)
     if ( req.http.host ~ "([a-z0-9]{2}\.mydomain\.com)$" )
     {
        return(pipe);
     }

     #Goodbye incoming cookies:
     unset req.http.Cookie;

}


sub vcl_fetch {
    # Remove cookies that destroy cache:    
     unset beresp.http.Set-Cookie;

     # 5 minutes (300s) cache for images
    if ( req.url ~ "\.(jpg|jpeg|png|gif)$" )
     {
        set beresp.ttl = 300 s;
     }

    # This is very specific of SIFO.me framework, but you can recycle it:
    # Any static URL containing ?rev= (this is JS and CSS) cache it almost forever.
    # The following regexp will find urls like http://.../file.js?rev=1747c3872495221156287e2000a0d110
    if ( req.url ~ "\?rev=[a-f0-9]{32}$" )
    {
       set beresp.ttl = 600000 s;
    }
}

# Add some debug info headers when delivering the content:
# X-Cache: if content was served from Varnish or not
# X-Cache-Hits: Number of times the cached page was served
sub vcl_deliver {

        # Was a HIT or a MISS?
        if ( obj.hits > 0 )
        {
                set resp.http.X-Cache = "HIT";
        }
        else
        {
                set resp.http.X-Cache = "MISS";
        }

        # And add the number of hits in the header:
        set resp.http.X-Cache-Hits = obj.hits;
}

Try if the configuration syntax is OK with:

/etc/init.d/varnish configtest

And then restart the service (also wipes the cache).

/etc/init.d/varnish restart

The new headers should appear and you will be able to see what Varnish is doing with a simple CURL or with any browser Inspector. Example:

[root@mnm1 mnm]# curl --head http://yourhost,com
HTTP/1.1 200 OK
Server: Apache/2.2.15 (CentOS)
X-Powered-By: PHP/5.3.3
Cache-Control: public, must-revalidate, max-age=30, s-maxage=43200
Vary: Accept-Encoding
Content-Type: text/html; charset=UTF-8
Date: Tue, 09 Oct 2012 13:38:41 GMT
X-Varnish: 1572155458 1572155457
Age: 12
Via: 1.1 varnish
Connection: keep-alive
X-Cache: HIT
X-Cache-Hits: 1

Have in mind that all these functions are appended to the default behaviour. So they are adding extra things, but not preventing the default Varnish workflow take action.

In the cases where the time to live of the cache (TTL) is not set ,Varnish will cache it for 2 minutes (look for "120 s" in the deafault.vcl code).

All in all, it seems to me that for the huge benefit that Varnish adds to a project, the investment of time and resources you have to put on are ridiculous (half morning if your dynamic app doesn't have excessive magic). Do not be scared and try to add Varnish at least in your static files, then move to the dynamics.

Simple Varnish Installation

The first thing to do is to make sure your application is passing the headers properly. At least you'll need this (in PHP):

// Let's say Varnish caches for 12 hours:
$cache_max_age = 60*60*12;
header( "Cache-Control: public, must-revalidate, max-age=0, s-maxage=$cache_max_age" ); 

Varnish installation (CentOS/Redhat):
RPM taken from https://www.varnish-cache.org/installation/redhat

rpm --nosignature -i http://repo.varnish-cache.org/redhat/varnish-3.0/el5/noarch/varnish-release-3.0-1.noarch.rpm

After adding the package:

yum install varnish

If you have another Linux see in the link, is more or less the same.

Now Varnish is installed. What we want to do next is to configure Apache to listen in another port and let the port 80 for Varnish. Varnish will be the one requesting to Apache the html and saving it in the memory for later accesses.

We will use as example the port 8080 for Apache. The first thing is to tell Varnish, where Apache will be listening to:

vi /etc/varnish/default.vcl

# Change the port to 8080, like this. Leave the rest of file as is:
backend default {
  .host = "127.0.0.1";
  .port = "8080";
}

Then we have to change Varnish to make it listen in port 80:

vi /etc/sysconfig/varnish

# Change VARNISH_LISTEN_PORT variable to 80, like this:
VARNISH_LISTEN_PORT=80

And now in the Apache settings make it listen to 8080:

vi /etc/httpd/conf/httpd.conf
# Change the Listen variable to 8080:

Listen 8080

If you use Named Virtualhosts using the port number (e.g: You declare them with NameVirtualHost *:80) you'll need to change them to 8080 too. I usually store my virtual configurations under this file, use yours:

vi /etc/httpd/conf.d/virtual.conf

# You can replace all the 80 by 8080 easily with vi with (take care there aren't other things changed):
:%s/80/8080/g

And now hold your breathe. Stop both services and start them again to make changes effective:

/etc/init.d/httpd stop
/etc/init.d/varnish stop
/etc/init.d/httpd start
/etc/init.d/varnish start

Your application should be served by Varnish now. Check in the "Network" tab of your Google Chrome or Firefox that the headers are properly passed:

 TAGS:

How to setup a remote development environment over SFTP (working copy)

This article explains how to setup the server and client to work with a remote working copy.

To properly understand this post you should have read the previous post, When to setup a remote development environment over SFTP (working copy).

To have the enviroment up and running you must setup once the server, and then apply the configuration of the client in every developer machine. But the client side is very simple and requires no installation at all.

Here's how:

Read more