μNet3のHTTPクライアントを使用してサーバへファイルをアップロードするサンプルプログラムについて説明します。
ファイルアップロードの仕様は、サーバによります。一般的な方法はありません。
今回のサンプルプログラムでは、サーバ側のスクリプトは、下のURLを参考にしました。
http://php.net/manual/ja/features.file- ... method.php
また、このサンプルプログラムプログラムでは1Mバイトのファイルをアップロードするために、
1Mバイト+α(ヘッダ、区切り)をPOSTしています。
1Mバイトのバッファを用意できないケースを想定しています。
少ないメモリで大きなサイズのデータをPOSTする方法のサンプルでもあります。
コード: 全て選択
/* 1Mバイトのファイルをアップロードするサンプル */
/* ファイル名は1M_bytes.bin */
/* 変更する場合はFILE_SIZEの定義を変更してください。*/
/* ファイルの内容は全て0x55 */
/* POST先はhttp://192.168.0.2/test/file_upload.php */
/* 変更する場合はURL_POST_FILEの文字列を変更してください。*/
#define FILE_SIZE (1024*1024)
#define URL_POST_FILE "http://192.168.0.2/test/file_upload.php"
ER shell_usr_cmd_http_post_file(VP ctrl, INT argc, VB *argv[])
{
T_HTTP_CLIENT hc;
T_HTTP_POSTDATA data;
VB *url = URL_POST_FILE;
ER ercd;
UINT i;
UINT len;
net_memset(&hc, 0, sizeof(hc));
/* URLからサーバーのIPアドレス取得 */
/* HTTPクライアントで使用するデータ(T_HTTP_CLIENT型)のメンバ変数svrへ格納 */
ercd = http_get_ipaddr(
url, /* URL */
&hc.svr, /* IPアドレスを格納する場所 */
ID_SOC_DNSC, /* DNSクライアントで使用するソケットのソケットID */
SPL_DNS_SERVER /* DNSサーバのIPアドレス */
);
if (ercd != E_OK) {
return ercd;
}
hc.http_sid = ID_SOC_HTTPC; /* ソケットID */
hc.mpf_id = ID_HTTP_MSG_MPF; /* 固定長メモリプールのID */
/*
* http_cmd_post()の中でPOSTするデータを送信しないので、
* flagのHTTPC_FLG_SND_BODY_LATERビットをセットしておく
*/
hc.flag = HTTPC_FLG_SND_BODY_LATER;
/*
* POSTのデータはファイルの内容以外のデータ(ファイル名、ヘッダ)も送る
*
* 以下送信データ
*
* --BOUNDARY\r\n
* Content-Dispsition: form-data; name="userfile"; filename="1M_bytes.bin"\r\n
* Content-Type: application/octet-stream\r\n
* \r\n
* ファイルの内容
* \r\n
* --BOUNDARY--\r\n
* ここまで送信データ
* 上記のバイト数をContent-Lengthヘッダへセットして送信するために、
* data.buflenへ上記のデータのバイト数をセットする。
*/
net_memset(&data, 0, sizeof(data));
data.buf = NULL;
net_strcpy(http_buf,
"--BOUNDARY\r\n"
"Content-Disposition: form-data; name=\"userfile\"; filename=\"1M_bytes.bin\"\r\n"
"Content-Type: application/octet-stream\r\n"
"\r\n"
);
data.buflen = net_strlen(http_buf);
data.buflen += FILE_SIZE;
data.buflen += sizeof("\r\n"
"--BOUNDARY--\r\n") - 1;
data.contenttype = "multipart/form-data; boundary=BOUNDARY";
/* Postリクエストを送信 (http_cmd_postの処理でサーバと接続する)
* flagのHTTPC_FLG_SND_BODY_LATERビットがセットされているので、
* コンテンツの送信とレスポンスの受信は行わない
*/
ercd = http_cmd_post(&hc, url, &data);
/* コンテンツ送信 (ファイルの内容の直前まで) */
ercd = http_snd(&hc, (UB*)http_buf, net_strlen(http_buf));
/* ファイルの内容を送信 */
/* データサイズが大きいので、複数回http_snd()を実行する */
net_memset(http_buf, 0x55, sizeof(http_buf));
for (i = 0; i < FILE_SIZE; i += len) {
len = FILE_SIZE - i;
if (len > sizeof(http_buf)) {
len = sizeof(http_buf);
}
ercd = http_snd(&hc, (UB *)http_buf, len);
}
/* ファイルの内容の後のデータを送信する
* \r\n
* --BOUNDARY--\r\n
*/
net_strcpy(http_buf,
"\r\n"
"--BOUNDARY--\r\n");
ercd = http_snd(&hc, (UB *)http_buf, net_strlen(http_buf));
/* レスポンス(ステータスラインとヘッダ)を受信 */
ercd = http_rcv_status(&hc);
/* サーバから送られコードを表示 */
shell_printf(ctrl, "\r\n");
shell_printf(ctrl, "code = %d\r\n", hc.response.code);
/* サーバから送信されるコンテンツを受信 */
/* 受信関数の中身はサンプルコードのファイルを参照。
*/
if (hc.response.chunked) {
ercd = rcv_chunked_contents(ctrl, &hc);
} else if (hc.response.contentlen) {
ercd = rcv_contents(ctrl, &hc);
} else {
ercd = rcv_continuous_contents(ctrl, &hc);
}
/* 切断 */
http_cls(&hc);
return ercd;
}
下のファイルをサーバのhttp://192.168.0.2/test/***でアクセスできる場所へ置いてください。
ファイル名
file_upload.php
コード: 全て選択
<?php
// 4.1.0より前のPHPでは$FILESの代わりに$HTTP_POST_FILESを使用する必要
// があります。
$uploaddir = './';
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);
echo '<pre>';
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
echo "File is valid, and was successfully uploaded.\n";
} else {
echo "Possible file upload attack!\n";
}
echo 'Here is some more debugging info:';
print_r($_FILES);
echo $uploadfile;
print "</pre>";
?>
(上記のPHPスクリプトの動作確認用、PHPスクリプトと同じディレクトリへ置いてください。)
コード: 全て選択
<!-- データのエンコード方式である enctype は、必ず以下のようにしなければなりません -->
<form enctype="multipart/form-data" action="file_upload.php" method="POST">
<!-- MAX_FILE_SIZE は、必ず "file" input フィールドより前になければなりません -->
<!-- <input type="hidden" name="MAX_FILE_SIZE" value="3000000" /> -->
<!-- input 要素の name 属性の値が、$_FILES 配列のキーになります -->
このファイルをアップロード: <input name="userfile" type="file" />
<input type="submit" value="ファイルを送信" />
</form>
(PHPスクリプトを置いたディレクトリへ生成されます。)