MEMORVA

ダウンロードCGI、Javaサンプル - データのダウンロード方法

更新:

au独自のデータのダウンロード仕様とサンプル。

データのダウンロード方法

  • auの古い機種では、着メロや待ち受け画像のダウンロードの方法が少し特殊です。
    1. CRCの付加
      まず、データファイルにEZweb独自のCRC値を付加します。
      一般的なCRC16やCRC32と違います。
      詳しくは、公式サイトを参照。
      この処理によって、データファイルの一番最後にCRC計算値が2バイト付加されます。
      したがって、ファイルサイズが2バイト増えます。
      CRC値がついてないデータは、ダウンロードできません。
    2. ダウンロードCGIを用意する
      EZweb独自のダウンロード方式を使ったプログラムを用意し、データをダウンロードします。
      このダウンロード方式は、データを少しずつダウンロードさせるようになっています。
      端末が1回に受信を要求するデータのサイズ(バイト数)は、端末により異なります。
  • 上記の方法は、Aタグを使ってダウンロードCGIにリンクをはり、データのダウンロードを行います。
    だたし、端末によってはこの方式でなくても単にAタグでデータファイルに直接リンクを張るだけでダウンロードできるものもあります。
    これらの仕様については、公式サイトにも書いてあります。
  • しかし、着うた対応機種(WAP2.0)以降は、着メロなどのデータは基本的にOBJECTタグを使ってダウンロードできるので、この仕様は今はあまり使用されないかもしれません。
    ただし、画像や一部のデータはOBJECTタグを使ってダウンロードできません。


データのダウンロード用のタグ

  • ダウンロード用プログラムに対してのリンクの張り方です。
    1. HDMLの場合(全データ共通)
      <A TASK="gosub"
      LABEL="Get"
      METHOD="post"
      DEST="device:data/dnld?url=http://example.com/download.cgi&name=$fname&size=$fsize&disposition=$devtype">
      ダウンロード</A>
      name:データファイルのパス(必須)
      size:データファイルのファイルサイズ(必須)
      disposition:データファイルのデータタイプ(必須)。下記参照。
      title:データのタイトル(任意)。何も書かなければ、データに埋め込まれた題名。携帯電話により動作が異なります。
    2. HTMLの場合(全データ共通)
      <a href="device:data/dnld?url=http://example.com/download.cgi&name=$fname&size=$fsize&disposition=$devtype">
      ダウンロード</a>

      上の書き方の場合、データのダウンロード後に強制的にトップページなどに戻ってしまう場合があります。
      <wml:anchor>
      <wml:spawn href="device:data/dnld?url=http://example.com/download.cgi&name=$fname&size=$fsize&disposition=$devtype"/>
      ダウンロード</wml:anchor>
      と書くと、ダウンロード完了後、ダウンロード元のページに戻ります。
    3. disposition
      dispositionについては、MIMEタイプ、dispositionを参照。


データダウンロードのサンプルソース

  • サンプルソースの出力は、HDML。
    HTMLに書き換えても動作します。
  • データをダウンロード後、ソース中に書いたページが表示されるものと、携帯独自の画面が表示されるものがあり、 携帯電話により異なります。
  • Perlの場合
    #!/usr/bin/perl
    
    $str = $ENV{'QUERY_STRING'};
    @pairs = split(/&/,$str);
    foreach $pair (@pairs){
    	($name,$value) = split(/=/,$pair);
    	$value =~ tr/+/ /;
    	$value =~ s/%(..)/pack("C",hex($1))/eg;
    	$cgi{$name} = $value;
    }
    
    $namex = $cgi{'name'};
    $offsetx = $cgi{'offset'};
    $countx = $cgi{'count'};
    
    &fileDownload;
    
    sub fileDownload{
    
    	if($offsetx >= 0 && $countx > 0){
    		open(FD, '<'."$namex");
    		binmode FD; 
    		seek(FD, $offsetx, 0);
    		read(FD, $buf, $countx);
    		close FD;
    	  
    	# HEADER 
    		print "Content-type: application/x-up-download" ,"\n";
    		print "Content-length: $countx", "\n";
    		print "\n";
    		print $buf;
    		}
    	#elsif($offsetx == 0 && $countx == 0){
    		#If &receipt was appended to the download request,
    		#the device will request a buffer of size count=0
    		#to indicate completion; so, return an "empty"
    		#download header
    		#
    		#print "Content-type: application/x-up-download", "\n";
    		#print "Content-length: 0", "\n";
    		#print "\n";
    		#}
    	elsif($offsetx == -1 && $countx == -1){
    		print "Content-type: text/x-hdml;charset=Shift_JIS\n\n";
    		print "<HDML VERSION=3.0 TTL=0>";
    		print "<DISPLAY>";
    	#	print "<ACTION TYPE=ACCEPT TASK=GO DEST=sound.hdml LABEL=戻る>";
    		print "<ACTION TYPE=accept TASK=return LABEL=戻る>";
    		print "<IMG ICON=scroll>再生<BR>";
    		print "ダウンロード成功";
    		print "<BR>";
    	#	print "<A TYPE=ACCEPT TASK=GOSUB DEST=sound.hdml LABEL=戻る>戻る</A>";
    		print "</DISPLAY>";
    		print "</HDML>";
    		}
    	elsif($offsetx == -1 && $countx == -2){
    		print "Content-type: text/x-hdml;charset=Shift_JIS\n\n";
    		print "<HDML VERSION=3.0 TTL=0>";
    		print "<DISPLAY>";
    		print "<ACTION TYPE=accept TASK=return LABEL=戻る>";
    		print "ダウンロード失敗";
    		print "<BR>";
    	#	print "<A TYPE=ACCEPT TASK=GOSUB DEST=sound.hdml LABEL=戻る>戻る</A>";
    		print "</DISPLAY>";
    		print "</HDML>";
    		}
    	else{
    		print "Content-type: text/x-hdml;charset=Shift_JIS\n\n";
    		print "<HDML VERSION=3.0 TTL=0>";
    		print "<DISPLAY>";
    		print "<ACTION TYPE=accept TASK=return LABEL=戻る>";
    		print "ファイルが存在しません";
    		print "<BR>";
    	#	print "<A TYPE=ACCEPT TASK=GOSUB DEST=sound.hdml LABEL=戻る>戻る</A>";
    		print "</DISPLAY>";
    		print "</HDML>";
    		}
    }
    
  • Javaの場合(JSP、サーブレットなど)
    String nameSt = null;
    String offsetSt = null;
    String countSt = null;
    int offsetx = 0;
    int countx = 0;
    nameSt = request.getParameter("name");
    offsetSt = request.getParameter("offset");
    countSt = request.getParameter("count");
    offsetx = Integer.parseInt(offsetSt);
    countx = Integer.parseInt(countSt);
    
    if(offsetx >= 0 && countx > 0){
    	try{
    		//ファイルがあるパスを指定する。
    		//ファイル名だけを受け取っても、ディレクトリ+ファイル名を受け取ってもOK。
    		/*
    		String strBuff = "";
    		FileReader fr = new FileReader("/htdocs/data/"+nameSt);
    		char buf[] = new char[countx];
    		fr.skip(offsetx);
    		fr.read(buf, 0, buf.length);
    		strBuff = new String(buf);
    		fr.close();
    		*/
    		String strBuff = "";
    		String serverDir = "/htdocs/data/"+nameSt;
    		InputStream in = new FileInputStream(serverDir);
    		byte[] buf = new byte[countx];
    		in.skip(offsetx);
    		in.read(buf);
    		strBuff = new String(buf, "8859_1");
    		in.close();
    		response.setContentType("application/x-up-download");
    		response.setContentLength(countx);
    		out.print(strBuff);
    	}catch(Exception e){
    		System.out.println(e);
    	}
    }else if(offsetx == 0 && countx == 0){
    	response.setContentType("application/x-up-download");
    	response.setContentLength(0);
    	//out.print("\n");
    }else if(offsetx == -1 && countx == -1){
    	response.setContentType("text/x-hdml;charset=Shift_JIS");
    	out.println("<HDML VERSION=3.0 TTL=0>");
    	out.println("<DISPLAY>");
    	out.println("<ACTION TYPE=accept TASK=return LABEL=戻る>");
    	out.println("<IMG ICON=scroll>再生<BR>");
    	out.println("ダウンロード完了");
    	out.println("<BR>");
    	out.println("</DISPLAY>");
    	out.println("</HDML>");
    }else if(offsetx == -1 && countx == -2){
    	response.setContentType("text/x-hdml;charset=Shift_JIS");
    	out.println("<HDML VERSION=3.0 TTL=0>");
    	out.println("<DISPLAY>");
    	out.println("<ACTION TYPE=accept TASK=return LABEL=戻る>");
    	out.println("ダウンロード失敗");
    	out.println("<BR>");
    	out.println("</DISPLAY>");
    	out.println("</HDML>");
    }else{
    	response.setContentType("text/x-hdml;charset=Shift_JIS");
    	out.println("<HDML VERSION=3.0 TTL=0>");
    	out.println("<DISPLAY>");
    	out.println("<ACTION TYPE=accept TASK=return LABEL=戻る>");
    	out.println("ファイルが存在しません");
    	out.println("<BR>");
    	out.println("</DISPLAY>");
    	out.println("</HDML>");
    }