Code snippets, tech tricks and other bits and bobs

Integrating the Zencoder API

I have been working on integrating the Zencoder API with my CMS.

Where you have a configuration file that users can, of course, completely mangle, you need to do a lot of error checking to ensure that things are correctly set and keep the users informed.

Most of the things you will wanting to be checking are pretty straightforward, but one of the slightly more complex ones is the protocol for returning the encoded files.
Zencoder supports ftp, sftp and ftps, as well as Cloud File and Amazon S3.
Regex for testing protocols is widely available online, but we are looking at slightly less usual options than http(s) vs ftp.

Protocol:

First we need to allow for all 3 flavours of ftp

/^(s?(ftp)s?):\/\//

Cloud file uses their cf:// protocol, or alternatively cf+xx:// where xx is the two letter country code of the location - currently Cloud File supports us and uk, defaulting to us if not specified. However, realistically, Cloud File may support more countries in future, so we need to allow for them.

/^((cf)(\+[a-z]{2})?):\/\//
 

Amzon S3 uses their s3:// protocol.

/^(s3):\/\//i';

Sticking all three together we get:

/^(s?(ftp)s?|((cf)(\+[a-z]{2})?)|s3):\/\//'

To put it into action:

$host = 'ftps://mydomain.com';
$zencoder_protocol_regex = '/^(s?(ftp)s?|((cf)(\+[a-z]{2})?)|s3):\/\//i';

if(strpos($host, '://') > 0){
 preg_match($zencoder_protocol_regex, $host, $result);
 if(count($result) == 0){
 //Incorrect protocol
 }else{
 if($result[0] = 'ftp://'){
 //Protocol is ftp - give security warning
 }
 $protocol = $result[0];
 $host = str_replace($result[0], '' , $host);
 }
}else{
 $protocol = 'ftps://';
}

URL with username and password:

The next crucial step is to construct a valid destination url that includes a username and password, while allowing for S3 accounts, which don't require user/pass. Non alpha-numeric characters need to be percent encoded:

$user = 'username';
$pass = 'password';
$file = 'filename.ext';
if(strlen($user) > 0){ $user = rawurlencode($user) . ':';
}
if(strlen($pass) > 0){
 $pass = rawurlencode($pass) . '@';
}
$output = $protocol . $user . $pass . $host .  '/' . $file

So if we pass in the following variables:

$host = 'ftps://ftp.mydomain.com';
$user = 'bob@mydomain.com';
$pass = 'foo!';
$file = 'filename.ext';

We will get:
ftps://bob%40mydomain.com:foo%21@ftp.mydomain.com

Some notes on FTP protocols:

FTP: Completely unsecure - username and password sent in plain text
FTPS: User/pass sent over TLS/SSL - data not encrypted
SFTP: All data encrypted over SSH
So why not use SFTP all the time? Well, sometimes it's just not available if you are on a shared server, and if it is, it's often not available for additional FTP users as SSH requires shell access. As you don't want to be giving away your master FTP account details, an additional FTP account (which can point directly at the required folder) is preferable, and unless your videos are highly sensitive or valuable, FTPS should do just fine.

Want to see it all put together?

http://pastebin.com/iB3X1Dq5
This is the production code on my server, so it has a lot of things that are custom to the CMS - it should be pretty straightforward to follow though. You will also need to trawl it for the variables that need to be passed to the script, but you should be reading the Zencoder docs to familiarise yourself with the requirements anway. Sorry I don't have time to expand it all currently.
It is configured to output webm, ogg and mp4 files for HTML5 video players.

You will also need the API class from Zencoder - here's a copy for convenience:
http://pastebin.com/eVbF879j
I haven't yet integrated thumbnails, or processing a Zencoder notification returned to a script 

Filed under  //   FTP   FTPS   PHP   Regex   SFTP   Zencoder  

Multiple FTP users in Plesk 9

By now, Plesk is supposed to have built in support for creating multiple FTP users through the web interface, but it doesn’t seem to have materialised. So for the mean time, SSH is still the way forward:

Create ftp user with their own home directory:

# /usr/sbin/useradd -d $HTTPD_VHOSTS_D/your_domain/some/location -s /bin/false USER_NAME

Set the ftp user’s password:

# passwd USER_NAME

Add user to group psacln:

# /usr/sbin/usermod -G psacln USER_NAME

Change folder permissions for home directory:

# chmod 755 $HTTPD_VHOSTS_D/your_domain/some/location

Change ownership to user and group:

# chown USER_NAME:psacln $HTTPD_VHOSTS_D/your_domain/some/location

Set execute permission on the httpdocs folder for the domain:

# chmod 751 $HTTPD_VHOSTS_D/your_domain/httpdocs

At this point you have a valid FTP user who can connect. But only to their own folder. Now I want users with FTP write access to httpdocs so I can give 3rd party support access on occasion and later revoke it without having to change my master password. Also, all their actions will be logged as their user, so we have a data trail in case of things going pear shaped. This is as far as Parallels' guide goes, so we have to do a couple more steps:

Set the user’s home directory to the webroot:

# /usr/sbin/usermod -d $HTTPD_VHOSTS_D/your_domain/httpdocs/ USER_NAME

Grant write permissions to the group on the webroot:

# chmod g+w $HTTPD_VHOSTS_D/your_domain/httpdocs/

And we are done!

Where $HTTPD_VHOSTS_D is your vhosts path (typically /var/www/vhosts on the CentOS 5 boxes I’ve used) and USER_NAME is your chosen… errr, wossitcalled…

‘/some/location’ should be a non public access directory, e.g. /var/www/vhosts/your_domain/web_users/USER_NAME

These intstructions are tested on CentOS 5 / Plesk 9. They should work for other *nix flavours, but as with everything on t'net, excercise caution, and on your own head be it.

http://kb.parallels.com/en/415

Filed under  //   *nix   CentOS 5   FTP   Plesk 9   SSH   SysAdmin