none
MFCでPHPファイル経由でアップロード(HTTP) RRS feed

  • 質問

  • あぱるといいます。


    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からのレスポンスは返ってきます。
    ヘッダに付加情報(ファイルのデータ、ファイルのパス)を付けたいのですがうまくいきません。

    宜しくお願いします。


    2009年1月22日 11:04

回答

  • こんにちは。

     

    試してないのでこれが原因なのかどうかはわかりませんが、コードを見て気付いたところだけとりあえずお伝えしますと。。。

     

    Content-Type → multipart/form-data でしょうか?

     

    それから、バウンダリの指定が微妙に違うのではないかと思います。

     

    boundary の文字そのままをバウンダリにしていらっしゃるようですが、

    例えば boundary="ABC" としたら、実際のバウンダリは

     

    ...

    --ABC

    ...

    --ABC

    ...

    --ABC--

     

    のようになります。

     

    # IE が、確かに -- をたくさん含むバウンダリを作るんですよね。

     

    ご参考になりましたら幸いです。

     

    -----------------------------------------

    だどさん http://keicode.com/

     

     

    • 回答としてマーク sk7474 2009年2月3日 9:42
    2009年1月23日 16:40

すべての返信

  • こんにちは。

     

    試してないのでこれが原因なのかどうかはわかりませんが、コードを見て気付いたところだけとりあえずお伝えしますと。。。

     

    Content-Type → multipart/form-data でしょうか?

     

    それから、バウンダリの指定が微妙に違うのではないかと思います。

     

    boundary の文字そのままをバウンダリにしていらっしゃるようですが、

    例えば boundary="ABC" としたら、実際のバウンダリは

     

    ...

    --ABC

    ...

    --ABC

    ...

    --ABC--

     

    のようになります。

     

    # IE が、確かに -- をたくさん含むバウンダリを作るんですよね。

     

    ご参考になりましたら幸いです。

     

    -----------------------------------------

    だどさん http://keicode.com/

     

     

    • 回答としてマーク sk7474 2009年2月3日 9:42
    2009年1月23日 16:40
  • だとさん、返信ありがとうございます。
    バウンダリの設定を修正するとうまく動作しました!
    ありがとうございます!!

    よろしければもう一点教えていただきたいことがあるのですが、
    (件名とは異なってしまうのですが、)
    ローカル上にあるファイルをアップロードしたいので
    テキストデータとバイナリデータを連結しようとしています。
    しかし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);


    以上です。

    2009年1月24日 8:06
  • 間違いました。
    ×memcmp

    ○memcpy

    2009年1月24日 8:08
  • こんにちは。

     

    うまく行ってよかったです!

     

    別件につきましては、後からみたときにわかりやすい+他の方も質問を見つけやすいので、

    別スレッドにしたほうが良いと思いますよ。

     

    # と、いいつつ、パッと見た印象で書きますと、バイナリデータを扱うときは strcat などは

    # うまく機能しないと思います。バッファを取ったら、そのバッファの書き込んだバイト数を

    # 覚えておき、次々 memcpy していけば速いし問題もないと思います。

    # (あ、関数自体のセキュリティの問題はまた別ですが)

     

    ご参考になりましたら幸いです。

     

    -----------------------------------------

    だどさん http://keicode.com/

     

    2009年1月25日 14:43
  • >別件につきましては、後からみたときにわかりやすい+他の方も質問を見つけやすいので、

    >別スレッドにしたほうが良いと思いますよ。

     

    了解です。
    このスレッドは解決にします。

    #文を参考し試みます。
    行き詰まった場合、別スレッドで質問してみます。


    だとさん本当にありがとうございました。

    2009年1月26日 1:40
  • こんにちは。中川俊輔です。

    だどさん、回答ありがとうございます。

    あぱるさん、フォーラムのご利用ありがとうございます。
    有用な情報と思われたため、だどさんの回答へ回答済みチェックをつけさせていただきました。

    今後ともフォーラムをよろしくお願いします。
    それでは!
    マイクロソフト株式会社 フォーラム オペレータ 中川 俊輔
    2009年2月3日 9:44