Category Archives: Development

Apache Proxy with CORS headers

You want to have your JavaScript application access a remote API but that remote API does not have CORS headers. What to do?

Instead of pointing to that remote API, point to a location on an Apache server that you have control of, have it connect to that remote API for you, and also add the CORS headers so JavaScript is happy.

Apache can proxy, or hand off the API request for you while also injecting the CORS header Access-Control-Allow-Origin to that remote API response.

Requirements:
Apache mod_proxy
Apache mod_headers

# Proxy for BaseServer
<LocationMatch "/api">
   ProxyPass http://remote-server.com:8000/api/
   Header add "Access-Control-Allow-Origin" "*"
</LocationMatch>

Now instead of pointing my JavaScript to http://remote-server.com:8000/api/, I point it to my Apache server at /api/ and that will serve the data from http://remote-server.com:8000/api/ with the CORS header.

http://enable-cors.org/server_apache.html

If you are using mod_rewrite along with this, you might need the [P] flag which tells mod_rewrite to handle the request with mod_proxy.

https://httpd.apache.org/docs/2.4/rewrite/flags.html

An alternate animate.css animation order

Animate.css is a wonderful CSS animation library.

http://daneden.github.io/animate.css/

On the website, animations are grouped by types – “Attention Seekers”, “Bouncing Entrances”, “Bouncing Exits”, etc.

What I present is a revised order with In’s and Out’s grouped next to each other. This gives a nice effect when cycling through all the animations.

Continue reading An alternate animate.css animation order

Creating Retina Favicons

Simple instructions for creating Retina favicon:

Create a 16×16 PNG-24 for your low-res icon

Create a 32×32 PNG-24 for your high-res icon

Head over to http://convertico.org/Multi_Image_to_one_icon/ and upload those two icons together to create a dual-resource ico file which you rename to favicon.ico.

Upload that favicon.ico in the root of your webroot.

For some reason the meta tag <link rel=”icon” href=”favicon.ico”> seems to prevent the high-res version from working so I temporarily removed it. If you know the correct meta tag to be using for retina please let me know.

Here is what the difference looks like:
retina favicon

passfail.pl – Prevent password entry in IRSSI

Here is a little irssi script that will help prevent you entering your passwords into IRSSI

Click here to download the script: passfail.pl

Instructions are inside the file and below:

[perl]
use strict;
use Digest::MD5 qw(md5 md5_hex md5_base64);
use vars qw($VERSION %IRSSI);

#——————————————————————————
# passfail.pl – Help prevent you entering your passwords into IRC by mistake
#
# Copyright (C) 2010 Christopher Carey
# http://chriscarey.com
#
#——————————————————————————
# INSTALL:
#
# Stick the script passfail.pl into your .irssi/scripts/ directory.
# Symlink it into the autorun directory so it will run every time the
# application starts.
#
# cp passfail.pl .irssi/scripts/
# cd .irssi/scripts/
# ln -s passfail.pl autorun/
#
#——————————————————————————
# USAGE:
#
# Passfail has three basic commands: add, remove, show, and clearall.
#
# /passfail add <password>
#
# The previous command will add the password into the list of protected words.
# That password, if entered in the chat window, will not be sent to channel.
#
# /passfail remove <password>
#
# The previous command will remove the password from the list of protected words.
# If you type the password, it will be sent to channel.
#
# /passfail show
#
# The previous command will show the saved password hashes
#
# /passfail clearall
#
# The previous command will clear the list of protected words (start over).
#
#——————————————————————————
#
# TESTING:
#
# Test and configure on the (status) window, and not in a channel with users in it!
#
#——————————————————————————
#
# OTHER NOTES:
#
# You can manually load or unload the script with the following commands:
#
# /script load passfail.pl
# /script unload passfail
#
#

$VERSION = ‘20100804’;
%IRSSI = (
authors => ‘Chris Carey’,
contact => ‘chris@chriscarey.com’,
name => ‘passfail’,
description => ‘Prevent your password(s) from going over the wire accidentally’,
license => ‘BSD’,
url => ‘none’,
modules => ‘Digest::MD5’
);

my @password_md5s;

sub settings_register () {
# register the irssi settings (with defaults)
Irssi::settings_add_str("passfail", "passfail_hashes", "");
}

sub event_send_text () {

my ($line, $server_rec, $wi_item_rec) = @_;

# convert the input line to an array of strings
my @linearray = split(/ /, $line);
my @linearray_md5 = map { md5_hex($_) => $_ } @linearray;

# md5_hex each of the linearray elements
my %linearray_md5 = ();
map { $linearray_md5{$_} = 1 } @linearray_md5;

# compare each item in the array against the password hashes
my @intersection = grep { $linearray_md5{$_} } @password_md5s;
my $intersection_size = @intersection;

# compare the input to the array of password hashes
if ($intersection_size gt 0) {
# user entered password
Irssi::print("passfail.pl blocking password entry");
} else {
# user did not enter password
return;
}
Irssi::signal_stop();
}

sub display_hashes {
foreach(@password_md5s) {
Irssi::print($_);
}
}

sub settings_load {
# convert the comma separated hash list into an array
@password_md5s = split(‘,’, Irssi::settings_get_str(‘passfail_hashes’));
Irssi::print(scalar(@password_md5s)." password(s) loaded");
}

sub settings_save {
# convert the array to a comma seperated hash list and store it
my $hashes = join(‘,’, @password_md5s);
Irssi::settings_set_str(‘passfail_hashes’, $hashes);
Irssi::print(scalar(@password_md5s)." password(s) saved");
}

sub cmd_passfail {
# user typed the command /passfail

my $usage = "/passfail [add|remove|show|clearall] <password>";
my ($arguments, $server, $witem) = @_;
my @foo = split(/ /, $arguments);
my $cmd = @foo[0];
my $pw = @foo[1];
my $pw_md5 = md5_hex($pw);

# sanity check on inputs
if (!$arguments) {
Irssi::print($usage);
return;
}
if (length($cmd) eq 0 || length($pw eq 0)) {
Irssi::print($usage);
return;
}

# switch based on which command was specified
if ($cmd eq "add") {
# add password
if (grep(/$pw_md5/, @password_md5s)) {
Irssi::print("Password already exists");
} else {
Irssi::print("Adding new password…");
push(@password_md5s, $pw_md5);
&settings_save();
}
} elsif ($cmd eq "remove") {
# remove password
Irssi::print("Removing password…");
@password_md5s = grep { $_ ne $pw_md5 } @password_md5s;
&settings_save();

} elsif ($cmd eq "show") {
# display hashes
&display_hashes();

} elsif ($cmd eq "clearall") {
# clear all passwords
Irssi::print("Clearing all passwords…");
splice(@password_md5s);
&settings_save();

} else {
# invalid input, show usage
Irssi::print($usage);
}
}

# program start
settings_register();
settings_load();
Irssi::signal_add_first(‘send text’, "event_send_text");
Irssi::command_bind("passfail", "cmd_passfail");

[/perl]