bbz

perl

_
previous | next
101: Wed Oct 26 00:47:05 2011
でもあれか、natしてたりしたらIPアドレスで管理したら全部同じになっちゃうな。

セッションIDというのはHTTPプロトコルの仕組みで、それをサーバとクライアント(ブラウザ)で保持するようだ。

だが、キャプチャしても"session id"みたいなフィールドが見つからない。
102: Wed Oct 26 02:02:20 2011
セッション管理というのは、ステートレスであるHTTPプロトコルで状態管理をさせるための苦肉の策のようだ。
セッションIDを生成して、それをクッキーを使ってクライアントに渡す。
103: Wed Oct 26 02:07:44 2011

#!/usr/bin/perl

use CGI;
use CGI::Session;

my $cgi = CGI->new;
my $session = CGI::Session->new(undef, $cgi, {Directory=>'./tmp'});
session->param('name','mysession');

print $session->header(-charset=>'UTF-8');

print $cgi->start_html(-lang=>'ja', -encoding=>'UTF-8', -title=>'http session test'),
$cgi->p('session id: '.$session->id.'
',
'name: '.$session->param('name').'
'),
$cgi->end_html;



とりあえずこのようなcgiを作って実行すると、session idが表示される。
F5を押すたびにidは変わる。

キャプチャしてみると


Set-Cookie: CGISESSID=5d6b6c1c3248aa9b399060dcef4c4e58; path=/

のように、セッションIDがサーバからクライアントに返す HTTP OKのパケットの中に入っているのがわかる。


・・・・・・で?
104: Wed Oct 26 03:07:40 2011
まずはcookieからだな。

cookieというのは、サーバ側から送信するもので、ユーザが閲覧するとユーザがcookieを無効にしていない限り勝手に保存される。

cookieには名前、値、ドメイン名、パスなどが設定できる。

ユーザが保存しているcookieは、環境変数
$ENV{'HTTP_COOKIE'}
で取得できる。

たとえば名前=アクセス日時というcookieを送信しておけば、次のアクセス時に「前回のアクセスはxxでした」などと表示できる。



105: Wed Oct 26 03:13:43 2011
amazon.co.jpにアクセスしたら、6個のcookieが保存された。

at-acbjp
session-id
session-id-time
session-token
ubid-acbjp
x-acbjp

値を見てもなんのことやらさっぱりわからないが、
サインインしたときにアカウントと関連付けて保存しておけば、どのアカウントかわかる。

どのサイトでも「ログインしたままにする」などのチェックボックスがついているが、
それをチェックしたときはcookieを見てアカウントの認証プロセスを飛ばすのだろう。
106: Wed Oct 26 03:15:24 2011
と、こう見てくるとperlの CGI::Session モジュールがやってることはたいしたことがないように思えてきた。
ただidを発行してcookieにセットしてるだけじゃないのか?

107: Fri Oct 28 01:46:57 2011
画像アップローダーを作ろう。

そういうサイトはたくさんあるけど、なかなか私の使いたいものがない。

以前使っていたサイトがあって、それがとてもよかった。

まず、画像はすべてサムネイルが表示される。

サムネイルといっても、結構大きめで、それで十分楽しめるくらいの大きさである。
PCの1画面で、3、4列くらいかな。

背景は黒。各画像の下には短いコメントが表示される。
多くの場合は何もないか、ごく短い。
投稿者だけでなく閲覧者もコメントをつけられるが、そのコメントはサムネイル表示時には表示されない。

108: Fri Oct 28 01:48:48 2011
画像の表示はglobでいいかな。
まずglobで画像を表示させてみると、大きさがまちまちになる。
これをプレビュー画面では同じ大きさに統一したい。

Windowsのexplorerとかpicasaとかのように。

さて、どうやるか。
ちょっと調べるといろいろ出てくる。

いつもはとりあえずなんでもいいから動くものに食いついてきたけど、
今回はどんな方法があるのかを調べて吟味してから使おう。
109: Fri Oct 28 04:56:36 2011
Image::Magick
GD
ImgResize


110: Fri Oct 28 18:33:38 2011
画像のサムネイルを作成する。


#!/usr/bin/perl
use strict;
use Image::Magick;

print "Content-type: text/html\n";
print "\n";

my @files = glob "./images/*.png ./images/*.jpg";

foreach (@files){
&MakeThumbnails($_);
}

print '';

my @files = glob "./thumbnails/*.png ./thumbnails/*.jpg";

my $count =0;

foreach (@files){
if($count % 5 <1){
print "";
}

$count++;
}

print '
';

sub MakeThumbnails{
my ($name) = @_;
my $dir = './thumbnails';
(my $newname = $name) =~ s/\/images/\/thumbnails/;

my $img = Image::Magick->new;
my $x;
$x = $img->Read($name);
$x = $img->Resize(geometry=>"200x150");
$x = $img->Write($newname);
}

111: Fri Oct 28 18:35:46 2011
サムネイルの作成と表示を同時に実施している。
表示(リロード)するたびにサムネイルを上書きするのはムダかもしれない。
枚数が増えてくると重くなるから、ページを分けたりする必要もあるだろう。
サムネイルをクリックしたら元画像を表示するとか、コメントをつけたり削除したりできれば、
表示部分はOK。

あとは、アップロード部分か。
112: Thu Nov 3 20:17:22 2011
google検索文字列のエンコードが、下記のように%のあとが4桁になっている場合がある。
これをそのままデコードすると、25だけが取れる。
読めるようにするにはこれをもう一度でコードしなければならない。

%25E5%25A4%25A7%25E6%25B1%259F%25E6%2588%25B8%25E7%25B7...

検索すると、%25がついている場合は25を消す、という人がいたので私もマネした。


$string =~ s/%25([a-fA-F0-9][a-fA-F0-9])/%$1/g;


[]を2回繰り返す時の書き方がわからないので続けて書いた。
113: Wed Nov 9 03:16:52 2011
またスタイルの話であるが、このスレのようにpreを使っていると、iphoneで表示が崩れる。
preにはソースを書くので1行の文字数がどうしても長くなる。
するとなぜかほかの部分の文字が大きくなってしまう。
preの幅にあわせて小さくなるならわかるのだが・・・
どうしよう・・・
114: Sun Nov 13 04:33:04 2011
javascriptがアツい。
javascriptのコンパクトな画像ビューアがあったので、
cgiの中に入れることにした。
ヒアドキュメントを使ったら、文字化けしている。

それは、変数展開によるものであった。

print <<"END_OF_TXT";

apple
banana
$test

END_OF_TXT

とやると、$testが変数展開されてしまう。

それをさせないようにするには、

print <<'END_OF_TXT';

とすればよい。
115: Sun Nov 13 04:33:34 2011
ちなみにそのjavascriptによるビューアは動きが重かったので不採用。
116: Sun Nov 13 06:47:59 2011
ファイルの拡張子を取り出そうと調べたら、以下のようなソースがあった。

$name = "aaa.jpg";

if( index($name, '.', 0) != -1){
$suffix = (split(/\./, $name))[-1];
}

print $suffix."\n";


なるほどね、ピリオドで区切ってsplitすればいいのか・・・
と思ったがsplitしたものの取り出し方がちょっと変わっている。
私だったら、

@tmp = split /\./, $name;
$suffix = pop(@tmp);

とやるところだ。
おそらくそれを一発でできるのだろうが、どういうことなのかよくわからない。
[-1]で配列の最後を意味するのかな?
117: Tue Nov 15 03:58:08 2011
アクセスログにデコードされていない文字列が。UAを見ると、ezschとあった。
解析スクリプトの検索エンジンごとの処理にezschを追加する。
が、デコード結果が化ける。文字コードが違うのだろう・・・。
なんの文字コードなのかが判断できないので検索するとshift-jisらしい。
uri_unescapeの前にshiftjisでdecodeする。まだダメだ。
後か。
uri_unescapeした文字列をもう一回shiftjisでデコード。
できた。
118: Tue Nov 15 04:22:54 2011
しかし、やっていることはほとんど同じで、サーチエンジンによる違いというのは
・UAに含まれる検索エンジン名
・検索文字列の前につく文字列(p= とか、 q= とか)
・uri_unescapeの後にさらにデコードが必要な場合それをやる

なので、本当はこれらを引数にしてサブルーチン化すればよいのである。
119: Thu Dec 1 05:05:29 2011
検索エンジン経由で来たアクセスについては、検索後を即時ツイートするようにしているのだが、EZから来たものだけツイートされない。
それは、ツイートするまえにしていた以下の処理が原因だった。

$unescaped = Encode::decode('utf8', $unescaped);

無条件にutf8でデコードしていたのだがEZはshiftjisを使っている。
というわけでEZのときだけshiftjisでデコードし、それ以外はutf8でデコードするようにした。
120: Thu Dec 1 05:13:28 2011
ちなみにUAによる動作を確認するには以下のようなスクリプトを使う。

use LWP::UserAgent;
use strict;
use warnings;

my $url = "http://clebriz.net/cgi-bin/test.cgi";
my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new(GET => "$url");
$req->referer("http://ezsch.ezweb.ne.jp/search/?sr=0101&query=aiueo%20%95a%93I");
my $res = $ua->request($req);
if($res->is_success){
print $res->content;
}else{
print $res->status_line;
}

bing, yahoo, googleはブラウザから検索すればいいのだがauの携帯がないのでEZの場合はこれを使った。

そこで気付いたのだがezschのquery文字列は短い。これがshiftjisのメリットか。
121: Thu Dec 1 05:15:04 2011
$req->referer に設定しているのは、実際にアクセスがあったログのHTTP_REFERERである。
122: Sat Dec 3 06:56:50 2011
perlを使ってルータの設定をするのはよくやっていたが、全部telnetで、シリアルポートを使ったことがないのに気付いた。

Win32::SerialPort

を使う。

ppm install Win32::SerialPort

をやって、

以下、サンプル。


use strict;
use Win32::SerialPort;

my $ob = new Win32::SerialPort('COM1') || die;

$ob->user_msg(1);
$ob->error_msg(1);

$ob->baudrate(9600);
$ob->parity("none");
$ob->parity_enable(1);
$ob->databits(8);
$ob->stopbits(1);
$ob->handshake('rts');

$ob->write_settings;

$ob->write("\n");
sleep 1;
my $result = $ob->input;
print $result;


$ob->write("en\n");
sleep 1;
my $result = $ob->input;
print $result;

$ob->write("enable\n");
sleep 1;
my $result = $ob->input;
print $result;


$ob->write("conf t\n");
sleep 1;
my $result = $ob->input;

print $result;

$ob->write("hostname donguri\n");
sleep 1;
$result = $ob->input;
print $result;

$ob->write("end\n");
sleep 1;
$result = $ob->input;
print $result;

$ob->write("reset\n");
sleep 1;
$result = $ob->input;
print $result;

$ob->write("y\n");

undef $ob;

123: Sat Dec 3 06:58:14 2011
sleepして結果を表示しているところはダサいですね。
ここはteratermの waitのようにしたいところですが、そのやり方は後で調べる。
とりあえずserialポートで入出力ができるというサンプルです。
124: Sat Dec 3 07:55:30 2011
プロンプト待ちバージョン。


use strict;
use Win32::SerialPort;
use Time::HiRes;

my $ob = new Win32::SerialPort('COM1') || die;

$ob->user_msg(1);
$ob->error_msg(1);

$ob->baudrate(9600);
$ob->parity("none");
$ob->parity_enable(1);
$ob->databits(8);
$ob->stopbits(1);
$ob->handshake('rts');

$ob->write_settings;

$ob->are_match('>','#','word:');
$ob->lookclear;

&waitfor("\n",">");

&waitfor("en\n","word:");

&waitfor("enable\n","#");

&waitfor("conf t\n","#");

&waitfor("hostname otanko\n","#");

&waitfor("end\n","#");

&waitfor("reset\n",'(y/n)');

$ob->write("y\n");

undef $ob;

sub waitfor{
my($output_string,$prompt_to_wait)=@_;
my $gotit = "";

$ob->are_match($prompt_to_wait);
$ob->write($output_string);

until ("" ne $gotit) {
$gotit = $ob->lookfor;
die "aborted\n" unless (defined $gotit);
sleep 0.1;
}

my ($match, $after) = $ob->lastlook;
printf "%s%s",$gotit,$match;

}
125: Sat Dec 3 08:00:36 2011
$ob->are_match("hoge1", "hoge2", ...)

という風にして、特定の文字列を待つことができる。複数指定できる。

waitfor というサブルーチンを作って、入力するコマンドと、期待するプロンプトを指定して実行する。

$ob->lookfor で、are_matchで指定した文字列が来るのを待つ。

sleepは1秒未満で待ちたいので Time::HiRes を使う。

$ob->lastlook で、マッチした文字列を取得できる。
この例では are_matchを1個しかしていないので確認する必要はないが、
複数していした場合はどの文字列にマッチしたのかを知ることができる。

これでだいぶ使えるでしょう。

あとは、期待したプロンプトが帰ってこなかったときにタイムアウトするようにすれば完璧。
126: Fri Feb 3 20:17:15 2012
portfastを設定したポートにスイッチをつないでループが発生する状況を作ろうと思ったが、どうしてもできない。
ループが発生するのは2つのスイッチで両方spanning treeを無効にした場合だけである。
2つのスイッチのvlan 10に所属する二つのポートをそれぞれportfastに設定して2本のケーブルでつないだら、
全部FWDになってループが発生すると思ったのだが、ちゃんと一個がBLKになる。どうしてだろう・・・?
127: Thu Jan 31 09:07:04 2013
最近はどんなサイトもユーザーIDとパスワードを登録させて各ユーザごとにカスタマイズしたサイトを利用できるようにしている。私もそれをやってみたいとは思っているのだが、この仕組み時代には以前から不満を持っている。それは、自分のID/パスワードがどんどん増えてしまうことである。また、自分のIDとパスワードを決めることがメンドクサくて、忘れてしまう。
128: Tue Oct 28 05:15:38 2014
test
129: Tue Oct 28 06:10:36 2014
このスレッドではPREタグを有効にしている。

有効にしているといっても、PREタグがあったらそれ用の処置をしているわけだが、

それがうまくいってない。

なんか、img srcタグが悪さをして、apacheにerror_logを書いている。

とりあえずその部分は消した。


自分で書いたものだが、なんだかわけがわからない。

130: Tue Oct 28 06:14:05 2014
test

あれ

声が

遅れて

聞こえるよ
^
previous | next