火曜日, 9月 30, 2014

Tomcat8.0でシンボリックリンクを有効にする

$CATALINA_HOME/conf/context.xml の <Context> のすぐ後に

<Resources className="org.apache.catalina.webresources.StandardRoot" allowLinking="true"/>

を追記する。
バージョン8.0からこうなったみたい。

Tomcat8.0のRequestDumperFilterでServletの文字化け解消

$CATALINA_HOME/webapps/アプリ名/WEB-INF/web.xml の先頭部分につぎのように<filter>を追記する。

------------------------------------------------------------------------------
<web-app>

  <filter>
    <filter-name>requestdumper</filter-name>
    <filter-class>
      org.apache.catalina.filters.RequestDumperFilter
    </filter-class>
  </filter>
  <filter-mapping>
    <filter-name>requestdumper</filter-name>
    <url-pattern>/target_path/*</url-pattern>
  </filter-mapping>

(以下省略)
------------------------------------------------------------------------------

$CATALINA_HOME/conf/logging.properties を編集。

handlers = 1catalina.org.apache.juli.AsyncFileHandler, 2localhost.org.apache.juli.AsyncFileHandler, 3manager.org.apache.juli.AsyncFileHandler, 4host-manager.org.apache.juli.AsyncFileHandler, java.util.logging.ConsoleHandler



handlers = 1catalina.org.apache.juli.AsyncFileHandler, 2localhost.org.apache.juli.AsyncFileHandler, 3manager.org.apache.juli.AsyncFileHandler, 4host-manager.org.apache.juli.AsyncFileHandler, 5request-dumper.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler

のように 5request-dumper.org.apache.juli.FileHandler, を追記し、

4host-manager.org.apache.juli.AsyncFileHandler.prefix = host-manager.

の下あたりに

# request dumper configuration
5request-dumper.org.apache.juli.FileHandler.level = INFO
5request-dumper.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
5request-dumper.org.apache.juli.FileHandler.prefix = request-dumper.
5request-dumper.org.apache.juli.FileHandler.formatter = org.apache.juli.VerbatimFormatter
org.apache.catalina.filters.RequestDumperFilter.level = INFO
org.apache.catalina.filters.RequestDumperFilter.handlers = 5request-dumper.org.apache.juli.FileHandler

を追記する。
アプリをデプロイし直し、Tomcatを再起動。
これで

$CATALINA_HOME/logs/



request-dumper.2014-09-30.log

のようなログファイルが生成される。
理由はわからないが、POSTリクエストで送信されたUTF-8の2バイト文字が、それを受け取ったフィルターのurl-patternに含まれるServletで文字化けしなくなった。
ちなみにJavaのソースコードはシフトJIS。

木曜日, 9月 11, 2014

Azureで仮想ネットワーク内仮想マシンのDNS名

仮想マシンOSがWindowsの場合、コマンドプロンプトで


C:\Users\Administrator>ipconfig

Windows IP 構成


イーサネット アダプター Ethernet 21:

   接続固有の DNS サフィックス . . . . .: eldb.m2.internal.cloudapp.net
   リンクローカル IPv6 アドレス. . . . .: fe80::7de3:9900:a6a0:eda1%34
   IPv4 アドレス . . . . . . . . . . . .: 192.168.91.4
   サブネット マスク . . . . . . . . . .: 255.255.255.128
   デフォルト ゲートウェイ . . . . . . .: 192.168.91.1

Tunnel adapter isatap.eldb.m2.internal.cloudapp.net:

   メディアの状態. . . . . . . . . . . .: メディアは接続されていません
   接続固有の DNS サフィックス . . . . .: eldb.m2.internal.cloudapp.net

Tunnel adapter Teredo Tunneling Pseudo-Interface:

   接続固有の DNS サフィックス . . . . .:
   IPv6 アドレス . . . . . . . . . . . .: 2001:0:9d38:6abd:2cf8:151e:3f57:a4fb
   リンクローカル IPv6 アドレス. . . . .: fe80::2cf8:151e:3f57:a4fb%14
   デフォルト ゲートウェイ . . . . . . .: ::

C:\Users\Administrator>


この中の「接続固有の DNS サフィックス . . . . .: eldb.m2.internal.cloudapp.net」を確認。
例えばそのマシンのホスト名が hoge だったら

hoge.eldb.m2.internal.cloudapp.net

がその仮想ネットワーク内で使えるそのマシンのDNS名。
OSがLinuxの場合、


$ cat /etc/resolv.conf
; generated by /sbin/dhclient-script
search elweb.m5.internal.cloudapp.net
nameserver 168.63.129.16
$


この中の「search elweb.m5.internal.cloudapp.net」を確認。
そのマシンのホスト名が hogehoge だったら

hogehoge.elweb.m5.internal.cloudapp.net

がその仮想ネットワーク内で使えるそのマシンのDNS名。

水曜日, 9月 03, 2014

CPU使用率

5秒おきにCPUの平均使用率を表示

(Linuxの場合)
$ mpstat 5

(Windowsの場合)
> typeperf -si 5 "\Processor(_Total)\% Processor Time"

金曜日, 8月 08, 2014

node.jsのインストール (CentOS 6.5 x86_64)

$ sudo rpm -ivh http://ftp.riken.jp/Linux/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm
$ sudo yum install nodejs npm --enablerepo=epel

火曜日, 7月 01, 2014

Bracketsの proxy 設定

メニューバー「デバッグ」の「環境設定ファイルを開く」を選択。
brackets.json が開かれるので

{
    "debug.showErrorsInStatusBar": false
}

につぎのようにproxyの設定を追加し、Bracketsを再起動する。

{
    "debug.showErrorsInStatusBar": false,
    "proxy": "http://172.16.10.11:3128/"
}

以上。

金曜日, 4月 11, 2014

Bootstrap3 のカラースキームを変更する 1pxdeep

(1) http://rriepe.github.io/1pxdeep/

にアクセスする。
「Download」ボタンをクリックしてファイルをダウンロードして展開する。
Seed colorを指定し、「Scheme now」ボタンをクリックして色を確認する。
気に入った色になったら、RGB値をコピーする。

(2) http://getbootstrap.com/getting-started/#download

でSource Codeをダウンロードして展開し、less フォルダに (1) で取得したファイル

scheme.less
1pxdeep.less

を配置する。

1pxdeep.less

を編集し、先頭部分に

@import "bootstrap.less";
@import "scheme.less";

を追記する。

scheme.less

を編集し、先頭部分の

@seed-color:

に (1) でコピーしたRGB値を指定する。

(3) Crunch (http://crunchapp.net/) 等のツールを入手して、(2) の

1pxdeep.less

を .css ファイルにコンパイルし、適宜配置する。

(4) 対象のHTMLファイルを編集し

<link href="css/bootstrap.min.css" rel="stylesheet" />
<link href="css/1pxdeep.css" rel="stylesheet" />

のように Bootstrap の後に (3) で作成したCSSファイルを指定する。

以上。

木曜日, 3月 20, 2014

Bracketsの編集画面のフォントを変える (Windows)

C:\Documents and Settings\ユーザ名\Application Data\Brackets\extensions\user

に例えば code-font というフォルダを作成し、その中に main.js というファイル名で

define(function (require, exports, module) {
  "use strict";
  var ExtensionUtils = brackets.getModule("utils/ExtensionUtils");
  ExtensionUtils.addEmbeddedStyleSheet(".CodeMirror { font-family: 'MS Gothic'; }");
});

を保存する。
フォント名は MS Gothic のところで指定する。
以上。

金曜日, 3月 07, 2014

FreeTDS(Linux -> SQL Server)でSELECTできる文字列長255バイトまで

SELECT CAST(mycol as TEXT) FROM mytable

のようなSELECT文で回避。

水曜日, 6月 26, 2013

OpenLDAPのBerkeley DBファイルを特定の日時の状態に戻す

古いDebianで運用されているOpenLDAPのBerkeley DBに不整合が発生した。
念のためデータベースのディレクトリをコピーし、原因となる操作が行われる前の状態に戻した。

# cd /var/lib
#
# /etc/init.d/slapd stop
#
# cp -R -P ldap ldap.20130613
#
# db4.2_recover -c -v -t 06131100 -h ldap
#
# /etc/init.d/slapd start
#

水曜日, 5月 15, 2013

ffmpegでwmvファイルをmp4に変換 on Linux

$ ffmpeg -i hoge.wmv -b 968k hoge.mp4

このようにコマンドを実行する。

-i: 入力ファイルパス
-b: ビットレート(指定しない場合200k)

変換前の動画のビットレートが200kbpsを超えている場合、それを適切に指定しないと画像が粗くなってしまう。必要以上に大きい値を指定するとファイルサイズが無駄に大きくなってしまう。

ffmpegで動画ファイルからサムネイル画像作成 on Linux

$ ffmpeg -y -i hoge.wmv -f image2 -ss 2 -vframes 1 -s 320x240 hoge.jpg

このようにコマンドを実行する。

-y: 出力先ファイルを上書きする
-i: 入力ファイルパス
-f: 出力フォーマット
-ss: 開始位置(秒)
-vframes: 出力ビデオフレーム数
-s: 表示サイズ(横x縦)

縦横比はもとの動画と同じにしないと画像が歪む。

金曜日, 1月 18, 2013

メールのMIMEマルチパートの文字列をバイナリファイルに変換

メールの添付ファイル部分、例えば

--DC_BOUND_PRE_<1358488463.00267343d988> Content-Type: application/pdf; name="201301181454.pdf" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="201301181454.pdf"

こんな行から

--DC_BOUND_PRE_<1358488463.00267343d988>--

こんな行までを仮にhoge.txtとして保存する。
WindowsならCygwinのコンソールで

perl -MMIME::Base64 -ne 'print decode_base64($_)' < hoge.txt > 201301181454.pdf

を実行する。

水曜日, 11月 07, 2012

Google Chromeの機能

URLバーに chrome://chrome-urls/ を打ち込んでもよいし、Chromeウェブストアの「Service Pages for Google Chrome」を入れてもよし。便利。

金曜日, 5月 11, 2012

MS SQL Server 2008 R2 Expressのインストールでつまづいた

Windows XP SP3 (32bit)での話。
事前に「.NET Framework 4」やら「Windowsインストーラ4.5」やら「Windows PowerShell 1.0」のインストールが必要。
管理ツール -> 「ローカルセキュリティポリシー」 -> 「ローカルポリシー」 -> 「ユーザ権利の割り当て」の「プログラムのデバッグ」に「NETWORK SERVICE」やら「LOCAL SERVICE」やらデータベース管理者を追加した。
また同じく「ローカルセキュリティポリシー」の「サービスとしてログオン」から古いバージョンのSQL Serverのユーザを削除した。
インストールが失敗した場合、再インストールの前に「プログラムの追加と削除」でインストールしたインスタンスを削除する必要あり。
厄介なこった。

(参考)
http://awoni.net/fc/sql-server-2008-express/
http://d.hatena.ne.jp/haradago/20100211/p1

MS SQL Server:他のマシンのバックアップを復元した際のログイン名変更

Management Studioにデータベース管理者で接続し、対象のデータベースに対してつぎのクエリを実行する。

EXEC sp_change_users_login 'Update_One', '変更前ログイン名', '変更後ログイン名'

金曜日, 4月 13, 2012

Android SDKのエミュレータ起動(Proxy経由) on Windows

Android SDKのインストールディレクトリ下の tools にパスが通っている前提。
AVD名が「hoge」として、コマンドプロンプトで

> emulator -avd hoge -http-proxy http://172.16.10.11:3128

のようにタイプする。

木曜日, 4月 12, 2012

IE + SSL + Flash (HTTPレスポンスヘッダーの怪)

Apacheの設定ファイルに

<LocationMatch "/var/www/html/private/.*\.(html|swf|gif|jpg|png)$">
  Header set Pragma no-cache
  Header set Cache-Control no-cache
  Header set Expires "Thu, 01 Dec 1994 16:00:00 GMT"
</LocationMatch>

とか書いて特定のディレクトリのファイルがキャッシュされないようにしている場合
IEでhttps接続するとFlashが再生されないことがある。
原因は

Header set Pragma no-cache

らしい。要注意。

水曜日, 4月 11, 2012

JavaScript: FlashPlayerバージョン確認

var flashPlayerVer = (function() {
  var flashVer = 0,
      plugin,
      verParts,
      flashOCX;
  if (navigator.plugins
      && navigator.mimeTypes['application/x-shockwave-flash']) {
    plugin = navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin;
    if (plugin) {
      verParts = plugin.description.split(" ");
      flashVer = verParts[2].replace('.', ',') + ',' + verParts[3].substring(1);
    }
  }
  else {
    flashOCX = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7").GetVariable("$version");
    if (flashOCX) {
      flashVer = (flashOCX.split(" "))[1];
    }
  }
  return flashVer;
})();

木曜日, 2月 23, 2012

Perl: Linux -> SQLServer 画像ファイル格納

LinuxマシンからWindowsマシンのSQL ServerにはFreeTDSとunixODBCで接続できるようになっている前提。
データベース接続にはDBIとDBD::ODBCを使う。
DBD::Sybaseではプレースホルダーが使えない(?)のでDBD::ODBCしかないが、動きが怪しい。
レコードが存在する場合にupdateしようとしたがうまくいかない。
そこで、レコードが存在する場合deleteしてinsertすることにしたが、これも同一接続内ではうまくいかない。
仕方ないので、select、deleteで一旦切断し、insert用に再度接続するようにした。
以下サンプル。

#!/usr/bin/perl --

use MIME::Parser;
use DBI;
use warnings;
use strict;

my $dbname  = 'hoge';
my $user_id = "";
my $item_id = '10';

my $parser = new MIME::Parser;
$parser->output_to_core(1);
my $entity;

eval {
    local $SIG{ALRM} = sub { die "timeout" };
    alarm 10;
    $entity = $parser->parse(\*STDIN) or die;
    alarm 0;
};
alarm 0;
if ($@) { exit; }

my $from = $entity->head->get('from');
if ($from =~ /<(.+?\@.+?)>/) {
    $from = $1;
}

$user_id = _check_from($dbname, $from);

if ($user_id ne "" and $entity->is_multipart) {
    _save_attached_file($entity, $dbname, $user_id, $item_id);
}

exit;


sub _connect_db($$$$) {
    my $db_host   = shift;
    my $db_name   = shift;
    my $db_user   = shift;
    my $db_passwd = shift;

    my $data_source = "dbi:ODBC:"
                    . "server=" . $db_host . ";"
                    . "database=" . $db_name;
    my $dbh = DBI->connect($data_source, $db_user, $db_passwd)
                  or die $DBI::errstr;
    $dbh->{AutoCommit} = 0;
    $dbh->{RaiseError} = 1;

    return $dbh;
}

sub _check_from($$) {
    my $dbname  = shift;
    my $from    = shift;
    my $user_id = "";

    my $db_server = 'windows-db';
    my $db_name   = $dbname;
    my $db_user   = 'foo';
    my $db_passwd = 'bar';
    my $dbh
        = _connect_db($db_server, $db_name, $db_user, $db_passwd);
    my $stmt = "SELECT user_id"
             . " FROM users WITH (NOLOCK)"
             . " WHERE email = '$from'";
    my $sth = $dbh->prepare($stmt)
              or die $dbh->errstr;
    $sth->execute or die $dbh->errstr;
    while (my $row = $sth->fetchrow_arrayref) {
        ($user_id) = @$row;
    }
    $sth->finish;
    $dbh->disconnect;

    return $user_id;
}

sub _save_attached_file($$$$) {
    my $entity  = shift;
    my $dbname  = shift;
    my $user_id = shift;
    my $item_id = shift;

    my $parts_count = $entity->parts;
    for (my $i = 1; $i < $parts_count; $i++) {
        my $part_entity = $entity->parts($i) ?
                          $entity->parts($i) :
                          $entity->parts($i)->parts($i);
        my $content_type = $part_entity->head->mime_type;

        if ($content_type =~ /\/(html|plain|alternative)/) {
            next;
        }

        my $attachment = $part_entity->bodyhandle->as_string;
        my $filename   = $part_entity->head->recommended_filename;

        my $db_server = 'earth-db';
        my $db_name   = $dbname;
        my $db_user   = 'foo';
        my $db_passwd = 'bar';
        my $dbh
            = _connect_db($db_server, $db_name, $db_user, $db_passwd);
        my $stmt = "SELECT user_id FROM files WITH(NOLOCK)"
                 . " WHERE user_id = '$user_id'"
                 . " AND item_id = '$item_id'";
        my $sth = $dbh->prepare($stmt) or die $dbh->errstr;
        $sth->execute or die $dbh->errstr;
        my $result_user_id = "";
        while (my $row = $sth->fetchrow_arrayref) {
            ($result_user_id) = @$row;
        }
        $sth->finish;
        if ($result_user_id) {
            $stmt = "DELETE FROM files"
              . " WHERE user_id = '$user_id'"
              . " AND item_id = '$item_id'";
            $sth = $dbh->prepare($stmt) or die $dbh->errstr;
            eval {
                $sth->execute;
                $dbh->commit;
            };
            if ($@) {
                $dbh->rollback or die $dbh->errstr;
            }
        }
        $dbh->disconnect;

        $dbh = _connect_db($db_server, $db_name, $db_user, $db_passwd);
        $stmt = "INSERT INTO files ("
              . "user_id,"
              . "item_id,"
              . "content_type,"
              . "content,"
              . "filename,"
              . "date"
              . ") VALUES ("
              . "'$user_id',"
              . "'$item_id',"
              . "'$content_type',"
              . "?,"
              . "'$filename',"
              . "GETDATE()"
              . ")";
        $sth = $dbh->prepare($stmt) or die $dbh->errstr;
        $sth->bind_param( 1, $attachment, DBI::SQL_LONGVARBINARY );
        eval {
            $sth->execute;
            $dbh->commit;
        };
        if ($@) {
            $dbh->rollback or die $dbh->errstr;
        }
        $dbh->disconnect;

        last;
    }
}

__END__