PHP: checking links validity using multi-thread processes

janvier 12th, 2012
by Axel

I recently came to a situation where I had to check 1800 links validity. No chance to do it manually. I decided to write some PHP code to check these URLs using the PHP get_headers function. Checking an URL seems easy but it takes a tiny amount of time to process because it calls distant resources: DNS lookup, connection time, download time… for each request. Using a simple « while » PHP function, you may come across three issues:

  1. it may be very long to complete and it’s not always possible to increase the PHP maximum execution time
  2. the display: your web page will be blank for quite a long time until enough data is processed. Of course you may play with the buffer handler but still!
  3. the process: as PHP is not a multi-threaded language out of the box, it will check one link by one. Much longer…

Therefore, I developed a very simple peace of code to solve these issues. As it is working quite softly, I decided to share it with you.
Read the rest of this entry »

Popularity: 3% [?]

Tags: , , , , , , ,
Posted in Développement, Technologies | Comments (0)

PHP: How to extract attachments from email

janvier 4th, 2012
by Axel

I’ve been busy working on a piece of code whose role is to extract all attachments from emails using PHP and IMAP. It is not really simple so here’s a recursive function doing that work:

<?php

// You may change options here
$server = "{imap.domain.com:143/notls}INBOX";
$username = "valentin@domain.com";
$password = "valentin";
$mbox = imap_open($server, $username, $password);

// Getting all emails
if ($headers = imap_headers($mbox)) {
	$i = 0;
	foreach ($headers as $val) {
		$i ++;

		// Will return many infos about current email
		// Use var_dump($info) to check content
		$info = imap_headerinfo($mbox, $i);

		// Gets the current email structure (including parts)
		// Use var_dump($structure) to check it out
		$structure = imap_fetchstructure($mbox, $info->Msgno);

		// Getting attachments
		// Will return an array with all included files
		// Also works with inline attachments
		$attachments = get_attachments($structure);

		// You are now able to get attachments' raw content
		foreach ($attachments as $k => $at) {
			$content = imap_fetchbody($mbox, $info->Msgno, $at['part']);
			switch ($at['encoding']) {
				case '3':
					$content = base64_decode($content);
				break;

				case '4':
					$content = quoted_printable_decode($content);
				break;
			}
		}

	}
}
// Shutting down
imap_close($mbox); 

/**
* Gets all attachments
* Including inline images or such
* @author: Axel de Vignon
* @param $content: the email structure
* @param $part: not to be set, used for recursivity
* @return array(type, encoding, part, filename)
*
*/
function get_attachments($content, $part = null) {
	static $results;

	// First round, emptying results
	if (is_null($part)) {
		$results = array();
	}

	// Removing first dot (.)
	if (substr($part, 0, 1) == '.') {
		$part = substr($part, 1);
	}

	// Checking ifdparameters
	if (isset($content->ifdparameters) && $content->ifdparameters == 1 && isset($content->dparameters) && is_array($content->dparameters)) {
		foreach ($content->dparameters as $object) {
			if (isset($object->attribute) && strtolower($object->attribute) == 'filename') {
				$results[] = array(
					'type'			=> (isset($content->subtype)) ? $content->subtype : '',
					'encoding'		=> $content->encoding,
					'part'			=> (is_null($part)) ? 1 : $part,
					'filename'		=> $object->value
				);
			}
		}
	}

	// Checking ifparameters
	else if (isset($content->ifparameters) && $content->ifparameters == 1 && isset($content->parameters) && is_array($content->parameters)) {
		foreach ($content->parameters as $object) {
			if (isset($object->attribute) && strtolower($object->attribute) == 'name') {
				$results[] = array(
					'type'			=> (isset($content->subtype)) ? $content->subtype : '',
					'encoding'		=> $content->encoding,
					'part'			=> (is_null($part)) ? 1 : $part,
					'filename'		=> $object->value
				);
			}
		}
	}

	// Recursivity
	if (isset($content->parts) && count($content->parts) > 0) {
		// Other parts into content
		foreach ($content->parts as $key => $parts) {
			get_attachments($parts, ($part.'.'.($key + 1)));
		}
	}
	return $results;
}

Bonus tip: you may display images using their raw content data. For instance, the following HTML code will display a red dot:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot">

The result:
Red dot

Popularity: 2% [?]

Tags: , , , , ,
Posted in Développement, Technologies | Comments (0)

Postfix – how to handle dynamic addresses

janvier 3rd, 2012
by Axel

On the 25th of february 2010, I wrote a post explaining how to handle domain aliases with Postfix (http://vidax.net/blog/2010/02/domain-aliases-with-postfix/). I recently decided to add dynamic addresses support. Google uses this convenient feature. Let’s say your address is « james@domain.com ».  Using the dynamic addresses, you will be able to route « james+anything@domain.com » to your real address.

Read the rest of this entry »

Popularity: 4% [?]

Tags: , , ,
Posted in Système, Technologies | Comments (0)

How to handle SVN with Redmine

septembre 15th, 2011
by Axel

When it comes to project management, Redmine is one of the best tools according to me. Written in Ruby on Rails, it offers a huge amount of features in a clean, really nice and efficient interface. Plus it’s free and open source.

One of these features is related to Subversion. Redmine is able to interact with Subversion:

  • it has a powerful repository browser able to link tasks and commits.
  • it can manage SVN authentication. Redmine users have therefore access to the SVN repository with same username and password

In order to setup up this feature, you must follow this tutorial: http://www.redmine.org/projects/redmine/wiki/HowTo_to_handle_SVN_repositories_creation_and_access_control_with_Redmine

Sadly, this is not that simple. This tutorial doesn’t work on recent versions of Redmine (see post here: http://www.redmine.org/boards/2/topics/24383?r=26204). Redmine has updated it authentication system in adding a salt field. Initially, Redmine passwords were SHA1(password) only. Now passwords are SHA1(salt.SHA1(password)). This format is not supported by pam_mysql out of the box.

I’ve therefore patched pam_mysql.c. Patch is here: http://pastebin.com/4SATdQ8u

In order to use it, you must:

  1. download pam_mysql source here
  2. apply the attached patch on pam_mysql.c using the « patch » command
  3. compile again pam_mysql: « make clean && make && make install »
  4. modify the MySQL ssh_users view running this SQL query:
    CREATE OR REPLACE VIEW ssh_users as
    select login as username, CONCAT(hashed_password, '|', salt) as password
    from users
    where status = 1;
  5. edit /etc/pam.d/sshd and set crypt=5 for the 3 blocks

Auth will now take the salt into account. For pam_mysql-0.7RC1 only.
Let me know whether it works

Popularity: 14% [?]

Tags: , , , , ,
Posted in System, Technology | Comments (0)

WordPress 3 nginx virtualhost configuration

juin 22nd, 2011
by Axel

Hi there,

another configuration file for WordPress 3 running on Nginx:


server
        {
                listen 80;
                server_name blog.******.com;
                root /var/www/blog;
                index index.php;

                location /
                {
                        try_files $uri $uri/ @wordpress;
                }

                # BLOCKS ACCESS TO . FILES (.svn, .htaccess, ...)
                location ~ /\. {
                        deny  all;
                }

                # FOR PHP FILES
                location ~* \.php$ {
                        try_files $uri $uri/ @wordpress;

                        fastcgi_pass 127.0.0.1:9000;
                        fastcgi_index index.php;
                        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                        include fastcgi_params;
                }

                location @wordpress {
                        fastcgi_pass 127.0.0.1:9000;
                        #fastcgi_index index.php;
                        include fastcgi_params;
                        fastcgi_param SCRIPT_FILENAME  $document_root/index.php;
                        break;
                }

                location ~ /\. {
                        deny  all;
                }

                location ~* \.css|\.js|\.jpg|\.jpeg|\.png|\.gif|\.swf|\.svg|\.tiff$ {
                        expires 30d;
                }
}

There you go!

Popularity: 10% [?]

Tags: , , ,
Posted in System, Technology | Comments (0)

SVN Merge en ligne de commandes

mai 24th, 2011
by Axel

Travaillant intensément avec Subversion, j’utilise plusieurs branches pour gérer mes sites de développement et mes sites de production. Je passe donc chaque fonctionnalité d’une branche à l’autre pour les passer en PROD, ce qui correspond à un « merge » SVN.

Read the rest of this entry »

Popularity: 12% [?]

Tags: , ,
Posted in Système, Technologies | Comments (0)

Le vol de session expliqué simplement

octobre 27th, 2010
by Axel

Depuis un jour ou deux, une extension pour Firefox fait trembler les géants tels que Facebook, Google ou Twitter. Cette extension baptisée FireSheep et s’installant en deux clics de souris, permet de voler les sessions sur une vingtaines de sites Internet connus. S’ajoutent à ceux cités précédemment Tumblr, Yahoo, Amazon, Basecamp, Dropbox, Flickr et j’en passe.

Read the rest of this entry »

Popularity: 45% [?]

Tags: , , , , , , , ,
Posted in Technologies, Vie privée | Comments (0)

Confidentialité sur Facebook? Est-ce si compliqué?

septembre 24th, 2010
by Axel

J’entends souvent autour de moi des personnes se plaindre de Facebook, du manque de respect de la vie privée et la complexité de leur système de confidentialité. Même s’il reste vrai que Facebook a tout intérêt à laisser votre profil aussi ouvert que possible, je trouve que leurs paramètres de confidentialité sont au contraire plutôt bien pensés lorsqu’on se creuse un peu la tête. Je vais tenter de vous détailler ma méthode que je trouve efficace.
Read the rest of this entry »

Popularity: 25% [?]

Tags: , , ,
Posted in Vie privée | Comments (0)

Sphinx accentuated characters

septembre 6th, 2010
by Axel

When indexing like me french content into Sphinx, accentuated and non-accentuated search queries will not return the same results. For instance, searching on « Môle » returns a result unlike a search on « Mole ».
Read the rest of this entry »

Popularity: 7% [?]

Posted in System, Technology | Comments (0)

Kohana with Nginx – VirtualHost configuration

juin 10th, 2010
by Axel

In order to improve performances, I chose to switch web server for one of my websites. I switched from Apache 2 to Nginx, extremely fast and powerful. It’s not easy to configure though: it took me a really long time to configure Nginx for Kohana 2. Here is my configuration file:

server {
	listen 80;
	server_name www.xxxx.com;
	root /var/www/xxxx/prod/public;
	index index.php;

	# ROUTING TO KOHANA IF REQUIRED
	location / {
		try_files $uri $uri/ @kohana;
	}

	# BLOCKS ACCESS TO . FILES (.svn, .htaccess, ...)
	location ~ /\. {
		deny  all;
	}

	# FOR PHP FILES
	location ~* \.php$ {
	 	# PHP FILES MIGHT BE TO HANDLED BY KOHANA
		try_files $uri $uri/ @kohana;

		fastcgi_pass 127.0.0.1:9000;
		fastcgi_index index.php;
		fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
		include fastcgi_params;
	}

	# HANDLES THE REWRITTEN URLS TO KOHANA CONTROLLER
	location @kohana
	{
		fastcgi_pass 127.0.0.1:9000;
		fastcgi_index index.php;
		include fastcgi_params;
		fastcgi_param SCRIPT_FILENAME $document_root/index.php;
	}

	# CACHE CONTROL FOR STATIC FILES
	location ~* \.css|\.js|\.jpg|\.jpeg|\.png|\.gif|\.swf|\.svg|\.tiff|\.pdf$ {
		expires 30d;
	}

	# REDIRECTING MEDIAS TO STATIC
	location ^~ /medias/ {
		rewrite ^/medias/(.*) http://static.xxxx.com/$1 permanent;
		break;
	}

}

server {
	listen 80;
	server_name static.xxxx.com;
	root /var/www/xxxx/medias/;
	expires 90d;

	location /videos/ {
		keepalive_timeout     200 190;

		#limit_conn   videos  2;
		mp4;
		limit_rate_after 512k;
		limit_rate 512k;

		error_page 404 = /videos/video_not_found.png;
	}
}

My homepage now loads in 1,5s instead of 7s before. Thanks to Nginx ;-)

Popularity: 100% [?]

Tags: , , , ,
Posted in System, Technology | Comments (2)