「◆HTTPグループ」の編集履歴(バックアップ)一覧はこちら
「◆HTTPグループ」(2023/11/03 (金) 09:38:18) の最新版変更点
追加された行は緑色になります。
削除された行は赤色になります。
*情報
作者名:YouTubeダウンロードし放題
引用元:なでしこプログラム掲示板「HTTPグループ」>http://nade.jp-pro.net/bbs/bbs2/cbbs.cgi?mode=al2&namber=1219
更新:
2012/01/27
Cookie取得を更新
エラー防止の真偽グループを追加
*[[ダウンロード>http://www26.atwiki.jp/isoroku_be/?cmd=upload&act=open&page=%E2%97%86HTTP%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97&file=HTTP%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97.nako]]
*概要
五十六さんの作品「TCPクライアントでHTTPっぽいものセット」(以下TCPセット)
(http://nade.jp-pro.net/bbs/bbs2/cbbs.cgi?mode=al2&namber=911 感謝!!)
を元に機能拡張・改善したライブラリです。
目標としては、簡単に利用できて、且つ、カスタマイズ性に飛んだライブラリを目指して作成しました。
TCPセットとの大まかな違いとしては、
・TCPデータ取得→新HTTPデータ取得
・グループとして利用できる
・不同期ダウンロード
・Cookieの自動取得
・POST命令の削除(無念 後日また挑戦してみます)
などです。
*解説
「新HTTPデータ取得」は「HTTPデータ取得」と同じ使い方です。
HTTPグループの基本的な使い方は、URLや保存先、オプションなどを指定してから、「開始」です。
**注意
・HTTPグループに関わる全ての命令を本体の下に記述してください
本来ならば、本体のみを別ファイルにして「取り込む」命令を使用するのが望まれます
・HTTPグループにFILEを設定した時点でダウンロードとみなされます
逆にFILEを空にすればデータ取得になります
・「母艦の終了した時」のイベントのかわりに「母艦終了時」を使用してください
**追加した機能
***グループ化
動的作成による今までの命令も使えます
***ダウンロードの不同期化
「同期はオフ」とすることで不同期ダウンロードができます
しかし、タイマーで無理やり内臓しているので多少バグがあります
動的にHTTPグループを作成し、同時ダウンロードを行う事ができます
***経過表示のイベント化
経過表示時の行動を何度も書き換えることができるようになりました
***Cookie自動取得機能(意外と便利)
Internet ExplorerのCookieを取得します
***自動ページ転送機能
Locationがあれば再取得するようになりました
***自動エンコード機能(初期状態ではオフ)
***推定残り時間
***レジューム(途中ダウンロード)の簡潔化
レジュームを指定しなくても、FILEが存在すればレジュームが使用できるようになりました
逆に強制的に使用しないようにするには「レジューム機能はオフ」とします
**削除した機能
***POST命令
サンプル使う人はGET命令より少ないのと
グループが混じると条件分岐が多くて負担が多いので
**特に意識しなくてよいこと
***SizeOver機能
動画などの大容量のファイルを「データ取得」するとメモリが足りなくなってしまいます
なので、ファイルが0.5MGバイト以上の場合は一時的に保存するようにしました
***チャンクによるバグの修正
チャンクは受信し終わってからまとめて処理するようにしました
***TCPクライアントと統合
「nakonet.nako」も取り込まなくて済みます
(TCPクライアントと併用しても問題ありません)
***タイマーとの統合
タイマーを内蔵しているので、不同期ダウンロードの際にタイマーを作成する必要がありません
***TCP自動切断機能(重要)
ライブラリ内部でHTTPグループを一括管理しているので、終了時にTCPを手動で切断する必要がなくなりました。
(nakonet.dllのバグでTCPを切断しないと終了できない問題を克服)
***メモリ節約のための変数宣言
変数を厳密に宣言することで余計なメモリを節約し、関数外の変数が影響することを防ぎます
***計算を最小限かつ高速化
*サンプル
本体の後ろに置いてください
**新HTTP関数
「http://www.google.co.jp/」の新HTTPデータ取得を言う
**一番簡単なグループ
HTTP1とはHTTPグループ
HTTP1=「http://www.youtube.com/」
HTTP1で開始
それを言う
**高度な静的グループ
経過詳細テキストとは文字列
平均速度とは数値
受信サイズとは数値
受信予定サイズとは数値
経過バーとはプログレスバー
経過詳細とはラベル
経過詳細の位置=経過バーの右側
中止ボタンとはボタン
HTTP2とはHTTPグループ
中止ボタンのクリックした時は~
HTTP2の有効切替#HTTP2の停止判定=1
HTTP2について
URL=「http://www.youtube.com/」
#FILE=「{デスクトップ}sample.html」
#HEAD取得判定=1
#レジューム機能=0
#自動エンコード機能=1
経過表示時は~
経過詳細テキスト=空
経過パーセント=HTTP2の経過パーセント
平均速度=(HTTP2の平均速度/1024/1024)を1で小数点切り上げ
瞬間速度=(HTTP2の瞬間速度/1024/1024)を1で小数点切り上げ
推定残り=HTTP2の推定残り
経過詳細テキストに「{経過パーセント}% 平均速度:{平均速度}MB/s 瞬間速度:{瞬間速度}MB/s 推定残り:{推定残り}秒」を配列追加
受信サイズ=(HTTP2の受信Size/1024/1024)を1で小数点切り上げ
受信予定サイズ=(HTTP2の受信予定Size/1024/1024)を1で小数点切り上げ
経過詳細テキストに「受信:{受信サイズ}/{受信予定サイズ}MB」を配列追加
もし、経過パーセント=100ならば
経過詳細テキスト=「ダウンロード完了」
経過詳細=経過詳細テキスト
経過バー=HTTP2の経過パーセント
レジューム機能=0
経過表示間隔=0.5
データとは文字列
データ=開始
データを言う
**IDを利用した動的グループの同時ダウンロード
URL一覧とは配列
URL一覧に「http://www.google.co.jp/」を配列追加
URL一覧に「http://www.yahoo.co.jp/」を配列追加
URL一覧に「http://ja.wikipedia.org/wiki/」を配列追加#「http://ja.wikipedia.org/wiki/メインページ」に転送
URL一覧に「http://www.youtube.com/」を配列追加
URL一覧に「http://www.apple.com/jp/」を配列追加
URL一覧に「http://twitter.com/」を配列追加
IDとは数値
ID一覧とは配列
URL一覧で反復
ID=ActiveHTTPG_ID;ID一覧にIDを配列追加
Panel[回数]を経過パネルとして作成
Panel[回数]→Y=(回数-1)*60
Panel[回数]→テキスト1=対象
HTTPG[ID]→URL=対象
HTTPG[ID]→同期=0
HTTPG[ID]→タグ=回数
HTTPG[ID]→経過表示時は~
経過率とは数値=自身→経過パーセント
受信S=(自身→受信Size/1024)を1で小数点切り上げ
平均速度とは数値=(自身→平均速度/1024/1024)を1で小数点切り上げ
瞬間速度とは数値=(自身→瞬間速度/1024/1024)を1で小数点切り上げ
推定残りとは数値=自身→推定残り
Panel[自身→タグ]→値=経過率
TEXTとは文字列
TEXT[0]=「{経過率}% {受信S}kb」
TEXT[1]=「平均:{平均速度}MB/s 瞬間:{瞬間速度}MB/s 残り時間:{推定残り}秒」
もし、経過率=100ならば
TEXT[1]=「ダウンロード完了」
Panel[自身→タグ]→テキスト2=TEXT
描画処理反映
ID一覧で反復;HTTPG[対象]→開始()
■経過パネル
・Y ←Y設定
・値 ←値設定
・テキスト1 ←テキスト1設定
・テキスト2 ←テキスト2設定
・値設定(S)~経過バーOBJ→値=S
・テキスト1設定(S)~ラベル1OBJ→テキスト=S
・テキスト2設定(S)~ラベル2OBJ→テキスト=S
・Y設定(S)~
経過バーOBJ→Y=S
それ=経過バーOBJ→右側;ラベル1OBJ→位置=それ
それ=経過バーOBJ→下側;ラベル2OBJ→位置=それ
・パネルOBJ ・経過バーOBJ ・ラベル1OBJ ・ラベル2OBJ
・作る~
経過バーOBJをプログレスバーとして作成
ラベル1OBJをラベルとして作成
ラベル2OBJをラベルとして作成
ラベル1OBJ→テキスト=空
それ=経過バーOBJ→右側;ラベル1OBJ→位置=それ
ラベル2OBJ→テキスト=空
それ=経過バーOBJ→下側;ラベル2OBJ→位置=それ
*本体
!変数宣言が必要
最大HTTP数とは数値=20
!HTTP_ID一覧とは配列
!__TCPIDとは数値=0
母艦終了時とは変数
母艦終了時は~何もしない
経過表示時イベントとは変数
経過表示時イベントは~
それ=自身→経過パーセント;母艦=それ&「%」
母艦の終了可能=0
母艦の閉じた時は~
母艦終了時
HTTP_ID一覧で反復
エラー無視#一応エラー回避
「{対象}→終了時処理」をナデシコする
母艦の終了可能=1;おわり
!初期UA=「HTTP」
!ERROR_TCP_403=「HTTP_403 "Forbidden" アクセスが認められていません。」
!ERROR_TCP_404=「HTTP_404 "NotFound" 見つかりません」
!ERROR_TIMEOUT=「HTTP_TIMEOUT タイムアウトしました」
!ERROR_STOP=「HTTP_STOP ユーザーによって停止されました」
■真偽
・値 ←値設定 →値取得 デフォルト
・{整数}F値
・値設定(V)~
もし、(V=0)||(V=1)ならばF値=V
違えばエラー発生
・値取得~_=F値
■HTTPグループ
# ↓読み書きOK
# 基本オプション 初期化されないので毎回書き換えるように
・URL{="http://www.google.co.jp/"} ←URL設定 →URL取得 デフォルト
・FILE ←FILE設定 →FILE取得
・{整数/*真偽値*/}HEAD取得判定
・{イベント}経過表示時
# 高度なオプション
・{イベント}終了時イベント
・{イベント}エラー時#~エラーメッセージと言う
・{ハッシュ}オプション# 送信ヘッダに追加 UAなど
・{ハッシュ}Cookie
・{真偽}有効{=1} ←有効設定 →有効取得
・{真偽}同期{=1}
・{真偽}Cookie自動取得{=1} # InternetExplorerのCookieを適用
・{真偽}レジューム機能{=1}
・{真偽}自動ページ転送{=1}
・{真偽}自動エンコード機能# UTF8を自動でエンコード
・{数値}経過表示間隔{=0.1}# 経過表示する間隔(0.1秒ごと)
・{数値}瞬間速度幅{=5}
・{数値}TimeOut秒数{=5}
・{数値}HTTPVer{=1.1}
・ポケット ・タグ# 一時データの格納に使える
# ↓読込のみOK
・FILEDATA
・HEAD
# 経過表示に使える変数
・{整数}通信中・{整数}受信回数
・{整数}受信予定Size・{整数}受信Size
・{整数}開始時間 ・{整数}経過時間
・{整数}経過パーセント
・{整数}推定残り# 秒
・{数値}平均速度・{数値}瞬間速度# b/s
・{整数}瞬間Size・{整数}前時間・{整数}瞬間時間
・{整数}TimeOut回数
#-----
・{ハッシュ}HEAD_HASH・{整数}StatusNum{=200}
・Pass ・送信HEAD・{整数}出力H
・{真偽}一回目判定{=1}
・{真偽}Download判定・{真偽}Chunk判定
・{真偽}Resume判定・{真偽}SizeOver判定
・{真偽}中断判定・{真偽}停止判定
・Host{="www.google.co.jp"}・{整数}Port{=80}
・{整数}ID
# フェイク
・{非公開}FURL
・URL取得~FURLで戻る
・{非公開}FFILE
・FILE取得~FFILEで戻る
・{非公開}F有効{=1}
・有効取得~F有効で戻る
・{非公開}Option
・{非公開}FERROR ←エラー設定
・エラー設定(S)~エラーメッセージ=S;エラー時
#----------------------------------------------------------------
・開始~
FILEDATA=空;HEAD=空;終了時処理#一応
Option=オプション
もし、Option@「User-Agent」=空ならば、Option@「User-Agent」=初期UA
もし、Option@「Host」=空ならば、Option@「Host」=Host
もし、Cookie自動取得=1ならば、Cookie=FURLのCookie取得
もし、Cookie≠空ならば、Option@「Cookie」=Cookieの改行を「;」に置換
もし、Download判定=1ならば
もし、(FFILEの存在=1)AND(レジューム機能=0)ならば
FFILEをファイル完全削除
出力H=FFILEを「書」でファイルストリーム開く
もし、FFILEの存在=1ならば、
Resume判定=1
受信Size=FFILEのファイルサイズ
Option@「Range」=「bytes={受信Size}-」
出力Hで受信Sizeにファイルストリーム位置設定
送信HEAD=Optionを逆HTTPヘッダハッシュ変換("GET",Pass,HTTPVer);接続
もし、同期=0ならば
TIMER_OBJ=VCL_CREATE(自身,名前,VCL_GUI_TIMER)
VCL_SET(TIMER_OBJ,VCL_PROP_VALUE,経過表示間隔*1000)
VCL_SET(TIMER_OBJ,VCL_PROP_ENABLED,1);戻る
オンの間
メインループ
もし、(通信中=0)AND(一回目判定=0)ならば抜ける
(経過表示間隔)秒待つ
メインループ後
もし、HEAD取得判定=1ならば、HEADで戻る
違えば、FILEDATAで戻る
・メインループ~
もし、停止判定=1ならば、終了時処理;FERROR=ERROR_STOP;戻る
経過表示時
もし、一回目判定=1ならば、
TimeOut回数に1を直接足す
もし、(経過表示間隔*TimeOut回数)>TimeOut秒数ならば
終了時処理;FERROR=ERROR_TIMEOUT;戻る
違えば、TimeOut回数=0
・メインループ後~
経過表示時
もし、Download判定=1ならば
出力Hで0にファイルストリーム位置設定
FILEDATA=出力Hで(0.5*1024*1024)をファイルストリーム読む
出力Hをファイルストリーム閉じる
#自動エンコード機能
もし、自動エンコード機能=1ならば
Typeとは文字列=HEAD_HASH@「Content-Type」
Typeを「^([^;]*);」で正規表現マッチ
もし、抽出文字列[0]=「text/html」ならば
Typeを「charset=([^\s]*)」で正規表現マッチ
もし、抽出文字列[0]=「utf-8」ならば
FILEDATA=FILEDATAを「UTF8」から「SJIS」へ文字コード変換
もし、Download判定=1ならば、FILEDATAをFFILEに保存
終了時イベント;終了時処理
・終了時処理~
通信中=0;切断
もし、TIMER_OBJ≠空ならば
VCL_SET(TIMER_OBJ,VCL_PROP_ENABLED,0);TIMER_OBJ=空
もし、SizeOver判定=1ならば
もし、出力Hのファイルストリームサイズ≠-1ならば
出力Hをファイルストリーム閉じる
FFILEをファイル完全削除
Download判定=0;FILE=空;
# 変数の初期化
一回目判定=1;TimeOut回数=0;SizeOver判定=0;停止判定=0;
受信回数=0;受信予定Size=0;受信Size=0;出力H=0;
経過パーセント=0;平均速度=0;瞬間速度=0;
・接続した時~
通信中=1;開始時間=システム時間;
送信HEADを送信
・受信した時~
受信回数に1を直接足す
受信DATAとは文字列=受信
もし、一回目判定=1ならば
一回目判定=0
HEAD=受信DATAから「{~}{~}」まで切り取る
もし、HEAD取得判定=1ならば、経過パーセント=100;通信中=0;切断;戻る
HEAD_HASH=HEADをHTTPヘッダハッシュ変換
StatusNum=HEAD_HASH@「HTTP.Response」#正しい使いかたではない
もし、StatusNum≠200ならば
StatusNumで条件分岐
403ならば、経過パーセント=100;通信中=0;切断;FERROR=ERROR_TCP_403;戻る
404ならば、経過パーセント=100;通信中=0;切断;FERROR=ERROR_TCP_404;戻る
301ならば、HEAD_HASH@「Location」にTCP転送;戻る
302ならば、HEAD_HASH@「Location」にTCP転送;戻る
303ならば、HEAD_HASH@「Location」にTCP転送;戻る
#レジュームで既にダウンロード完了しているとき/Rangeが不正な場合
416ならば、経過パーセント=100;通信中=0;切断;戻る
違えば、#StatusNumを言う
もし、HEAD_HASH@「Content-Length」≠空ならば
受信予定Size=HEAD_HASH@「Content-Length」
もし、Resume判定=1ならば
受信予定Sizeに受信Sizeを直接足す
もし、(Download判定=0)AND(受信予定Size>(0.5*1024*1024))ならば
FILE=「download_{テンポラリフォルダ}{開始時間}.bak」
出力H=FFILEを「書」でファイルストリーム開く
SizeOver判定=1;Download判定=1;
もし、HEAD_HASH@「Transfer-Encoding」=「chunked」ならば、Chunk判定=1
前時間=開始時間
瞬間Sizeに(受信DATAのバイト数)を直接足す
受信Sizeに(受信DATAのバイト数)を直接足す
経過時間=システム時間-開始時間
経過パーセント=INT(受信Size/受信予定Size*100)
平均速度=受信Size/経過時間*1000
もし、受信回数%瞬間速度幅=0ならば
瞬間時間=システム時間-前時間;前時間=システム時間
瞬間速度=瞬間Size/瞬間時間*1000;瞬間Size=0;
推定残り=INT((受信予定Size-受信Size)/平均速度)
もし、Chunk判定=0ならば
もし、Download判定=0ならば、FILEDATAに受信DATAを追加
違えば、出力Hで受信DATAをファイルストリーム書く
もし、経過パーセント>=100ならば
経過パーセント=100;通信中=0;切断;戻る;
違えば
FILEDATAに受信DATAを追加
FILEDATAの(FILEDATAのバイト数-4)から1バイト抜き出す
もし、それ=「0」ならば
FILEDATA=FILEDATAからChunkData抽出
もし、Download判定=1ならば
出力HでFILEDATAをファイルストリーム書く
FILEDATA=空
経過パーセント=100;通信中=0;切断;戻る
・URL設定(S)~
FURL=S
Host=FURLからURLドメイン名抽出
もし、(FURLを「:(\d+)\/」で正規表現マッチ)≠空ならば、Port=抽出文字列[0]
FURLを「http:\/\/[^\/]+(\/.*)」で正規表現マッチ
Pass=抽出文字列[0]
・FILE設定(S)~
FFILE=S
もし、FFILE≠空ならば、Download判定=1
違えば、Download判定=0
・有効設定(S)~
F有効=S
もし、通信中=1ならば
もし、F有効=1ならば
もし、中断判定=1ならば
一回目判定=1;Resume判定=1;中断判定=0;
Option@「Range」=「bytes={受信Size}-」
送信HEAD=Optionを逆HTTPヘッダハッシュ変換("GET",Pass,HTTPVer);接続
違えば、切断;中断判定=1
・有効切替~
もし、F有効=0ならば、有効=1
違えば、有効=0
・停止~停止判定=1
・TCP転送(Sに)~
切断
もし、自動ページ転送=0ならば、経過パーセント=100;通信中=0;戻る
URL=S;一回目判定=1;
もし、Option@「User-Agent」=空ならば、Option@「User-Agent」=初期UA
もし、Option@「Host」=空ならば、Option@「Host」=Host
もし、Cookie自動取得=1ならば、Cookie=FURLのCookie取得
もし、Cookie≠空ならば、Option@「Cookie」=Cookieの改行を「;」に置換
送信HEAD=Optionを逆HTTPヘッダハッシュ変換("GET",Pass,HTTPVer);接続
・{非公開}TIMER_OBJ
・時満ちた時~
メインループ
もし、(通信中=0)AND(一回目判定=0)ならば
VCL_SET(TIMER_OBJ,VCL_PROP_ENABLED,0)
メインループ後
・受信データ・エラーメッセージ・{非公開}TCPID{=0}・{非公開}オブジェクト
・接続~TCP_COMMAND(TCPID,"connect","{Host}:{Port}")
・切断~TCP_COMMAND(TCPID,"disconnect",0)
・送信(Sを)~TCP_COMMAND(TCPID, "send", S)
・受信~TCP_COMMAND(TCPID,"recv",0)で戻る
・作る~
TCPID=__TCPID;__TCPIDに1を直接足す;
TCP_COMMAND(TCPID,"create",自身→名前)
HTTP_ID一覧に名前を配列追加
■TAG #タイマーに追加
・タグ・ポケット
●逆HTTPヘッダハッシュ変換(SをMethod,Pass,HTTP_Ver)
HEAD_TOPとは文字列=「{Method} {Pass} HTTP/{HTTP_Ver}」
HEAD_BTTOMとは配列
もし、S@「UA」≠空ならば、S@「UA」=S@「User-Agent」
Sの「UA」をハッシュキー削除
Sのハッシュキー列挙で反復
もし、S@対象≠空ならば、HEAD_BTTOMに「{対象}: {S@対象}」を配列追加
「{HEAD_TOP}{~}{HEAD_BTTOM}{~}{~}」で戻る
●ChunkData抽出(Sの|Sから)
結果とは文字列;DATAとは文字列;ChunkSizeとは数値
オンの間
ChunkSize=INT(「${Sから改行まで切り取る}」)
もし、(ChunkSize=「0」)OR(ChunkSize=空)ならば抜ける
DATA=Sの1から(ChunkSize)バイト抜き出す
結果にDATAを追加
Sの1から(ChunkSize+2)バイト削除
もし、DATA=空ならば抜ける
結果で戻る
●Cookie取得(URLから|URLの|URLを)
結果とはハッシュ;Hとは数値;
DATAとは文字列;DATA配列とは配列;
URLを「http://(?:www\.)*([^\/]+\/)」で正規表現マッチ
Domainとは文字列=抽出文字列[0]
「{テンポラリフォルダ}\Cookies\*.txt」の全ファイル列挙で反復
H=対象を「読」でファイルストリーム開く
DATA=Hで(対象のファイルサイズ)をファイルストリーム読む
Hをファイルストリーム閉じる
オンの間
DATAで「*」まで切り取る
エラー監視#壊れている可能性があるので
DATA配列=それの配列上下空行削除
エラーならば続ける
もし、DATA配列=空ならば抜ける
もし、DATA配列[2]=Domainならば
結果@DATA配列[0]=DATA配列[1]
#結果=結果の改行を「;」に置換
結果で戻る
HTTPGとは変数;TIMERとは変数;
新HTTPオプションとはハッシュ;HTTPG一覧とはハッシュ;
●HTTPG準備(S)
(S)回
HTTPG[回数]をHTTPグループとして作成
HTTPG[回数]→ID=回数
HTTPG一覧@回数=0
●新HTTPデータ取得(URLから|URLの|URLを)
IDとは数値=ActiveHTTPG_ID
HTTPG[ID]→URL=URL
HTTPG[ID]→経過表示時は~経過表示時イベント
HTTPG[ID]→オプション=新HTTPオプション
HTTPG[ID]→FILE=空;HTTPG[ID]→HEAD取得判定=0;
HTTPG[ID]→開始
HTTPG一覧@ID=0
HTTPG[ID]→FILEDATAで戻る
●新HTTPヘッダ取得(URLから|URLの|URLを)
IDとは数値=ActiveHTTPG_ID
HTTPG[ID]→URL=URL
HTTPG[ID]→経過表示時は~経過表示時イベント
HTTPG[ID]→オプション=新HTTPオプション
HTTPG[ID]→FILE=空;HTTPG[ID]→HEAD取得判定=1;
HTTPG[ID]→開始
HTTPG一覧@ID=0
HTTPG[ID]→HEADで戻る
●新HTTPダウンロード(URLをFILEへ|URLからFILEに)
IDとは数値=ActiveHTTPG_ID
HTTPG[ID]→URL=URL
HTTPG[ID]→経過表示時は~経過表示時イベント
HTTPG[ID]→オプション=新HTTPオプション
HTTPG[ID]→FILE=FILE;HTTPG[ID]→HEAD取得判定=0;
HTTPG[ID]→開始
HTTPG一覧@ID=0
HTTPG[ID]→HEADで戻る
●ActiveHTTPG_ID
(最大HTTP数)回
もし、HTTPG一覧@回数=0ならば
HTTPG一覧@回数=1;回数で戻る
HTTPG準備(20)#最大20個のHTTPグループが利用できます
!変数宣言が不要
----
総合:&counter()
今日:&counter(today)人
昨日:&counter(yesterday)人
#comment()
*情報
作者名:YouTubeダウンロードし放題
引用元:なでしこプログラム掲示板「HTTPグループ」>http://nade.jp-pro.net/bbs/bbs2/cbbs.cgi?mode=al2&namber=1219
更新:
2012/01/27
Cookie取得を更新
エラー防止の真偽グループを追加
*[[ダウンロード>http://www26.atwiki.jp/isoroku_be/?cmd=upload&act=open&page=%E2%97%86HTTP%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97&file=HTTP%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97.nako]]
*概要
五十六さんの作品「TCPクライアントでHTTPっぽいものセット」(以下TCPセット)
(http://nade.jp-pro.net/bbs/bbs2/cbbs.cgi?mode=al2&namber=911 感謝!!)
を元に機能拡張・改善したライブラリです。
目標としては、簡単に利用できて、且つ、カスタマイズ性に飛んだライブラリを目指して作成しました。
TCPセットとの大まかな違いとしては、
・TCPデータ取得→新HTTPデータ取得
・グループとして利用できる
・不同期ダウンロード
・Cookieの自動取得
・POST命令の削除(無念 後日また挑戦してみます)
などです。
*解説
「新HTTPデータ取得」は「HTTPデータ取得」と同じ使い方です。
HTTPグループの基本的な使い方は、URLや保存先、オプションなどを指定してから、「開始」です。
**注意
・HTTPグループに関わる全ての命令を本体の下に記述してください
本来ならば、本体のみを別ファイルにして「取り込む」命令を使用するのが望まれます
・HTTPグループにFILEを設定した時点でダウンロードとみなされます
逆にFILEを空にすればデータ取得になります
・「母艦の終了した時」のイベントのかわりに「母艦終了時」を使用してください
**追加した機能
***グループ化
動的作成による今までの命令も使えます
***ダウンロードの不同期化
「同期はオフ」とすることで不同期ダウンロードができます
しかし、タイマーで無理やり内蔵しているので多少バグがあります
動的にHTTPグループを作成し、同時ダウンロードを行う事ができます
***経過表示のイベント化
経過表示時の行動を何度も書き換えることができるようになりました
***Cookie自動取得機能(意外と便利)
Internet ExplorerのCookieを取得します
***自動ページ転送機能
Locationがあれば再取得するようになりました
***自動エンコード機能(初期状態ではオフ)
***推定残り時間
***レジューム(途中ダウンロード)の簡潔化
レジュームを指定しなくても、FILEが存在すればレジュームが使用できるようになりました
逆に強制的に使用しないようにするには「レジューム機能はオフ」とします
**削除した機能
***POST命令
サンプル使う人はGET命令より少ないのと
グループが混じると条件分岐が多くて負担が多いので
**特に意識しなくてよいこと
***SizeOver機能
動画などの大容量のファイルを「データ取得」するとメモリが足りなくなってしまいます
なので、ファイルが0.5MGバイト以上の場合は一時的に保存するようにしました
***チャンクによるバグの修正
チャンクは受信し終わってからまとめて処理するようにしました
***TCPクライアントと統合
「nakonet.nako」も取り込まなくて済みます
(TCPクライアントと併用しても問題ありません)
***タイマーとの統合
タイマーを内蔵しているので、不同期ダウンロードの際にタイマーを作成する必要がありません
***TCP自動切断機能(重要)
ライブラリ内部でHTTPグループを一括管理しているので、終了時にTCPを手動で切断する必要がなくなりました。
(nakonet.dllのバグでTCPを切断しないと終了できない問題を克服)
***メモリ節約のための変数宣言
変数を厳密に宣言することで余計なメモリを節約し、関数外の変数が影響することを防ぎます
***計算を最小限かつ高速化
*サンプル
本体の後ろに置いてください
**新HTTP関数
「http://www.google.co.jp/」の新HTTPデータ取得を言う
**一番簡単なグループ
HTTP1とはHTTPグループ
HTTP1=「http://www.youtube.com/」
HTTP1で開始
それを言う
**高度な静的グループ
経過詳細テキストとは文字列
平均速度とは数値
受信サイズとは数値
受信予定サイズとは数値
経過バーとはプログレスバー
経過詳細とはラベル
経過詳細の位置=経過バーの右側
中止ボタンとはボタン
HTTP2とはHTTPグループ
中止ボタンのクリックした時は~
HTTP2の有効切替#HTTP2の停止判定=1
HTTP2について
URL=「http://www.youtube.com/」
#FILE=「{デスクトップ}sample.html」
#HEAD取得判定=1
#レジューム機能=0
#自動エンコード機能=1
経過表示時は~
経過詳細テキスト=空
経過パーセント=HTTP2の経過パーセント
平均速度=(HTTP2の平均速度/1024/1024)を1で小数点切り上げ
瞬間速度=(HTTP2の瞬間速度/1024/1024)を1で小数点切り上げ
推定残り=HTTP2の推定残り
経過詳細テキストに「{経過パーセント}% 平均速度:{平均速度}MB/s 瞬間速度:{瞬間速度}MB/s 推定残り:{推定残り}秒」を配列追加
受信サイズ=(HTTP2の受信Size/1024/1024)を1で小数点切り上げ
受信予定サイズ=(HTTP2の受信予定Size/1024/1024)を1で小数点切り上げ
経過詳細テキストに「受信:{受信サイズ}/{受信予定サイズ}MB」を配列追加
もし、経過パーセント=100ならば
経過詳細テキスト=「ダウンロード完了」
経過詳細=経過詳細テキスト
経過バー=HTTP2の経過パーセント
レジューム機能=0
経過表示間隔=0.5
データとは文字列
データ=開始
データを言う
**IDを利用した動的グループの同時ダウンロード
URL一覧とは配列
URL一覧に「http://www.google.co.jp/」を配列追加
URL一覧に「http://www.yahoo.co.jp/」を配列追加
URL一覧に「http://ja.wikipedia.org/wiki/」を配列追加#「http://ja.wikipedia.org/wiki/メインページ」に転送
URL一覧に「http://www.youtube.com/」を配列追加
URL一覧に「http://www.apple.com/jp/」を配列追加
URL一覧に「http://twitter.com/」を配列追加
IDとは数値
ID一覧とは配列
URL一覧で反復
ID=ActiveHTTPG_ID;ID一覧にIDを配列追加
Panel[回数]を経過パネルとして作成
Panel[回数]→Y=(回数-1)*60
Panel[回数]→テキスト1=対象
HTTPG[ID]→URL=対象
HTTPG[ID]→同期=0
HTTPG[ID]→タグ=回数
HTTPG[ID]→経過表示時は~
経過率とは数値=自身→経過パーセント
受信S=(自身→受信Size/1024)を1で小数点切り上げ
平均速度とは数値=(自身→平均速度/1024/1024)を1で小数点切り上げ
瞬間速度とは数値=(自身→瞬間速度/1024/1024)を1で小数点切り上げ
推定残りとは数値=自身→推定残り
Panel[自身→タグ]→値=経過率
TEXTとは文字列
TEXT[0]=「{経過率}% {受信S}kb」
TEXT[1]=「平均:{平均速度}MB/s 瞬間:{瞬間速度}MB/s 残り時間:{推定残り}秒」
もし、経過率=100ならば
TEXT[1]=「ダウンロード完了」
Panel[自身→タグ]→テキスト2=TEXT
描画処理反映
ID一覧で反復;HTTPG[対象]→開始()
■経過パネル
・Y ←Y設定
・値 ←値設定
・テキスト1 ←テキスト1設定
・テキスト2 ←テキスト2設定
・値設定(S)~経過バーOBJ→値=S
・テキスト1設定(S)~ラベル1OBJ→テキスト=S
・テキスト2設定(S)~ラベル2OBJ→テキスト=S
・Y設定(S)~
経過バーOBJ→Y=S
それ=経過バーOBJ→右側;ラベル1OBJ→位置=それ
それ=経過バーOBJ→下側;ラベル2OBJ→位置=それ
・パネルOBJ ・経過バーOBJ ・ラベル1OBJ ・ラベル2OBJ
・作る~
経過バーOBJをプログレスバーとして作成
ラベル1OBJをラベルとして作成
ラベル2OBJをラベルとして作成
ラベル1OBJ→テキスト=空
それ=経過バーOBJ→右側;ラベル1OBJ→位置=それ
ラベル2OBJ→テキスト=空
それ=経過バーOBJ→下側;ラベル2OBJ→位置=それ
*本体
!変数宣言が必要
最大HTTP数とは数値=20
!HTTP_ID一覧とは配列
!__TCPIDとは数値=0
母艦終了時とは変数
母艦終了時は~何もしない
経過表示時イベントとは変数
経過表示時イベントは~
それ=自身→経過パーセント;母艦=それ&「%」
母艦の終了可能=0
母艦の閉じた時は~
母艦終了時
HTTP_ID一覧で反復
エラー無視#一応エラー回避
「{対象}→終了時処理」をナデシコする
母艦の終了可能=1;おわり
!初期UA=「HTTP」
!ERROR_TCP_403=「HTTP_403 "Forbidden" アクセスが認められていません。」
!ERROR_TCP_404=「HTTP_404 "NotFound" 見つかりません」
!ERROR_TIMEOUT=「HTTP_TIMEOUT タイムアウトしました」
!ERROR_STOP=「HTTP_STOP ユーザーによって停止されました」
■真偽
・値 ←値設定 →値取得 デフォルト
・{整数}F値
・値設定(V)~
もし、(V=0)||(V=1)ならばF値=V
違えばエラー発生
・値取得~_=F値
■HTTPグループ
# ↓読み書きOK
# 基本オプション 初期化されないので毎回書き換えるように
・URL{="http://www.google.co.jp/"} ←URL設定 →URL取得 デフォルト
・FILE ←FILE設定 →FILE取得
・{整数/*真偽値*/}HEAD取得判定
・{イベント}経過表示時
# 高度なオプション
・{イベント}終了時イベント
・{イベント}エラー時#~エラーメッセージと言う
・{ハッシュ}オプション# 送信ヘッダに追加 UAなど
・{ハッシュ}Cookie
・{真偽}有効{=1} ←有効設定 →有効取得
・{真偽}同期{=1}
・{真偽}Cookie自動取得{=1} # InternetExplorerのCookieを適用
・{真偽}レジューム機能{=1}
・{真偽}自動ページ転送{=1}
・{真偽}自動エンコード機能# UTF8を自動でエンコード
・{数値}経過表示間隔{=0.1}# 経過表示する間隔(0.1秒ごと)
・{数値}瞬間速度幅{=5}
・{数値}TimeOut秒数{=5}
・{数値}HTTPVer{=1.1}
・ポケット ・タグ# 一時データの格納に使える
# ↓読込のみOK
・FILEDATA
・HEAD
# 経過表示に使える変数
・{整数}通信中・{整数}受信回数
・{整数}受信予定Size・{整数}受信Size
・{整数}開始時間 ・{整数}経過時間
・{整数}経過パーセント
・{整数}推定残り# 秒
・{数値}平均速度・{数値}瞬間速度# b/s
・{整数}瞬間Size・{整数}前時間・{整数}瞬間時間
・{整数}TimeOut回数
#-----
・{ハッシュ}HEAD_HASH・{整数}StatusNum{=200}
・Pass ・送信HEAD・{整数}出力H
・{真偽}一回目判定{=1}
・{真偽}Download判定・{真偽}Chunk判定
・{真偽}Resume判定・{真偽}SizeOver判定
・{真偽}中断判定・{真偽}停止判定
・Host{="www.google.co.jp"}・{整数}Port{=80}
・{整数}ID
# フェイク
・{非公開}FURL
・URL取得~FURLで戻る
・{非公開}FFILE
・FILE取得~FFILEで戻る
・{非公開}F有効{=1}
・有効取得~F有効で戻る
・{非公開}Option
・{非公開}FERROR ←エラー設定
・エラー設定(S)~エラーメッセージ=S;エラー時
#----------------------------------------------------------------
・開始~
FILEDATA=空;HEAD=空;終了時処理#一応
Option=オプション
もし、Option@「User-Agent」=空ならば、Option@「User-Agent」=初期UA
もし、Option@「Host」=空ならば、Option@「Host」=Host
もし、Cookie自動取得=1ならば、Cookie=FURLのCookie取得
もし、Cookie≠空ならば、Option@「Cookie」=Cookieの改行を「;」に置換
もし、Download判定=1ならば
もし、(FFILEの存在=1)AND(レジューム機能=0)ならば
FFILEをファイル完全削除
出力H=FFILEを「書」でファイルストリーム開く
もし、FFILEの存在=1ならば、
Resume判定=1
受信Size=FFILEのファイルサイズ
Option@「Range」=「bytes={受信Size}-」
出力Hで受信Sizeにファイルストリーム位置設定
送信HEAD=Optionを逆HTTPヘッダハッシュ変換("GET",Pass,HTTPVer);接続
もし、同期=0ならば
TIMER_OBJ=VCL_CREATE(自身,名前,VCL_GUI_TIMER)
VCL_SET(TIMER_OBJ,VCL_PROP_VALUE,経過表示間隔*1000)
VCL_SET(TIMER_OBJ,VCL_PROP_ENABLED,1);戻る
オンの間
メインループ
もし、(通信中=0)AND(一回目判定=0)ならば抜ける
(経過表示間隔)秒待つ
メインループ後
もし、HEAD取得判定=1ならば、HEADで戻る
違えば、FILEDATAで戻る
・メインループ~
もし、停止判定=1ならば、終了時処理;FERROR=ERROR_STOP;戻る
経過表示時
もし、一回目判定=1ならば、
TimeOut回数に1を直接足す
もし、(経過表示間隔*TimeOut回数)>TimeOut秒数ならば
終了時処理;FERROR=ERROR_TIMEOUT;戻る
違えば、TimeOut回数=0
・メインループ後~
経過表示時
もし、Download判定=1ならば
出力Hで0にファイルストリーム位置設定
FILEDATA=出力Hで(0.5*1024*1024)をファイルストリーム読む
出力Hをファイルストリーム閉じる
#自動エンコード機能
もし、自動エンコード機能=1ならば
Typeとは文字列=HEAD_HASH@「Content-Type」
Typeを「^([^;]*);」で正規表現マッチ
もし、抽出文字列[0]=「text/html」ならば
Typeを「charset=([^\s]*)」で正規表現マッチ
もし、抽出文字列[0]=「utf-8」ならば
FILEDATA=FILEDATAを「UTF8」から「SJIS」へ文字コード変換
もし、Download判定=1ならば、FILEDATAをFFILEに保存
終了時イベント;終了時処理
・終了時処理~
通信中=0;切断
もし、TIMER_OBJ≠空ならば
VCL_SET(TIMER_OBJ,VCL_PROP_ENABLED,0);TIMER_OBJ=空
もし、SizeOver判定=1ならば
もし、出力Hのファイルストリームサイズ≠-1ならば
出力Hをファイルストリーム閉じる
FFILEをファイル完全削除
Download判定=0;FILE=空;
# 変数の初期化
一回目判定=1;TimeOut回数=0;SizeOver判定=0;停止判定=0;
受信回数=0;受信予定Size=0;受信Size=0;出力H=0;
経過パーセント=0;平均速度=0;瞬間速度=0;
・接続した時~
通信中=1;開始時間=システム時間;
送信HEADを送信
・受信した時~
受信回数に1を直接足す
受信DATAとは文字列=受信
もし、一回目判定=1ならば
一回目判定=0
HEAD=受信DATAから「{~}{~}」まで切り取る
もし、HEAD取得判定=1ならば、経過パーセント=100;通信中=0;切断;戻る
HEAD_HASH=HEADをHTTPヘッダハッシュ変換
StatusNum=HEAD_HASH@「HTTP.Response」#正しい使いかたではない
もし、StatusNum≠200ならば
StatusNumで条件分岐
403ならば、経過パーセント=100;通信中=0;切断;FERROR=ERROR_TCP_403;戻る
404ならば、経過パーセント=100;通信中=0;切断;FERROR=ERROR_TCP_404;戻る
301ならば、HEAD_HASH@「Location」にTCP転送;戻る
302ならば、HEAD_HASH@「Location」にTCP転送;戻る
303ならば、HEAD_HASH@「Location」にTCP転送;戻る
#レジュームで既にダウンロード完了しているとき/Rangeが不正な場合
416ならば、経過パーセント=100;通信中=0;切断;戻る
違えば、#StatusNumを言う
もし、HEAD_HASH@「Content-Length」≠空ならば
受信予定Size=HEAD_HASH@「Content-Length」
もし、Resume判定=1ならば
受信予定Sizeに受信Sizeを直接足す
もし、(Download判定=0)AND(受信予定Size>(0.5*1024*1024))ならば
FILE=「download_{テンポラリフォルダ}{開始時間}.bak」
出力H=FFILEを「書」でファイルストリーム開く
SizeOver判定=1;Download判定=1;
もし、HEAD_HASH@「Transfer-Encoding」=「chunked」ならば、Chunk判定=1
前時間=開始時間
瞬間Sizeに(受信DATAのバイト数)を直接足す
受信Sizeに(受信DATAのバイト数)を直接足す
経過時間=システム時間-開始時間
経過パーセント=INT(受信Size/受信予定Size*100)
平均速度=受信Size/経過時間*1000
もし、受信回数%瞬間速度幅=0ならば
瞬間時間=システム時間-前時間;前時間=システム時間
瞬間速度=瞬間Size/瞬間時間*1000;瞬間Size=0;
推定残り=INT((受信予定Size-受信Size)/平均速度)
もし、Chunk判定=0ならば
もし、Download判定=0ならば、FILEDATAに受信DATAを追加
違えば、出力Hで受信DATAをファイルストリーム書く
もし、経過パーセント>=100ならば
経過パーセント=100;通信中=0;切断;戻る;
違えば
FILEDATAに受信DATAを追加
FILEDATAの(FILEDATAのバイト数-4)から1バイト抜き出す
もし、それ=「0」ならば
FILEDATA=FILEDATAからChunkData抽出
もし、Download判定=1ならば
出力HでFILEDATAをファイルストリーム書く
FILEDATA=空
経過パーセント=100;通信中=0;切断;戻る
・URL設定(S)~
FURL=S
Host=FURLからURLドメイン名抽出
もし、(FURLを「:(\d+)\/」で正規表現マッチ)≠空ならば、Port=抽出文字列[0]
FURLを「http:\/\/[^\/]+(\/.*)」で正規表現マッチ
Pass=抽出文字列[0]
・FILE設定(S)~
FFILE=S
もし、FFILE≠空ならば、Download判定=1
違えば、Download判定=0
・有効設定(S)~
F有効=S
もし、通信中=1ならば
もし、F有効=1ならば
もし、中断判定=1ならば
一回目判定=1;Resume判定=1;中断判定=0;
Option@「Range」=「bytes={受信Size}-」
送信HEAD=Optionを逆HTTPヘッダハッシュ変換("GET",Pass,HTTPVer);接続
違えば、切断;中断判定=1
・有効切替~
もし、F有効=0ならば、有効=1
違えば、有効=0
・停止~停止判定=1
・TCP転送(Sに)~
切断
もし、自動ページ転送=0ならば、経過パーセント=100;通信中=0;戻る
URL=S;一回目判定=1;
もし、Option@「User-Agent」=空ならば、Option@「User-Agent」=初期UA
もし、Option@「Host」=空ならば、Option@「Host」=Host
もし、Cookie自動取得=1ならば、Cookie=FURLのCookie取得
もし、Cookie≠空ならば、Option@「Cookie」=Cookieの改行を「;」に置換
送信HEAD=Optionを逆HTTPヘッダハッシュ変換("GET",Pass,HTTPVer);接続
・{非公開}TIMER_OBJ
・時満ちた時~
メインループ
もし、(通信中=0)AND(一回目判定=0)ならば
VCL_SET(TIMER_OBJ,VCL_PROP_ENABLED,0)
メインループ後
・受信データ・エラーメッセージ・{非公開}TCPID{=0}・{非公開}オブジェクト
・接続~TCP_COMMAND(TCPID,"connect","{Host}:{Port}")
・切断~TCP_COMMAND(TCPID,"disconnect",0)
・送信(Sを)~TCP_COMMAND(TCPID, "send", S)
・受信~TCP_COMMAND(TCPID,"recv",0)で戻る
・作る~
TCPID=__TCPID;__TCPIDに1を直接足す;
TCP_COMMAND(TCPID,"create",自身→名前)
HTTP_ID一覧に名前を配列追加
■TAG #タイマーに追加
・タグ・ポケット
●逆HTTPヘッダハッシュ変換(SをMethod,Pass,HTTP_Ver)
HEAD_TOPとは文字列=「{Method} {Pass} HTTP/{HTTP_Ver}」
HEAD_BTTOMとは配列
もし、S@「UA」≠空ならば、S@「UA」=S@「User-Agent」
Sの「UA」をハッシュキー削除
Sのハッシュキー列挙で反復
もし、S@対象≠空ならば、HEAD_BTTOMに「{対象}: {S@対象}」を配列追加
「{HEAD_TOP}{~}{HEAD_BTTOM}{~}{~}」で戻る
●ChunkData抽出(Sの|Sから)
結果とは文字列;DATAとは文字列;ChunkSizeとは数値
オンの間
ChunkSize=INT(「${Sから改行まで切り取る}」)
もし、(ChunkSize=「0」)OR(ChunkSize=空)ならば抜ける
DATA=Sの1から(ChunkSize)バイト抜き出す
結果にDATAを追加
Sの1から(ChunkSize+2)バイト削除
もし、DATA=空ならば抜ける
結果で戻る
●Cookie取得(URLから|URLの|URLを)
結果とはハッシュ;Hとは数値;
DATAとは文字列;DATA配列とは配列;
URLを「http://(?:www\.)*([^\/]+\/)」で正規表現マッチ
Domainとは文字列=抽出文字列[0]
「{テンポラリフォルダ}\Cookies\*.txt」の全ファイル列挙で反復
H=対象を「読」でファイルストリーム開く
DATA=Hで(対象のファイルサイズ)をファイルストリーム読む
Hをファイルストリーム閉じる
オンの間
DATAで「*」まで切り取る
エラー監視#壊れている可能性があるので
DATA配列=それの配列上下空行削除
エラーならば続ける
もし、DATA配列=空ならば抜ける
もし、DATA配列[2]=Domainならば
結果@DATA配列[0]=DATA配列[1]
#結果=結果の改行を「;」に置換
結果で戻る
HTTPGとは変数;TIMERとは変数;
新HTTPオプションとはハッシュ;HTTPG一覧とはハッシュ;
●HTTPG準備(S)
(S)回
HTTPG[回数]をHTTPグループとして作成
HTTPG[回数]→ID=回数
HTTPG一覧@回数=0
●新HTTPデータ取得(URLから|URLの|URLを)
IDとは数値=ActiveHTTPG_ID
HTTPG[ID]→URL=URL
HTTPG[ID]→経過表示時は~経過表示時イベント
HTTPG[ID]→オプション=新HTTPオプション
HTTPG[ID]→FILE=空;HTTPG[ID]→HEAD取得判定=0;
HTTPG[ID]→開始
HTTPG一覧@ID=0
HTTPG[ID]→FILEDATAで戻る
●新HTTPヘッダ取得(URLから|URLの|URLを)
IDとは数値=ActiveHTTPG_ID
HTTPG[ID]→URL=URL
HTTPG[ID]→経過表示時は~経過表示時イベント
HTTPG[ID]→オプション=新HTTPオプション
HTTPG[ID]→FILE=空;HTTPG[ID]→HEAD取得判定=1;
HTTPG[ID]→開始
HTTPG一覧@ID=0
HTTPG[ID]→HEADで戻る
●新HTTPダウンロード(URLをFILEへ|URLからFILEに)
IDとは数値=ActiveHTTPG_ID
HTTPG[ID]→URL=URL
HTTPG[ID]→経過表示時は~経過表示時イベント
HTTPG[ID]→オプション=新HTTPオプション
HTTPG[ID]→FILE=FILE;HTTPG[ID]→HEAD取得判定=0;
HTTPG[ID]→開始
HTTPG一覧@ID=0
HTTPG[ID]→HEADで戻る
●ActiveHTTPG_ID
(最大HTTP数)回
もし、HTTPG一覧@回数=0ならば
HTTPG一覧@回数=1;回数で戻る
HTTPG準備(20)#最大20個のHTTPグループが利用できます
!変数宣言が不要
----
総合:&counter()
今日:&counter(today)人
昨日:&counter(yesterday)人
#comment()