ウィリアムのいたずらの、まちあるき、たべあるき

ウィリアムのいたずらが、街歩き、食べ物、音楽等の個人的見解を主に書くブログです(たま~にコンピューター関係も)

オブジェクト指向で開発の最初から最後までの手順例-その43:雛形(16)。

2008-01-18 13:27:22 | 開発ネタ

一ヶ月ぶりくらいになりますが、オブジェクト指向で開発の最初から最後までの手順例です。

 現在、「いままでのまとめ」にある、「(4)フレームワークにもとづき、クラスなどの開発手順、雛形の確定」をやっています。前回、Viewの概要について説明し、JavaScript(AJAX)で、サーバーにアクセスし、データを取ってくるという説明をしました。そして、今回、その「サーバーにアクセスし、データを取ってくる」共通部分について、説明することになってました。今回はその説明です。




■プログラムの中身

 で、そのサーバーアクセスプログラムなのですが、こんなのを作ります。

●サーバーアクセス
(1)httpRequest(method,target_url,args,func)

<<引数について>>
method:"POST"または"GET"
target_url:アクセスするところ
args:引数を連想配列で
func:帰るときの関数

<<内容>>
 argsで渡された引数をエンコードし、target_urlにアクセスします。
 最終的に、アクセスしてうまくいくとfunc(httpObj)が呼び出されます
(httpObjは、結果のXMLです)

<<注意>>
 func(httpObj)で結果が返ってくるまで、同時に何回も呼びださないで
ください(httpObj、retFuncを外部変数で共通化してとっているので)

●結果処理
(2)getRetCode(xtree)

<<引数>>
xtree:(1)のhttpObjに対して、httpObj.responseXMLしたもの

<<内容>>
結果から、retcode(処理結果)を受け取ります


(3)getRecCount(xtree)

<<引数>>
xtree:(1)のhttpObjに対して、httpObj.responseXMLしたもの

<<内容>>
結果が検索型の場合、レコード数を取得します

(4)getRecItemValue(xtree,pos,tag)

<<引数>>
xtree:(1)のhttpObjに対して、httpObj.responseXMLしたもの
pos:何番目のレコード
tag:項目名のタグ

<<内容>>
結果が検索型の場合、指定番目のレコードの指定項目の値を取得します


これ以外の関数は、内部で使用するものです




■使い方の概要

・サーバーアクセス時にhttpRequest(method,target_url,args,func)でアクセスします
・func(httpObj)に帰ってきたら、編集型でも検索型でもgetRetCodeで結果を受け取り、
  結果に応じた処理をします
・検索型の場合、getRecCountでレコード数を指定し、getRecItemValueでレコードの値を取得します。




■ソース

 ちょっとメモ程度に書いたもので、テストしてないので、動くかどうか保証の限りではないですが、とりあえず載せときます(自己責任で見てね ^^;)

//*==============================================//
//*					   *//
//*	アクセス共通関数			   *//
//*					   *//
//*==============================================//

//	共通変数
var	httpObj;		//	データ
var	timer;			//	タイムアウト用
var	retFunc;		//	戻り関数

//*==============================================//
//*	関数:httpRequest()		  *//
//*	内容:アクセス関数		  	  *//
//*==============================================//
function httpRequest(method,target_url,args,func)
{

	//==============================//
	//	配列をシリアル化	    //
	//==============================//
	buf		=	"";
	flgs		=	"";
	for(key in arr)
	{
		buf = buf + flgs + key + "=" +  encodeURIComponent(args[key]);
		flgs = "&";
	}

	//==============================//
	//	getで読まないこと対策  //
	//==============================//
	if ( ( method == "GET") || ( method == "get" ) )
	{ 
		buf = buf + flgs + "nowtime="+ new Date().getTime();
	}

	//==============================//
	//	帰るところ保存	    //
	//==============================//
	retFunc	=	func;

	//==============================//
	//	XMLHttpRequest取得	    //
	//==============================//
	try
	{
	      	if(window.XMLHttpRequest)
		{
			httpObj = new XMLHttpRequest();
		}
		else if(window.ActiveXObject)
		{
			httpObj = new ActiveXObject("Microsoft.XMLHTTP");
		}
		else
		{
			alert('エラーです');
			return;
		}
	}
	catch(e)
	{
		alert('エラーです');
		return;
	}
	//	タイマーセット
	timer = setInterval("timeout()",60000); //60秒にセット

	//==============================//
	//	データを取得する	//
	//==============================//
	httpObj.open(method, target_url, true);
	httpObj.onreadystatechange = RetEntry;
	httpObj.send(buf);

	return;
}

//*==============================================//
//*	関数:timeout()		  	   *//
//	内容:タイムアウト			   *//
//*==============================================//
function timeout()
{
	clearInterval(timer);
	httpObj.abort();
//	alert('タイムアウト');		// 表示する場合
}

//*==============================================//
//*	関数:RetEntry()		  	   *//
//*	内容:XML読み取ったあと		   *//
//*==============================================//
function RetEntry()
{
        if ( httpObj.readyState == 4 )
	{
		clearInterval(timer);	//	タイマーとめる
		if ( httpObj.status == 200)
		{
			if ( retFunc	!=	null )
			{
				retFunc(httpObj);
			}
		}
		else
		{
			alert("エラーNo "+httpObj.status);
		}
       	}
}

//*==============================================//
//*	関数:getRetCode()			  *//
//*	内容:処理結果の取得		  *//
//*==============================================//
function getRetCode(xtree)
{
	retCode	=	"";

	komoku = node.getElementsByTagName("retcode");
	if ( komoku.length	>	0 )
	{
		retCode  = komoku[0].firstChild.nodeValue;
	}
	
	return	retCode;
}

//*==============================================//
//*	関数:getRecItemValue()		  *//
//*	内容:指定番目のレコードの指定項目の値 *//
//*==============================================//
function getRecItemValue(xtree,pos,tag)
{
	retCode	=	"";

			//	レコードを取得する
	list	=	xtree.getElementsByTagName("item");
	if ( list.length	>	pos )
	{
		node	= 	list[pos];
		komoku = node.getElementsByTagName(tag);
		if ( komoku.length	>	0 )
		{
			retCode  = komoku[0].firstChild.nodeValue;
		}
	}
	
	return	retCode;
}

//*==============================================//
//*	関数:getRecCount()		  *//
//*	内容:レコード数		 	   *//
//*==============================================//
function getRecCount(xtree)
{
			//	レコードを取得する
	list	=	xtree.getElementsByTagName("item");
	return list.length;
}

(上記< > ¥は、本当は半角です)




 次回は、これの利用方法です。




  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

SugarCRMにおける、モジュール間の関連(&カーディナリティ)について

2008-01-18 11:31:03 | SugarCRM

メモメモ(確かめていない)

SugarCRMにおいて、モジュール同士の関係っていうのは、テーブル同様、1対多と多対多がある。
どちらのケースでも、まず、vardef.phpに項目は書かれる。
こんなかんじ
  'modified_user_link' =>
  array (
        'name' => 'modified_user_link',
    'type' => 'link',
    'relationship' => 'cases_modified_user',
    'vname' => 'LBL_MODIFIED_BY_USER',
    'link_type' => 'one',
    'module'=>'Users',
    'bean_name'=>'User',
    'source'=>'non-db',
  ),

(上記 >は、本当は半角)

しかし、このあと、1対多と多対多で違う。




■1対多の場合

そのvardefの中(下のほう)に'relationships'の指定があり、そので、上記の'relationship'で指定された関係が記述されている。上記の場合は、'cases_modified_user'ということになるが、それは、vardefの下のほうの'relationships'の中に以下のように指定されている。

   ,'cases_modified_user' =>
   array('lhs_module'=> 'Users', 'lhs_table'=> 'users', 'lhs_key' => 'id',
   'rhs_module'=> 'Cases', 'rhs_table'=> 'cases', 'rhs_key' => 'modified_user_id',
   'relationship_type'=>'one-to-many')

(上記 >は、本当は半角)

ちなみに、vardefは、項目の内容、indicesで示されるインデックス、'relationships'で示される1対多の関係が記述されている。




■多対多の場合

 一方、多対多の場合は、metadataに作られる。たとえば、cases_bugsにおいて、vardef.phpでは、

  'bugs' =>
  array (
  	'name' => 'bugs',
    'type' => 'link',
    'relationship' => 'cases_bugs',
    'source'=>'non-db',
		'vname'=>'LBL_BUGS',
  ),

(上記 >は、本当は半角)
と記述されている。このcases_bugsは、下にあるのではなく、Sugarのホームのしたのmetadata(=modulesと同じレベル)のところに、cases_bugsMetaData.phpというファイルを作成し、そこにテーブル名とテーブル内容、インデックス、'relationships'を記述する。

 これを作成した場合、関係のテーブルを作り直すため、管理者機能でリペアを行うか、インストーラーから行う場合、実践!オープンソースCRMアプリケーション入門の131ページ下側のmanifestファイルの例にあるようなrelationshipsを記述して、インストールする。


  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

Javaでファイルのアンチウイルススキャンを実装する方法の一例

2008-01-17 19:34:29 | JavaとWeb

まだ、読んでないので、一応自分へのメモということで・・

ここの記事
JEEアプリケーションでのファイルのウイルススキャンの実装
http://codezine.jp/a/article/aid/1979.aspx


Symantec Scan Engine 5.1のJava APIをつかうらしい。
ってことは、他のメーカーじゃだめってことなんでしょうが
(他のメーカーは他のメーカーでAPIがあるのかな。。)



  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

最強”コンピューター”ウィルスによるパンデミックに対する備えは?

2008-01-17 16:05:52 | Weblog

 この前、NHKスペシャルで、シリーズ 最強ウイルス 第1夜 ドラマ 感染爆発~パンデミック・フルーっていうのをやってた。これはインフルエンザだけど、コンピューターウィルスでも、似たようなことは考えられると思う。

 従来のコンピューターウィルスは、(ウィリアムのいたずらを含め)誰でも作れるわけではない。
 そこで、アンチウィルスメーカーがそのウイルスをチェックするソフトを作れば、事態は解決する。

 しかし、仮に、ちょっとした知識があれば、簡単にコンピューターウィルスが作れるようになった場合、話はやっかいになる。そーすると、そのウィルスの変異体も簡単に作れてしまう。その場合、コンピューターウィルスのように、そのウィルスに自己増殖作用はなくても、故意に、自分でそのウィルスというか、破壊プログラムを入れられてしまったら(その上変異させて入れたら)どんどん被害が広まってしまう(この状態が”コンピューターウィルスによるパンデミック”)。




 とくに、あのドラマでは、他国からウィルスがきたが、コンピューターウィルスにおいても、他国からこられると、厄介な話になる。こんなケースだ。

<<妄想>>

(1)ある国と日本がささいなことで、ネット上の争いになる。
(2)怒ったその国が、日本のサイトに細工して、ウィルス(というか破壊プログラム)を入れる
(3)多くの日本人がそのサイトを開き、どんどん障害が起きる
(4)その国の有志が、どんどん、その破壊プログラムを変形して細工する
(5)なので、アンチウィルスメーカーも対策がとれない。

 とこんなケースだ。国が違う場合、国民感情が入ってくるので、多くの人がそれに参加することになるだろう。




 現在、このような手法はSQLインジェクション、クロスサイトスクリプティングぐらいしかないが、もっと強力な、
    :

   以下省略、やっぱ書くの、やめました。
   この作り方に、気づかれる可能性が大きいので・・

    :





ということで、具体的にXXX(省略したところに書いたこと)と、その応用破壊工作に対する手法をIPAは考えるべきだが、考えていなさそうなので((^^;)・・大丈夫なのか・・)ウィリアムのいたずら様が換わりに教えて進ぜよう。

<<対応方法>>

・一番効果的なのはブラウザメーカーが、あらかじめ設定してある■(これは自分で設定できるようにする)以外の■に対して、アクセスしようとした場合は、そのメッセージを出すようにする。

 そして、そのメッセージが出た場合、おかしな■だったら、その■へのアクセスをしないように出来るようにする。さらに、そのページ内で、サイトは違っても同じ■だったら、アクセスしないということも出来るようにする。

 このXXXで入ってくるやつは、違うアドレスでも同じ■にアクセスするはずである。

 →でも、これは、IEやFireFoxがやってくれないとだめだ。

・パーソナルファイヤーウォールはあるので、OK!と思うかもしれないが、一般的に使っている■だと、その■を閉じられると困る。
 また、一般的に使っている■を変えても、一般的に使っている■へアクセスしようとするパケットは流れてしまい、パケットがいっぱいになってこまることには変わりないので、それだけでは不十分である。

・メールからこの手を使われる危険がある。Outlook(Express)では、デフォルトだと、最後に来たメールをプレビューウィンドウで開いてしまう。
 こーなると、この手を使われたメールが最後に来ると(開かれて危険なので)困るので、

 表示→レイアウト

 で出てくる「ウィンドウのレイアウトのプロパティ」で「プレビューウィンドウを表示する」のチェックをはずす。そして、変なメールは開かない。

・変なサイトは開かないというのは、たしかに多少の効果があるかもしれないが、不正アクセスされてみんなが開くようなサイトに細工されると、この効果はない。

・・・ごめん、やっぱ、はやったら、あんまり手がないかも。。

(■には、同じことばが入りますが、その言葉を書くと、手口がわかってしまうので、伏字にしました)



  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

量子コンピューターで売りたいのか、先生の美しさで売りたいのか?出版社は(^^;)

2008-01-17 12:12:30 | Weblog

量子コンピューター・・
よくわかりませんよね。

で、その量子コンピューターの本に、ようこそ量子という本があるんだそうです。

で、ここからが問題。
この本の宣伝用チラシ、および、ブックカバーに著者の先生の写真が載ってるんだけど、
(ふつう、こーいう難しい話題の本のブックカバーに著者の先生の写真って、入れないよね)
この先生が、美しい・・

うーん、丸善(って、この本の出版社)
量子コンピューターで売りたいのか、先生の美しさで売りたいのか?


  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

音楽権利者団体「ipod、HDD、携帯電話、カーナビ等も課金の対象にすべき」―DBのHDも?。。

2008-01-16 23:04:43 | Weblog

ここの痛いニュース
音楽権利者団体「ipod、HDD、携帯電話、カーナビ等も課金の対象にすべき」
http://blog.livedoor.jp/dqnplus/archives/1080245.html

によると(以下斜体は上記サイトより引用)


87の権利者団体が「Culture First」の理念を発表した。
「文化が経済至上主義の犠牲になっている」とし、私的録音録画補償金の堅持に加え、対象をiPodやPC、携帯電話などに拡大すべきと訴えている。


だそうな。で、その87の団体とは

日本音楽著作権協会(JASRAC)や実演家著作隣接権センター(CPRA)など著作権者側
の87団体


だそうで、


権利者側はこれまでも、補償金の徴収対象になっていないデジタル録画・録音機器を
対象にするよう訴えてきたが、今後は「Culture First」の旗印の下に、改めて
「iPodなど携帯オーディオ、PC、携帯電話、カーナビ、Blu-ray Disc、HD DVD、HDD
などを補償金の対象にすべき」と訴えていく。


といってるそーなんだけど・・

HDDって、ハードディスクう??

あのー、データベースとかをおいておく、ハードディスクですか??
パソコンのワードやExcelデータを置いておくハードディスクですかあ??

家で使っているのはさておき、会社のHDDに音楽とか入れることは。。。ないと思いますけどお・・

お金返してくれるのかしら・・??
それとも音楽用パソコンと事務用パソコンとか、別れるのかしら(^^;)

うーん、これはUSBメモリやSDカードにデータを置くしかない?




  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

クロスサイト”プリンティング”の応用その2-Webからローカルのプログラムを起動

2008-01-16 16:27:14 | Weblog

 先日のクロスサイト”プリンティング”のテクニック、本当ならWebアプリの世界が広がる気が。。と、昨日のクロスサイト”プリンティング”の応用-Webからローカルにファイルを書き出すの続き。

 あるサーバーのJavaScript(ローカル以外)から、ローカルのプログラムを起動する方法を示します。これって、便利でしょ(^^)v

 今回は具体的に、
・前回と同じく、
  http://www.geocities.jp/xmldtp/aj_localtest.htm
のサイトから、
・上の段に、自分のローカルにあるExcel.EXEのパスを指定して
・実行ボタンをクリックすると
・ローカルでExcelが起動するというのをやります。




■方法の概要

昨日と同じです。

・ローカルに、Socketサーバーで、ポート5050番で、以下の機能を持った
 サービスを立ち上げる
  ・POST形式で受け取った内容をもとに、引数
     fnameで指定されたパスのプログラムを実行

・フォームタグでmethod=POST action="http://127.0.0.1:5050" を指定、
 このフォームタグ内に、fnameを用意しておく。
 このファイルを保存し、ローカル以外の別のサーバーに置く

・上記ファイルにアクセスし、fnameをいれ、Submitボタンをクリックすると、
 ポート5050のサービスが実行され、fnameに指定したパスのプログラムが実行される。




■ソース

 エラー処理とか、日本語化とか、一切抜いて、簡単に書いてあります。

●別のサーバーに置いたHTMLファイル
 これ、前回と同じ。

<html>
<head><title>クロスサイトプリンティング応用テスト</title></head>
<body>
<form method="post" action="http://127.0.0.1:5050">
<input type=text name=fname><BR>
<textarea name=fdata>
</textarea><BR>
<input type=submit value="実行"><BR>
</form>
</body>

(上記< > ¥は、本当は半角です)

今回はfdataは使いませんが、前回と比較しやすくするため、そのままにしておきました。




●ローカルに置くソース
 ローカルにおくプログラムは、起動するプログラムと、1セッション分(1スレッド分)のプログラムの2つに分かれます。
 だいたいの書き方は、ここと同じです。

<<1.起動するプログラム>>

 前回とまったく同じ。以下のプログラムをtest.javaとします
import java.io.*;
import java.net.*;

public class test {
	/*
	 * 	メイン処理(呼び出し元)
	 */
	public static void main(String[] args) 
	{
		try
		{
			// サーバーを生成
			ServerSocket serverSocket = new ServerSocket(5050);
			while(true)
			{			
				// ソケットを生成
				Socket socket = serverSocket.accept();
				TestThread tr1 = new TestThread();
				tr1.setSocket(socket);
				tr1.start();
			}	

		}
		catch(Exception e)
		{
			e.printStackTrace();
		}	
	}

}

(上記< > ¥は、本当は半角)

<<2.スレッドのプログラム>>

 前回とは「処理」のところがちがっていてて、プログラムを起動します。
 以下のプログラムをTestThread.javaとします
import java.io.*;
import java.net.*;

public class TestThread extends Thread {
	Socket socket = null;

 	
  	public void setSocket(Socket socket)
  	{
  		this.socket	=	socket;
  	}
  	
	/*
	 * 処理部分
	 */
	public void run()
	{
		if ( socket	==	null )
		{
			return;
		}

		try
		{
			//--------------------
			//受信する
			//--------------------
			InputStream	is1	
				=socket.getInputStream();
			InputStreamReader	ir1
				= new InputStreamReader(is1);
			BufferedReader		br1	= new BufferedReader(ir1);

			//	よみこめるまでまってる
			while(is1.available()	==	0);
		
			
			//	1行読み込む
			int	c;
			String  header = "";
			while((c = br1.read()) != -1 )
			{
				header = header + (char)c;
				if (( header.indexOf("¥n¥n") > 0 ) ||
					( header.indexOf("¥r¥n¥r¥n") > 0 ) )
				{
					break;
				}
			}
				
			//	データ部分の長さを取得
			String[] line = header.split("¥n");
			int datalen = -1;
			for(int i = 0 ; i < line.length; i ++ )
			{
				if ( line[i].indexOf("Content-Length:")	>=	0 )
				{
					String lenbuf
					  = line[i].substring("Content-Length:".length());
					try{
						datalen = Integer.parseInt(lenbuf.trim());
					}catch(Exception e){
					}
				}	
			}

			//	データがある場合、データ取得
			String data = "";
			if ( datalen	>	0 )
			{
				char[] datachar = new char[datalen];
				br1.read(datachar);
				StringBuffer databuf = new StringBuffer();
				databuf.append(datachar);
				data	=	databuf.toString();
			}

			//--------------------
			//	処理
			//--------------------
			//	データがある場合、ファイル名、データ取得
			String fname="";
			if ( data.length()	>	0 )
			{
				// 改行をカットする
				data = data.replaceAll("¥r","");
				data = data.replaceAll("¥n","");

				//	ファイル名とデータきりだし
				String[] dline = data.split("&");
				for(int i = 0 ; i < dline.length ; i ++ )
				{
					String[] cell = dline[i].split("=");
					if ( cell[0].compareTo("fname")	==	0 )
					{
						fname	=	cell[1];
					}
				}					
			}

			//	プログラム実行
			if (fname.length()	>	0 )
			{
				try
				{
					// 適当に、コード変換
					fname = URLDecoder.decode(fname,"UTF-8");
					
				     // プロセス実行
      				Process process = Runtime.getRuntime().exec(fname);
				}
				catch(Exception e)
				{
				}			
			}

			//--------------------
			//送信する
			//--------------------
			OutputStreamWriter	ow1
				= new OutputStreamWriter(socket.getOutputStream());
			BufferedWriter bw1 = new BufferedWriter(ow1);

			bw1.write("OK");
			bw1.flush();
			
			
			//	クローズ
			bw1.close();
			ow1.close();
			br1.close();
			ir1.close();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		
	}

}

(上記< > ¥は、本当は半角)




■うごかしかた

で、2つのjavaプログラムをコンパイルして、同じフォルダにおいて、
testのクラスを実行すれば
(Eclipseだったら、同じプロジェクトに入れて、testのクラスを指定して
 Runすれば)、
プログラムが開始します(しますけど、その時点では、何もおきません、見かけ上)

で、あらかじめ、どっかのサーバーにおいておいた、HTMLファイルをIEで開いて、
上にプログラムのパス名を適当に入れて、実行ボタンをクリックすると、
ローカルで、そのプログラムが実行します。
たとえば、

C:¥Program Files¥Microsoft Office¥ほにゃらら¥EXCEL.EXE
(¥は、実際には半角です。「ほにゃらら」には、Microsoft Officeフォルダの下の、
 Excelが入っているフォルダ名(Office10とか)が入ります)。

と、fnameのところ(つまり、上)に入れて実行ボタンをクリックすると、
ローカルでExcelが立ち上がります。

なお、返り値を、この結果として返したい場合は、以下のサイト
JavaでHello World 外部コマンド編
http://www.hellohiro.com/command.htm

を参考にして、Process以下を直してください。



  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

Webから、(サーバだけでなく)ローカルDBに、更新がかけられるってことなら、グーグルを超えた?

2008-01-16 12:24:56 | Weblog

 おお、ウィリアムのいたずらは、グーグルを越えたかもしれん!

 昨日の、クロスサイト”プリンティング”の応用-Webからローカルにファイルを書き出すだけど、 TestThread.javaで、ファイルに書き出しているけど、これを、JDBCとかでやれば、ローカルのデータベースに書き出せることになる。
 ちなみに、今はJavaで書いているけど、ソケットプログラムはVC++でも書ける。
 そーして、ODBCを経由して、ローカルMS-Accessのmdbにデータを書き出したり、帳票をローカルから出したりすることも出来そうだ。

 一定時間ごとに動かせるプログラム(Linuxのクーロンとか、Windowsのタスクとか、ただし、排他制御まで考えた場合、そーいうフリーソフトもあるみたい)を使えば、ローカルDBとサーバーの同期を取ることもできる。

 もちろん、このスレッドから、さらに複数スレッドを生成して処理することも出来る・・

 おおおおー。。

 もちろん、このサーバープログラムが動いていれば、プログラムをAJAXで書いて、ダウンロードし、その後、ローカルファイル、DBを書き出す形でオフライン処理、適当なところで(同期を取りたいところで)ローカルDBからデータを取り出し、サーバーにアップすることも出来る。まさに、Google Gearsなみの機能。

 その上、GoogleGearsとちがって、好きなローカルDBに入れられるし、帳票も出せる。。。

 おお、ウィリアムのいたずらのこの機能は、GoogleGearsを越えたかもしれん!

P.S あくまでも、クライアントに、ソケット通信プログラムを入れないと出来ないよ(^^;)
  なにもしないで、帳票が出たりするわけではないからね。

  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

クロスサイト”プリンティング”の応用-Webからローカルにファイルを書き出す

2008-01-15 20:08:09 | Weblog

 昨日のクロスサイト”プリンティング”のテクニック、本当ならWebアプリの世界が広がる気が。。で、調べてみるね!と書いたこと報告。

 たしかに、IEで、Formタグに書いた内容とファイル名で、ローカルにファイルを書き出せました
(もちろん、セキュリティレベルを一切変えずに!です)。

 その方法と、コードを説明しますね。




■方法の概要

・ローカルに、Socketサーバーで、ポート5050番で、以下の機能を持った
 サービスを立ち上げる
  ・POST形式で受け取った内容をもとに、引数
     fnameで指定されたファイル名で、
     fdataの内容を書き出す

・フォームタグでmethod=POST action="http://127.0.0.1:5050" を指定、
 このフォームタグ内に、fname、fdataを用意しておく。
 このファイルを保存し、ローカル以外の別のサーバーに置く

・上記ファイルにアクセスし、fname、fdataをいれ、Submitボタンをクリックすると、
 ポート5050のサービスが実行され、fnameに指定したファイル名で、
 fdataの内容が書き出される。




■ソース

 エラー処理とか、日本語化とか、一切抜いて、簡単に書いてあります。

●別のサーバーに置いたHTMLファイル
 これなのですが、中身は、こんなかんじ

<html>
<head><title>クロスサイトプリンティング応用テスト</title></head>
<body>
<form method="post" action="http://127.0.0.1:5050">
<input type=text name=fname><BR>
<textarea name=fdata>
</textarea><BR>
<input type=submit value="実行"><BR>
</form>
</body>

(上記< > ¥は、本当は半角です)




●ローカルに置くソース
 ローカルにおくプログラムは、起動するプログラムと、1セッション分(1スレッド分)のプログラムの2つに分かれます。
 だいたいの書き方は、ここと同じです。

<<1.起動するプログラム>>

 とくに、起動するプログラムに関して言うと、まったくおなじです。
 以下のプログラムをtest.javaとします
import java.io.*;
import java.net.*;

public class test {
	/*
	 * 	メイン処理(呼び出し元)
	 */
	public static void main(String[] args) 
	{
		try
		{
			// サーバーを生成
			ServerSocket serverSocket = new ServerSocket(5050);
			while(true)
			{			
				// ソケットを生成
				Socket socket = serverSocket.accept();
				TestThread tr1 = new TestThread();
				tr1.setSocket(socket);
				tr1.start();
			}	

		}
		catch(Exception e)
		{
			e.printStackTrace();
		}	
	}

}

(上記< > ¥は、本当は半角)

<<2.スレッドのプログラム>>

 そいつは、こんなかんじ。「処理」のところがちがっていてて、ファイル保存します。
 以下のプログラムをTestThread.javaとします
import java.io.*;
import java.net.*;

public class TestThread extends Thread {
	Socket socket = null;

 	
  	public void setSocket(Socket socket)
  	{
  		this.socket	=	socket;
  	}
  	
	/*
	 * 処理部分
	 */
	public void run()
	{
		if ( socket	==	null )
		{
			return;
		}

		try
		{
			//--------------------
			//受信する
			//--------------------
			InputStream	is1	
				=socket.getInputStream();
			InputStreamReader	ir1
				= new InputStreamReader(is1);
			BufferedReader		br1	= new BufferedReader(ir1);

			//	よみこめるまでまってる
			while(is1.available()	==	0);
		
			
			//	1行読み込む
			int	c;
			String  header = "";
			while((c = br1.read()) != -1 )
			{
				header = header + (char)c;
				if (( header.indexOf("¥n¥n") > 0 ) ||
					( header.indexOf("¥r¥n¥r¥n") > 0 ) )
				{
					break;
				}
			}
				
			//	データ部分の長さを取得
			String[] line = header.split("¥n");
			int datalen = -1;
			for(int i = 0 ; i < line.length; i ++ )
			{
				if ( line[i].indexOf("Content-Length:")	>=	0 )
				{
					String lenbuf = 
                                                  line[i].substring("Content-Length:".length());
					try{
						datalen = Integer.parseInt(lenbuf.trim());
					}catch(Exception e){
					}
				}	
			}

			//	データがある場合、データ取得
			String data = "";
			if ( datalen	>	0 )
			{
				char[] datachar = new char[datalen];
				br1.read(datachar);
				StringBuffer databuf = new StringBuffer();
				databuf.append(datachar);
				data	=	databuf.toString();
			}

			//--------------------
			//	処理
			//--------------------
			//	データがある場合、ファイル名、データ取得
			String fname="";
			String fdata= "";
			if ( data.length()	>	0 )
			{
				// 改行をカットする
				data=data.replaceAll("¥r","");
				data=data.replaceAll("¥n","");

				//	ファイル名とデータきりだし
				String[] dline = data.split("&");
				for(int i = 0 ; i < dline.length ; i ++ )
				{
					String[] cell = dline[i].split("=");
					if ( cell[0].compareTo("fname")	==	0 )
					{
						fname	=	cell[1];
					}
					else if ( cell[0].compareTo("fdata")	==	0 )
					{
						fdata	=	cell[1];
					}
				}					
			}

			//	ファイル書き出し
			if (fname.length()	>	0 )
			{
				try
				{
					File f = new File(fname);
					FileOutputStream fo = new FileOutputStream(f);
					fo.write(fdata.getBytes());
					fo.close();			
				}
				catch(Exception e)
				{
				}			
			}

			//--------------------
			//送信する
			//--------------------
			OutputStreamWriter	ow1
				= new OutputStreamWriter(socket.getOutputStream());
			BufferedWriter bw1 = new BufferedWriter(ow1);

			bw1.write("OK");
			bw1.flush();
			
			
			//	クローズ
			bw1.close();
			ow1.close();
			br1.close();
			ir1.close();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		
	}

}

(上記< > ¥は、本当は半角)




■うごかしかた

で、2つのjavaプログラムをコンパイルして、同じフォルダにおいて、
testのクラスを実行すれば
(Eclipseだったら、同じプロジェクトに入れて、testのクラスを指定して
 Runすれば)、
プログラムが開始します(しますけど、その時点では、何もおきません、見かけ上)

で、あらかじめ、どっかのサーバーにおいておいた、HTMLファイルをIEで開いて、
上にファイル名、下に書き出しデータを適当に入れて、実行ボタンを
クリックすると、ファイル書き出しします。

だだし、話を簡単にするため、コード変換とかはしてないので、日本語を入れると
日本語では書き出されませんが・・・


  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

植物警備隊

2008-01-15 10:54:34 | Weblog

 前に書いた、植物による防犯装置ができるってこと?と、「ナノチューブでできた極小ラジオの開発に成功」軍事の市街戦に使われたら・・ を、あわせると、植物(農作物)を警備する&植物で警備することが出来そうな気がする・・

こんなかんじ。
・農作物や植物の生体電位をはかる
  →はかることは出来るようだ。
・その電位情報を、ナノチューブとまではいかないが、小型の発信機で、近くの中継局に送り、
・中継局は、電気信号に変えて、インターネットで処理設備までおくる。
・そーすると、動物によって植物(農作物)が食べられたとか、踏みつけられたりしたら、
 電位が変わりそうだ・・
・変わった電位情報が、インターネットを経由して届いてくるから、特徴検出して
 (電位変化に特徴がある?)食べられたり、踏まれたようであれば、警告を発する。

こーいうシステムなら、作物に付けておいて、いのししとかきたら、警告を発してくれる(小型の発信機はラジオになっていて、大きな音を鳴らしたりするものいいとおもうし、場所が分かるので、ロボットが軽微に言ってもいい)ので、農作物あらし対策にいいし、家の窓辺に人が入ってきたら、この装置??によって、警告を発してくれる。

 ・・・って、どお?


  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

クロスサイト”プリンティング”のテクニック、本当ならWebアプリの世界が広がる気が。。

2008-01-14 12:45:15 | JavaとWeb

ここのスラッシュドットの記事
「クロスサイト・プリンティング」攻撃が発見される
http://slashdot.jp/security/08/01/13/2326218.shtml

によると、(以下斜体は上記サイトより引用)

ITProの記事によると、ネットワーク・プリンタに許可なく印刷できる攻撃手法、Cross Site Scriptingならぬ「Cross Site Printing」が発見された(ha.ckers.orgのブログ記事、発見者による説明資料[PDF])。

Cross Site Printingで細工されたウェブサイトにアクセスすると,そのパソコンを接続しているローカル・ネットワーク内のプリンタ(多くの場合ポート9100を開けて待機している)に印刷ジョブが送られ,ユーザが意図しない印刷が行われる。公開された資料を見ると、攻撃にはJavaScriptを仕込むだけで良く、単に印刷する以外にPostScriptの実行やFAX送信も出来るようだ。


ほー、見てみましょう
ここ(PDF) http://aaron.weaver2.googlepages.com/CrossSitePrinting.pdf

うん?
てーか、JavaScriptどころか、ポート9100とか、ポート番号指定すると、
ブラウザって、ローカルのそのポートに接続に行っちゃうの(@_@!)

つまり、http://ほにゃらら:9100と指定すると、ローカルの9100番
ポートにアクセスに行っちゃうらしい

だから(以下青字は、上記PDFより引用)


<FORM ACTION='HTTP://YOURPRINTER:9100' ID='MSGFORM' ENCTYPE='MULTIPART/FORM-DATA' METHOD='POST'>
<TEXTAREA NAME='MSG' ID='MSG' WRAP='NONE' ROWS='50' COLS='100'>
TESTING THIS PRINTER OUT.
</TEXTAREA><INPUT TYPE=SUBMIT VALUE=SUBMIT></FORM>


(上記< >は、原文は半角)

ってすると、テキストエリアの内容を(自分のローカルにあるプリンタの)YOURPRINTERのポート9100に送り込む
9100がプリンタ用ポートなら出力できる
という話らしい。

えー、(@_@!)これって、自分が今開いているサイト以外、
ローカルといえどもアクセスできないんじゃなくって・・・

そっか、なこたーねーな、あれはJavascriptとかはそうだけど、
たしかに画像とか、自分のアクセスしているサイト以外の
ほかのサイトの画像とかも、とってくるもんな・・・




うん?そーすると、この機能あると、ちょー便利!

 もちろん、マッシュアップなどで、プリンタへ直接
 データを書きだせるということはあるけど、

 そんなことより、ソケット(サーバー側用)のプログラムを
いろいろ書いて、ローカルにデーモンみたいな感じでずーっと
常駐させとけば、ブラウザからその機能をいつでも呼び出して
利用できる。ファイルの保存、書きだし、プログラム実行
なんでもOKっていうことになる・・

 たとえば、いままで、ブラウザからフォルダを指定して、
そのフォルダにあるファイル全部をZIP圧縮して転送するってことは
できなかったけど、

・ローカルに、そーいうプログラムをソケットで
(サーバー側のソケットプログラム)書いておいて、

・自分のマシンでそのプログラムを立ち上げておけば
 (ポート7777とか決めて)、

・FORMで、上記のように(ポートは7777にするけど)指定して、
 データにフォルダを指定しておけば

OKってこと・・・

 もし、これがOKになれば、いろいろ規制があってできないと
思われていたことが、一挙に実現可能になる・・・

 まじっすかあ・・
 まじなんっすかああ・・

 ちょっと時間があったら、試してみよう・・・

 試してみたら、報告するね!



  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

「ナノチューブでできた極小ラジオの開発に成功」軍事の市街戦に使われたら・・

2008-01-13 23:21:22 | Weblog

ここのニュース
ナノチューブでできた極小ラジオの開発に成功――米大学
http://www.itmedia.co.jp/news/articles/0711/02/news028.html

によると(以下斜体は上記サイトより引用)


 米カリフォルニア大学バークリー校は10月31日、同校の物理学教授らが、「世界最小」のラジオを開発したと発表した。髪の毛の1万分の1の細さとされるカーボンナノチューブで作られたラジオで、バッテリーとイヤフォンさえあれば、好きなラジオ局に周波数を合わせることができるという。


ほー。バッテリって言っても、そんなに小さいのだったら、ものすごぐ小さくていいし、
イヤフォンもふくめて、1ミリ四方ぐらいにできるのかなあ。。
だって


血管内に送り込んで利用する無線端末など、まったく新しい用途に発展する可能性もあるとしている。


って書いてあるくらいだから。。。

そーなってくると、軍事で、市街戦でつかわれたら、大変だね!

・大都市上空で、このラジオの粉(1ミリ四方ぐらいの粉末にして)をまき散らします。
・あまりにも小さいので、みんなの耳の中に入ってしまいます!
・そこで、なんか、歌でもなんでもいいから、ずーっとラジオからかけ続けます。

耳に入ってしまった住民。。

うー(>_<!)
聞きたくもない歌がエンドレスに聞こえる・・
耳に指を入れて取ろうとしたら・・・
なおさら中に入って、大音響(>_<!)
耳かきでとろうとしても・・・いっぱい入って取り出せない・・
耳鼻科も大変、長い列・・・

みんな、うるさくて寝られなーい、考えられなーい・・・

これ、テロの手に渡ったりしたら、大変だよね!!

*コンピュータにまったく関係なさそうな話ですが、
あとで関係します。今回のこの記事は、前ふりです。


  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

植物による防犯装置ができるってこと?

2008-01-13 01:55:18 | Weblog

 さっき、サイエンスZEROのアートと科学のフシギな関係というのをいていたら、
ユリの電圧を測って音をならすというのをやっていた。
ユリは周りの環境によって、表面に流れる電圧が変わるんですって。
人がきたりすると。。

 そこで、その電圧の違いを音であらわしていた。。


。。。ちょっとまって。。
人が来ると、音が変わるんだったら、それって、番犬がわりにならない?
家の前の木に電圧測るやつるけて、人が来たら、電圧が変わるので、
その変化に応じて音を鳴らすと・・

さらに、人がきたくらいで電圧が変わるんだったら、食べられちゃったりしたら、
もっとかわりそうだよねえ。。

だとすると、作物に、その電圧装置をつけておいて、夜、野生動物がきて、
食べれれてしまったら、電圧が変わって、知らせてくれる
(ないしは、警報機が作動、おおきな音が出るとか。。)

そうすれば、野生動物に荒らされる被害が最小限に抑えられるような気が。。。

植物による防犯装置の研究は、警備だけでなく、農業の面からも、
奥深いものがあるかも。。。


  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

mラーニング?

2008-01-12 09:31:16 | Weblog

さっき、放送大学のONAIR(放送大学の連絡誌?みたいなもん)の最近来たやつ(NO88)見ていたら、上海電視大学のことが書いた2ページめに

mラーニング

という言葉が。。。

ただしくはm(モバイル)ラーニングとかいてある。

ケータイ電話のe-ラーニングのことだそうな


  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

2008年のテンサプライズ(IT版)予想解説(10)消えた年金が見つかると年金減る人も!

2008-01-11 23:21:45 | Weblog

シリーズウィリアムのいたずら選定2008年のテンサプライズ(IT版)、今回は10個目

10.年金問題はさらに話題に
   →年金の照合について、かけている部分を補う検索を指摘した
    ウィリアムのいたずらの2007/12/26のエントリが話題に
   →このほかでも、7,8,9の理論、今回のテンサプライズの的中率から、
    このブログが超話題に!日経コンピューターでも取り上げざるを得なくなる
   →Gooブログでベスト100入り常連、ベスト10入りも!
     →現在、平日は150番台前後、ベスト100入りしたのは、確か1、2回です。


です




これを書いたときは、
「年金は、記録が見つかったら増える」と思って書いてました。
でも、そーじゃないようです。

ここのニュース

えっ? 年金記録、見つかったら損する!?
http://www.iza.ne.jp/news/newsarticle/living/114284/


たいへんです。こーいう人は、みつけないでほしいよね(^^;)

うーん、こーなってくると、この話、複雑・・

ということで、年金の話は、どーなるかわかりませんな。。

ただ、この前書いた、年金を納めているところ、納めてないところを図形みたいにみて、その形を検索するという、ゲシュタルト検索?(はい、こんな言葉ありません。ウィリアムのいたずらが今作りました。全体的な形からの検索ということです)は、おもしろいんではないかいなと。。

 え、形だったら、ゲシュタルトもそうだけど、パターンもそうじゃないかって?
 でも、パターン検索っていうと、図形の形ではなく、ぜんぜん違う検索なのよ
 特徴点検索ともちがうし(特徴をだしてるんじゃなくって、形そのもので検索している)。。。






 一方、このブログの順位ですけど、いま、170番台くらいが、平日だと多いのから・・
 800人くらいの人が見て、(IP数が)、プレビュー数が2800件くらいです。
 Gooの順位は、IP数でつきます。100番は、1233 IPなので、もうちょっと??
 (いや、遠い??)

実現可能性

今年、100番以内に入るのは、ウィリアムのいたずら的には120%だけど、
現実的には、60%くらい??


  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする