tohokuaikiのチラシの裏

技術的ネタとか。

今更ながらクロスドメインのAjaxをする場合

1分でわかるようにメモ。

Ajaxを送る側(http://send.example.com/send_ajax.html

<html>
<head>
<script
  src="https://code.jquery.com/jquery-1.12.4.min.js"
  integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ="
  crossorigin="anonymous"></script>
  <script>
$(function(){
    $('#b').on('click', function(e){
        $.ajax({
          url: 'http://receive.example.com/catch.php',
          xhrFields: {
            withCredentials: true
          },          
          cache: false,
          data: {
              foo: 'var'
          }
        }).success(function(data, status, xhr){
            $('#foo').html(data);
        }).error(function(xhr, status, data){
            console.log("error"); 
        })
    });
});
  </script>
</head>
<body>
  <div id="foo">foo</div>
  <button id="b">click</button>
</body>
</html>

f:id:tohokuaiki:20181130154434p:plain

Ajaxを受信する側(https://receive.example.com/catch.php

<?php
session_start();
header("Access-Control-Allow-Credentials: true");
header('Access-Control-Allow-Origin: http://send.example.com');
$_SESSION['counter'] += 1;
?>
Hello 
<?php
printf('<b>%d</b>times %s', $_SESSION['counter'], time());
?>

これで、先ほどボタンをクリックすると

f:id:tohokuaiki:20181130154702p:plain

となる。送り側の、xhrFields と受け側の header("Access-Control-Allow-Credentials: true"); はCOOKIEを使わないなら不要。

PHPでアクセスしてきたIPアドレスがプライベートアドレスかをチェックする

プライベートIPは以下の範囲で

10.0.0.0~10.255.255.255
172.16.0.0~172.31.255.255
192.168.0.0~192.168.255.255

PHPip2longをかませると

167772160~184549375
2886729728~2887778303
3232235520~3232301055

なので、こんな感じで。

<?php
function isPrivateAddress($ip = null)
{
    is_null($ip) and $ip = $_SERVER['REMOTE_ADDR'];
    
    $iplong = ip2long($ip);
    $iplong = sprintf('%u', $iplong); // for 32bit architecture
    
    return ($iplong >= 167772160 && $iplong <=184549375) ||
           ($iplong >= 2886729728 && $iplong <=2887778303) ||
           ($iplong >= 3232235520 && $iplong <=3232301055) ;
}

テスト

<?php
$testips=<<<EOF
10.0.0.0
10.0.0.1
10.0.1.1
10.255.255.254
10.255.255.255
11.0.0.1
172.15.234.1
172.16.0.0
172.16.0.1
172.31.255.254
172.31.255.255
172.32.0.1
191.255.255.255
192.168.0.0
192.168.0.1
192.168.255.254
192.168.255.255
193.0.0.1
EOF;

foreach (explode("\n", $testips) as $ip){
    $ip = trim($ip);
    $long = ip2long($ip);
    printf("%s\t(%u)\t=>\t%s\n",
           $ip, $long,
           isPrivateAddress($ip) ? 'private' : 'global');
}

10.0.0.0        (167772160)     =>      private
10.0.0.1        (167772161)     =>      private
10.0.1.1        (167772417)     =>      private
10.255.255.254  (184549374)     =>      private
10.255.255.255  (184549375)     =>      private
11.0.0.1        (184549377)     =>      global
172.15.234.1    (2886724097)    =>      global
172.16.0.0      (2886729728)    =>      private
172.16.0.1      (2886729729)    =>      private
172.31.255.254  (2887778302)    =>      private
172.31.255.255  (2887778303)    =>      private
172.32.0.1      (2887778305)    =>      global
191.255.255.255 (3221225471)    =>      global
192.168.0.0     (3232235520)    =>      private
192.168.0.1     (3232235521)    =>      private
192.168.255.254 (3232301054)    =>      private
192.168.255.255 (3232301055)    =>      private
193.0.0.1       (3238002689)    =>      global

VirtualBoxに共有フォルダを作成する方法のメモ

普通だったらこんな事せずに、Sambaで終わらせるんだけどこのパソコンは後で別の所に持っていくのでIPアドレスとかなんだりかんだりが変わる可能性があるのでVirtualBoxの共有フォルダ機能を使用した。

ホストOSはWindows10Home、ゲストOSはDebian8(jessie)

仮想マシンにGuest Additionsをインストール

この記事を参考にした。 qiita.com

マシンに仮想ディスクを挿入

自分の場合、起動させたゲストOSのコンソールからデバイス光学ドライブ>ディスクイメージを選択で、C:\Program Files\Oracle\VirtualBox\VBoxGuestAdditions.iso を選択した。

f:id:tohokuaiki:20181112122236p:plain

ゲストOSでインストールスクリプトを実行

…の前にこのインストールスクリプトはmake, gcc, kernel-packageが必要なので

apt-get install -y gcc make kernel-package

をしてから

mkdir -p /mnt/cdrom
mount -r /dev/cdrom /mnt/cdrom
sh /mnt/cdrom/VBoxLinuxAdditions.run

としても、なんかエラーで引っかかる…

# sh /mnt/cdrom/VBoxLinuxAdditions.run
Verifying archive integrity... All good.
Uncompressing VirtualBox 5.2.20 Guest Additions for Linux........
VirtualBox Guest Additions installer
Removing installed version 5.2.20 of VirtualBox Guest Additions...
Copying additional installer modules ...
Installing additional modules ...
VirtualBox Guest Additions: Building the VirtualBox Guest Additions kernel modules.  This may take a while.

This system is currently not set up to build kernel modules.
Please install the Linux kernel "header" files matching the current kernel
for adding new hardware support to the system.
The distribution packages containing the headers are probably:
    linux-headers-686-pae linux-headers-3.16.0-6-686-pae
update-initramfs: Generating /boot/initrd.img-3.16.0-6-686-pae
VirtualBox Guest Additions: Starting.
VirtualBox Guest Additions: Building the VirtualBox Guest Additions kernel modules.  This may take a while.

This system is currently not set up to build kernel modules.
Please install the Linux kernel "header" files matching the current kernel
for adding new hardware support to the system.
The distribution packages containing the headers are probably:
    linux-headers-686-pae linux-headers-3.16.0-6-686-pae
update-initramfs: Generating /boot/initrd.img-3.16.0-6-686-pae

linux-headersが必要な様子。apt-cache search linux-headersをするとlinux-headers-686-paeとlinux-headers-3.16.0-6-686-paeってのがあったので、これを入れておけばいいのかな?

apt-get install -y linux-headers-686-pae linux-headers-3.16.0-6-686-pae

としてから sh /mnt/cdrom/VBoxLinuxAdditions.run をするとどうやらうまく進行してくれた。

共有フォルダをVirtualBoxで作成

ゲストOSをシャットダウンしてからVirtualBoxで共有フォルダを設定

f:id:tohokuaiki:20181112122829p:plain

ゲスト側での共有設定

mount -t vboxsf share_folder_name /home/user/sample

で、毎回起動時にマウントするように /etc/rc.local に記載しておく。

これをやらなくても、VirtualBoxで設定しただけで自動的にマウントするようになった。

→ 以下の問題を解決するためにはVirtualBoxから自動起動ではなく、ゲストOSからの自動起動が必要になってしまう。

が、作成されるファイル・フォルダに問題が…

ホストからでもゲストからでもファイル・フォルダを作成すると、オーナーがrootでグループがvboxsfになり、パーミッションが770になってしまう。 あまりうれしくない。

gpasswd -a XXXXXX vboxsf

してやると、ゲストOS側で使用するユーザーXXXXXXもこの共有ファイルを触れるけど、ん~~~。イマイチ。だいたいApacheでこのファイルを覗けないというのはどうなんだろうという気もするし、いや、apacheユーザーをvboxsfに入れればいいじゃんって思うけど、さすがにapacheの作成するファイルがrootオーナーってどうなんだろうという。

しかも、フォルダの位置がゲストOSから見ると、/media/sf_{VirtualBoxで設定した共有フォルダ名} となる。うーん、sambaみたいにできないものだろうか…

ということで、この記事を見ながら編集。 giraffydev.hatenablog.com

-oオプションで、マウントするオーナーとグループの設定

自分のuid,gidを知る。

id xXXXXX
uid=1000(XXXXXX) gid=1000(XXXXXX)

とあるので、両方とも1000なので、

-o uid=1000,gid=1000 

とする。

-oオプションで、マウントする時のファイルとディレクトリのデフォルトモードを設定

-o fmode=0664,dmode=0755

で結局のマウントコマンドは

mount -t vboxsf share_folder_name /home/user/sample -o uid=1000,gid=1000,fmode=0664,dmode=0755

となる。

地味にアンマウントができなくて汗る。

-t オプションと -i オプションが必要らしい。 qiita.com

sudo umount -t vboxsf -i /home/user/sample

とする。

自動設定

VirtualBoxで設定した自動起動だとこういうところは上手くやってくれない。

/etc/rc.localにさっきのマウントコマンドを記載してもいいけど、なんとなく/etc/fstabに記載したくなった。

デバイス名(share_folder_name)        マウントポイント(/home/users/sample)       vboxsf  uid=1000,gid=1000,fmode=0664,dmode=0755    0    0

/etc/modulesにvboxsfを食わないと起動時にミスするっていう記載があったけど、なんか問題なくいった。新しいOSで対応されたのかもしれない。 VirtualBoxの共有フォルダの自動マウント化 - どうでもいい日記帳

PHPのoutput bufferingの罠

別のサーバーだとheaderの前にエラーが出て「Message: Cannot modify header information - headers already sent by」になって終わっちゃうのに、自分のサーバーだとこれが引っかからなくて不思議だなーって思ってたら

f:id:tohokuaiki:20181107164605p:plain
output.bufferingの値が設定されていた。なんぞこれ。

PHP: 実行時設定 - Manual

output_buffering boolean/integer このディレクティブを 'On' と設定することにより、全てのファイルに 関して出力バッファリングを有効にすることができます。 特定の大きさにバッファの大きさを制限したい場合、このディレクティブの 値として 'On' の代わりに最大バイト数(例:output_buffering=4096) を使用することができます。 PHP-CLI ではこのディレクティブが常に Off となります。

ということ。試しに、var_dump(ob_get_status());exit; してみたら

array(7) {
  ["name"]=>
  string(22) "default output handler"
  ["type"]=>
  int(0)
  ["flags"]=>
  int(20592)
  ["level"]=>
  int(0)
  ["chunk_size"]=>
  int(4096)
  ["buffer_size"]=>
  int(69632)
  ["buffer_used"]=>
  int(0)
}

って出てきた。なー。デフォルトでob_start()してたってことなのね。

.htaccess

php_value output_buffering 0

として対策完了。

10年くらいぶりにPerlのCPANモジュールをインストールしようとしたら全然覚えてなくて焦った。

MT6を使おうとして

Perlすっかり忘れてる。mt-check.cgiにアクセスしたらいっぱいオプションで必要なのが出てきた。

CPANをインストール

# yum install perl-CPAN

CPANプロンプトを起動する

# perl -MCPAN -e shell

最初はなんか言われるけど、のきなみエンターキーをたたく。

CPANモジュールのインストール

cpan[1]> install Net::SSLeay

スペース区切りで複数を一度にインストールいけるかと思いきやダメだった。

複数行くときは、

# perl -MCPAN -e 'CPAN::Shell->install("XML::LibXML::SAX")'
# perl -MCPAN -e 'CPAN::Shell->install("Authen::SASL")'

みたいにやる。

モジュールのインストールの有無を確認

一覧で出てきてほしいなーと思いつつ、インストール済みのCPANモジュールを調べる | bacchi.me そういうのは無いみたいなので。

# perl -Mモジュール名 -e \'\'

で何も出てこなければインストールされている。エラーメッセージがでたらインストールされてない。という方法。

Archive::Zipとかインストールでコケル。メンテナンスされてないんだろうか。

とりあえず、MT6で出てきたのを

perl -MCPAN -e 'CPAN::Shell->install("CGI::Cookie")'
perl -MCPAN -e 'CPAN::Shell->install("Scalar::Util")'
perl -MCPAN -e 'CPAN::Shell->install("LWP::UserAgent")'
perl -MCPAN -e 'CPAN::Shell->install("File::Spec")'
perl -MCPAN -e 'CPAN::Shell->install("Image::Size")'
perl -MCPAN -e 'CPAN::Shell->install("CGI")'
perl -MCPAN -e 'CPAN::Shell->install("DBI")'
perl -MCPAN -e 'CPAN::Shell->install("DBD::mysql")'
perl -MCPAN -e 'CPAN::Shell->install("DBD::SQLite")'
perl -MCPAN -e 'CPAN::Shell->install("DBD::Pg")'
perl -MCPAN -e 'CPAN::Shell->install("DBD::SQLite2")'
perl -MCPAN -e 'CPAN::Shell->install("Net::SSLeay")'
perl -MCPAN -e 'CPAN::Shell->install("IPC::Run")'
perl -MCPAN -e 'CPAN::Shell->install("Archive::Zip")'
perl -MCPAN -e 'CPAN::Shell->install("Net::SMTP::TLS")'
perl -MCPAN -e 'CPAN::Shell->install("XML::LibXML::SAX")'
perl -MCPAN -e 'CPAN::Shell->install("Authen::SASL")'
perl -MCPAN -e 'CPAN::Shell->install("Storable")'
perl -MCPAN -e 'CPAN::Shell->install("List::Util")'
perl -MCPAN -e 'CPAN::Shell->install("CGI::PSGI")'
perl -MCPAN -e 'CPAN::Shell->install("Cache::Memcached")'
perl -MCPAN -e 'CPAN::Shell->install("Digest::SHA")'
perl -MCPAN -e 'CPAN::Shell->install("Cache::File")'
perl -MCPAN -e 'CPAN::Shell->install("Crypt::SSLeay")'
perl -MCPAN -e 'CPAN::Shell->install("GD")'
perl -MCPAN -e 'CPAN::Shell->install("Archive::Tar")'
perl -MCPAN -e 'CPAN::Shell->install("Safe")'
perl -MCPAN -e 'CPAN::Shell->install("XML::SAX::Expat")'
perl -MCPAN -e 'CPAN::Shell->install("CGI::Parse::PSGI")'
perl -MCPAN -e 'CPAN::Shell->install("Image::Magick")'
perl -MCPAN -e 'CPAN::Shell->install("File::Temp")'
perl -MCPAN -e 'CPAN::Shell->install("HTML::Parser")'
perl -MCPAN -e 'CPAN::Shell->install("Crypt::DSA")'
perl -MCPAN -e 'CPAN::Shell->install("XML::SAX")'
perl -MCPAN -e 'CPAN::Shell->install("SOAP::Lite")'
perl -MCPAN -e 'CPAN::Shell->install("Text::Balanced")'
perl -MCPAN -e 'CPAN::Shell->install("Digest::MD5")'
perl -MCPAN -e 'CPAN::Shell->install("HTML::Entities")'
perl -MCPAN -e 'CPAN::Shell->install("XML::Parser")'
perl -MCPAN -e 'CPAN::Shell->install("IO::Socket::SSL")'
perl -MCPAN -e 'CPAN::Shell->install("IO::Uncompress::Gunzip")'
perl -MCPAN -e 'CPAN::Shell->install("Digest::SHA1")'
perl -MCPAN -e 'CPAN::Shell->install("Plack")'
perl -MCPAN -e 'CPAN::Shell->install("IO::Compress::Gzip")'
perl -MCPAN -e 'CPAN::Shell->install("Imager")'
perl -MCPAN -e 'CPAN::Shell->install("XML::Atom")'
perl -MCPAN -e 'CPAN::Shell->install("Time::HiRes")'
perl -MCPAN -e 'CPAN::Shell->install("YAML::Syck")'
perl -MCPAN -e 'CPAN::Shell->install("Net::SMTP")'
perl -MCPAN -e 'CPAN::Shell->install("Mozilla::CA")'
perl -MCPAN -e 'CPAN::Shell->install("MIME::Base64")'
perl -MCPAN -e 'CPAN::Shell->install("XMLRPC::Transport::HTTP::Plack")'
perl -MCPAN -e 'CPAN::Shell->install("Net::SMTP::SSL")'
perl -MCPAN -e 'CPAN::Shell->install("XML::SAX::ExpatXS")'

この中でいくつかインストール失敗するのがあって、もうオプショナルだしあきらめようかなと思ったんだけど、以下にあるのは普通にyumで転がってたので

# yum install -y perl-Archive-Zip perl-XML-SAX perl-Crypt-SSLeay perl-GD perl-XML-Parser 

で行けた。いくつかモジュールがO.Kになってた。うーん歴史を感じる。