トップ回答者
MFCでPHPファイル経由でアップロード(HTTP)

質問
-
あぱるといいます。
MFCのクラスを使用しHTTP通信を行いたいのですが、
うまく行かず、先週から悩んでおります。
////////////////////////////////////////////////////////////////////////////////////
環境
WindowsXP SP3
VisualStudio2005
C++(MFC)
////////////////////////////////////////////////////////////////////////////////////
詳細
サーバにあるPHPにアクセスし、・アップロード先のフォルダ名
・自分のアカウント名・ファイルのバイナリデータ
の3つデータを送ろうとしています。
下のソースは正常に動作しているダウンロードと同じHTTP接続を用いています。
////////////////////////////////////////////////////////////////////////////////////
ソース
//変数定義
CString url = "http://・・・upload.php"CString sServer, sObject, sTemp, sHeader, sReq;
INTERNET_PORT nPort;
DWORD dwServiceType;
CHttpConnection *pConn;
//~コネクト
CInternetSession cSession(HTTPPOST);
::AfxParseURL( url , dwServiceType, sServer, sObject, nPort );
pConn = cSession.GetHttpConnection( sServer, INTERNET_FLAG_SECURE, nPort, "account", "password" );pFile = pConn->OpenRequest( _T("POST"), sObject );
//ヘッダ
sHeader = " Content-Type: \"multipart/formdata\" boundary=-----------------------------7d11dc24268052c"
//ボディ
sReq = "Content-Length: 3556\r\n";
sReq+="-----------------------------7d11dc24268052c\r\n";sReq+="Content-Disposition: form-data; name=\"foldername\"\r\n";
sReq+="testfolder"
sReq+="\r\n-----------------------------7d11dc24268052c\r\n\r\n";
sReq+="Content-Disposition: form-data; name=\"account\"\r\n";
sReq+="account";
sReq+="\r\n-----------------------------7d11dc24268052c\r\n\r\n";
sReq+="Content-Disposition: form-data; name=\"data\"; filename=\"C:\\test.txt\"\r\n";sReq+="Content-Type: text/plain\r\n\r\n";
sReq+="バイナリデータ・・・・・";sReq+="\r\n\r\n";
sReq+="-----------------------------7d11dc24268052c--";
pFile->SendRequest( sHeader, (LPVOID)((LPCTSTR)sReq), sReq.GetLength());
//↓※200ではなく87を返しCInternetExceptionに入ります。
pFile->QueryInfoStatusCode( dwStatus );
・
・
////////////////////////////////////////////////////////////////////////////////////
ヘッダに"Content-type: application/x-www-form-urlencoded"を指定するとアップロードはできないものの
PHPからのレスポンスは返ってきます。
ヘッダに付加情報(ファイルのデータ、ファイルのパス)を付けたいのですがうまくいきません。
宜しくお願いします。
回答
-
こんにちは。
試してないのでこれが原因なのかどうかはわかりませんが、コードを見て気付いたところだけとりあえずお伝えしますと。。。
Content-Type → multipart/form-data でしょうか?
それから、バウンダリの指定が微妙に違うのではないかと思います。
boundary の文字そのままをバウンダリにしていらっしゃるようですが、
例えば boundary="ABC" としたら、実際のバウンダリは
...
--ABC
...
--ABC
...
--ABC--
のようになります。
# IE が、確かに -- をたくさん含むバウンダリを作るんですよね。
ご参考になりましたら幸いです。
-----------------------------------------
だどさん http://keicode.com/
- 回答としてマーク sk7474 2009年2月3日 9:42
すべての返信
-
こんにちは。
試してないのでこれが原因なのかどうかはわかりませんが、コードを見て気付いたところだけとりあえずお伝えしますと。。。
Content-Type → multipart/form-data でしょうか?
それから、バウンダリの指定が微妙に違うのではないかと思います。
boundary の文字そのままをバウンダリにしていらっしゃるようですが、
例えば boundary="ABC" としたら、実際のバウンダリは
...
--ABC
...
--ABC
...
--ABC--
のようになります。
# IE が、確かに -- をたくさん含むバウンダリを作るんですよね。
ご参考になりましたら幸いです。
-----------------------------------------
だどさん http://keicode.com/
- 回答としてマーク sk7474 2009年2月3日 9:42
-
だとさん、返信ありがとうございます。
バウンダリの設定を修正するとうまく動作しました!
ありがとうございます!!
よろしければもう一点教えていただきたいことがあるのですが、
(件名とは異なってしまうのですが、)
ローカル上にあるファイルをアップロードしたいので
テキストデータとバイナリデータを連結しようとしています。
しかし2つのデータを連結できずに困っています。
下にソースを載せます。
char *data;
data = (char *)malloc(filesize + 10000);
strcpy(data, "-------------------------------7e11dc24268052c\r\n");
strcat(data, "Content-Disposition: form-data; name=\"folder_id\"\r\n");
strcat(data, "\r\n");
strcat(data, "100");
strcat(data, "\r\n");
strcat(data, "-------------------------------7e11dc24268052c\r\n");
strcat(data, "Content-Disposition: form-data; name=\"data\"; filename=\"");
strcat(data, (LPCSTR)localPass);
strcat(data, "\"\r\n");
strcat(data, "Content-Type: application/x-www-form-urlencoded\r\n\r\n");
strcat(data, "\r\n");
//ローカルの○○データをバイナリ読み込み
FILE *fp;
char fdata[10000];
fdata[0] = NULL;
size_t size;
size_t i;
fp = fopen( localPass, "rb" );if( fp == NULL ){ return 1; }
size = fread( fdata, 1, 10000, fp );
fclose(fp);
int len = strlen(data);memcmp(&data[len], fdata, size); //←ここの連結がうまくいかない
strcat(data, "\r\n");
strcat(data, "-------------------------------7e11dc24268052c--\r\n");free(data);
以上です。 -
こんにちは。
うまく行ってよかったです!
別件につきましては、後からみたときにわかりやすい+他の方も質問を見つけやすいので、
別スレッドにしたほうが良いと思いますよ。
# と、いいつつ、パッと見た印象で書きますと、バイナリデータを扱うときは strcat などは
# うまく機能しないと思います。バッファを取ったら、そのバッファの書き込んだバイト数を
# 覚えておき、次々 memcpy していけば速いし問題もないと思います。
# (あ、関数自体のセキュリティの問題はまた別ですが)
ご参考になりましたら幸いです。
-----------------------------------------
だどさん http://keicode.com/