autostart PSGI/Plack by amon2 + Starlet + Supervisor

Standard

######## config for supervisord

STEP1) make default config file.

# /usr/local/bin/echo_supervisord_conf > /etc/supervisord.conf

STEP2) un-commnet “include block”.

# vi /etc/supervisord.conf

[include]
files = /etc/supervisord.d/*.ini

######## autostart for supervisord

TYPE A)

# vi /etc/rc.d/rc.local
/usr/local/bin/supervisord -c /etc/supervisord.conf

TYPE B)

$ wget https://github.com/Supervisor/initscripts/ ????? (ex. redhat-init-jkoppe )

$ su -
# cp redhat-init-jkoppe /etc/rc.d/init.d/supervisord
# vi /etc/rc.d/init.d/supervisord
   path : /usr/bin/ -> /usr/local/bin/
# chmod 755 /etc/rc.d/init.d/supervisord
# cp redhat-sysconfig-jkoppe /etc/sysconfig/supervisord
# chkconfig --add supervisord
# chkconfig --list supervisord
# /etc/rc.d/init.d/supervisord start
Starting supervisord: 
/etc/rc.d/init.d/supervisord: line 36: PIDFILE: unbound variable

# /etc/rc.d/init.d/supervisord start
Starting supervisord: 
/etc/rc.d/init.d/supervisord: line 44: OPTIONS: unbound variable

If you have error “unbound variable” , you add “PIDFILE” , “OPTIONS” to “/etc/rc.d/init.d/supervisord”

# vi /etc/rc.d/init.d/supervisord

PIDFILE=/var/run/supervisord.pid
OPTIONS="-c /etc/supervisord.conf"

######## config for plack(starlet)

# vi /etc/supervisord.d/ean_starlet.ini

[program:ean-starlet]
directory=/var/www/Ean/app/Ean/script
command=/var/www/Ean/local/perl5/bin/start_server --port=5000
--interval=10 \
  -- /var/www/Ean/local/perl5/bin/plackup -E development \
  --no-default-middleware -s Starlet --max-workers=25 --timeout=1800 \
  --keepalive-timeout=0 --max-reqs-per-child=700 --min-reqs-per-child=1000 \
  /var/www/Ean/app/Ean/script/Ean-server
numprocs=1
autostart=true
autorestart=true
user=Eanapache
redirect_stderr=true
stdout_logfile=/var/log/Ean_starlet_log

※”-E development” means “$ export PLACK_ENV=development” .
######## set plack application to supervisord , and start

# /usr/local/bin/supervisorctl reread && /usr/local/bin/supervisorctl update
# /usr/local/bin/supervisorctl start ean-starlet

CGI::param called in list context from …, this can lead to vulnerabilities.

Standard

I hava a warning message, when I was testiing mod_perl + Devel::Cover.

CGI::param called in list context from /home/endo/dev/.../Test.pm line 304,
this can lead to vulnerabilities.
See the warning in "Fetching the value or values of a single named parameter"
at /usr/local/lib/perl5/site_perl/5.18.4/CGI.pm line 404.

Document of CGI.pm describes below.
http://search.cpan.org/perldoc?CGI

Warning - calling param() in list context can lead to vulnerabilities
if you do not sanitise user input as it is possible to inject other param keys
and values into your code.
This is why the multi_param() method exists,
to make it clear that a list is being returned,
note that param() can still be called in list context
and will return a list for back compatibility.

and

You can disable this warning by setting $CGI::LIST_CONTEXT_WARN to 0
or by using the multi_param() method instead.

I added next setting in my perl source code.

use CGI;
$CGI::LIST_CONTEXT_WARN = 0;

cperl-mode setting for perltidy in .emacs

Standard

“cperl-indent-parens-as-block” and “cperl-indent-subs-specially” are important.

(autoload 'cperl-mode "cperl-mode" "alternate mode for editing Perl programs" t)
(setq auto-mode-alist
      (append '(("\\.\\([pP][Llm]\\|al\\|cgi\\|t\\|psgi\\)$" . cperl-mode))
              auto-mode-alist ))
(add-hook 'cperl-mode-hook
          (lambda ()
            (setq cperl-font-lock t)
            (cperl-set-style "PerlStyle")
            (setq indent-tabs-mode nil)  ; use space for indent
            (hs-minor-mode 1)))          ; hodeshow-mode
(setq cperl-indent-parens-as-block t)
(setq cperl-indent-subs-specially nil)

(defalias 'perl-mode 'cperl-mode)  ; makes quickly

access (allow/deny) control by X-Forwarded-For (ip address) in nginx.conf

Standard

For example, under AWS ELB (load-balancer)

# for pre-open closed test
map $http_x_forwarded_for $allowed {
    default deny;
    ~\s*111.222.333.444$ allow;
    ~\s*123.456.789.*$   allow;
}

location / {
    if ( $allowed = "deny" ) { return 403; }
    alias /path/to/document_root
}

http://nginx.org/en/docs/http/ngx_http_access_module.html
http://nginx.org/en/docs/http/ngx_http_map_module.html

JSON.pm for perl has several encode/decode methods

Standard

http://search.cpan.org/perldoc?JSON

#!/usr/local/bin/perl
use strict;
use utf8;
use Encode;
use JSON;
use Data::Dumper;

main();

sub main {
    my $org_data =
        {hash_str_ascii =>      'ABCDE12345',
         hash_str_not_ascii =>  'あいうえお12345',
         hash_str_mix =>        'ABCDEあいうえお',
         array_int =>           [qw/01 2 3 4 5 6/]
        };

    to_from_json($org_data);            #### to_json / from_json       ####
    encode_decode_json($org_data);      #### encode_json / decode_json ####
    encode_decode_json_oo($org_data);   #### OO encode / decode        ####
}

sub to_from_json {
    my ($org_data) = @_;

    my $json_str = JSON::to_json($org_data);
    print "#### to_json / from_json ####\n";
    print Dumper($org_data);
    print encode('utf8',$json_str),"\n";
    print Dumper(JSON::from_json($json_str));
}

sub encode_decode_json {
    my ($org_data) = @_;

    my $json_str = JSON::encode_json($org_data);
    print "#### encode_json / decode_json ####\n";
    print Dumper($org_data);
    print encode('utf8',$json_str),"\n";
    print Dumper(JSON::decode_json($json_str));
}

sub encode_decode_json_oo {
    my ($org_data) = @_;

    # NOT generate characters outside the code range 0..127.
    # Any Unicode characters outside that range will be escaped
    # using either a single \uXXXX or a double \uHHHH\uLLLLL escape sequence,
    # as per RFC4627.
    my $json = JSON->new()->ascii(1);
    my $json_str = $json->encode($org_data);
    print "#### OO encode / decode ####\n";
    print Dumper($org_data);
    print encode('utf8',$json_str),"\n";
    print Dumper($json->decode($json_str));
}

↓RESULT

$ ./foo.pl 
#### to_json / from_json ####
$VAR1 = {
          'hash_str_mix' => "ABCDE\x{3042}\x{3044}\x{3046}\x{3048}\x{304a}",
          'hash_str_not_ascii' => "\x{3042}\x{3044}\x{3046}\x{3048}\x{304a}\x{ff11}\x{ff12}\x{ff13}\x{ff14}\x{ff15}",
          'array_int' => [
                           '01',
                           '2',
                           '3',
                           '4',
                           '5',
                           '6'
                         ],
          'hash_str_ascii' => 'ABCDE12345'
        };
{"hash_str_mix":"ABCDEあいうえお","hash_str_not_ascii":"あいうえお12345","array_int":["01","2","3","4","5","6"],"hash_str_ascii":"ABCDE12345"}
$VAR1 = {
          'hash_str_ascii' => 'ABCDE12345',
          'array_int' => [
                         '01',
                         '2',
                         '3',
                         '4',
                         '5',
                         '6'
                       ],
          'hash_str_mix' => "ABCDE\x{3042}\x{3044}\x{3046}\x{3048}\x{304a}",
          'hash_str_not_ascii' => "\x{3042}\x{3044}\x{3046}\x{3048}\x{304a}\x{ff11}\x{ff12}\x{ff13}\x{ff14}\x{ff15}"
        };
#### encode_json / decode_json ####
$VAR1 = {
          'hash_str_mix' => "ABCDE\x{3042}\x{3044}\x{3046}\x{3048}\x{304a}",
          'hash_str_not_ascii' => "\x{3042}\x{3044}\x{3046}\x{3048}\x{304a}\x{ff11}\x{ff12}\x{ff13}\x{ff14}\x{ff15}",
          'array_int' => [
                           '01',
                           '2',
                           '3',
                           '4',
                           '5',
                           '6'
                         ],
          'hash_str_ascii' => 'ABCDE12345'
        };
{"hash_str_mix":"ABCDEあいうえお","hash_str_not_ascii":"あいうえお12345","array_int":["01","2","3","4","5","6"],"hash_str_ascii":"ABCDE12345"}
$VAR1 = {
          'hash_str_mix' => "ABCDE\x{3042}\x{3044}\x{3046}\x{3048}\x{304a}",
          'hash_str_not_ascii' => "\x{3042}\x{3044}\x{3046}\x{3048}\x{304a}\x{ff11}\x{ff12}\x{ff13}\x{ff14}\x{ff15}",
          'array_int' => [
                           '01',
                           '2',
                           '3',
                           '4',
                           '5',
                           '6'
                         ],
          'hash_str_ascii' => 'ABCDE12345'
        };
#### OO encode / decode ####
$VAR1 = {
          'hash_str_mix' => "ABCDE\x{3042}\x{3044}\x{3046}\x{3048}\x{304a}",
          'hash_str_not_ascii' => "\x{3042}\x{3044}\x{3046}\x{3048}\x{304a}\x{ff11}\x{ff12}\x{ff13}\x{ff14}\x{ff15}",
          'array_int' => [
                           '01',
                           '2',
                           '3',
                           '4',
                           '5',
                           '6'
                         ],
          'hash_str_ascii' => 'ABCDE12345'
        };
{"hash_str_mix":"ABCDE\u3042\u3044\u3046\u3048\u304a","hash_str_not_ascii":"\u3042\u3044\u3046\u3048\u304a\uff11\uff12\uff13\uff14\uff15","array_int":["01","2","3","4","5","6"],"hash_str_ascii":"ABCDE12345"}
$VAR1 = {
          'hash_str_mix' => "ABCDE\x{3042}\x{3044}\x{3046}\x{3048}\x{304a}",
          'hash_str_not_ascii' => "\x{3042}\x{3044}\x{3046}\x{3048}\x{304a}\x{ff11}\x{ff12}\x{ff13}\x{ff14}\x{ff15}",
          'array_int' => [
                           '01',
                           '2',
                           '3',
                           '4',
                           '5',
                           '6'
                         ],
          'hash_str_ascii' => 'ABCDE12345'
        };
$

Encoding mail subject to MIME-Header by Encode.pm for perl

Standard

use Encode::encode(‘MIME-Header-ISO_2022_JP’, …)
or
use Encode::encode(‘MIME-Header’, …)

#!/usr/local/bin/perl
use strict;
use utf8;
use Encode;
use Data::Dumper;

main();

sub main {
    my $str_org =
        "これはテストです。これはテストです。\nこれはテストです。";
    encode_decode_mime('MIME-Header-ISO_2022_JP',$str_org);
    encode_decode_mime('MIME-Header',$str_org);
}

sub encode_decode_mime {
    my ($encoding, $str_org) = @_;

    my $str_enc = Encode::encode($encoding, $str_org);
    my $str_dec = Encode::decode($encoding, $str_org);


    print "#### $encoding ####\n";
    print "ORIGINAL->", encode('utf8',$str_org),"\n";
    print "ENCODED-> $str_enc\n";
    print encode('utf8',"DECODED-> $str_dec\n\n");

}

↓RESULT

$ ./foo.pl 
#### MIME-Header-ISO_2022_JP ####
ORIGINAL->これはテストです。これはテストです。
これはテストです。
ENCODED-> =?ISO-2022-JP?B?GyRCJDMkbCRPJUYlOSVIJEckOSEjJDMkbCRPJUYlOSVIJEckOSEjGyhC?=
 =?ISO-2022-JP?B?IBskQiQzJGwkTyVGJTklSCRHJDkhIxsoQg==?=
DECODED-> これはテストです。これはテストです。
これはテストです。
#### MIME-Header ####
ORIGINAL->これはテストです。これはテストです。
これはテストです。
ENCODED-> =?UTF-8?B?44GT44KM44Gv44OG44K544OI44Gn44GZ44CC44GT44KM44Gv44OG44K544OI?=
 =?UTF-8?B?44Gn44GZ44CC?=
=?UTF-8?B?44GT44KM44Gv44OG44K544OI44Gn44GZ44CC?=
DECODED-> これはテストです。これはテストです。
これはテストです。