質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.61%

  • HTTP

    531questions

    HTTP(Hypertext Transfer Protocol)とはweb上でHTML等のコンテンツを交換するために使われるアプリケーション層の通信プロトコルです。

  • MFC

    118questions

    MFC (Microsoft Fouondation Class)とは、MicrosoftがVC++用に開発したWindows用アプリケーションのフレームワークです。

MFCでのWEBDAVへのPUT(アップロード)に失敗する

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 434

Yussa

score 13

MFCでWindowsアプリを作成しています。
WindowsサーバのWEBDAV機能をつかって、
ファイルアップロードしようとしていますが、
エラーが発生しますが原因が分かりません。
発生場所は下記ソースのpHttpFile->EndRequest()になります。
エラー内容はリトライしてくださいという内容のもので意味が分かりません。

サーバ側はWindows認証を設定しております。
フリーのWEBDAVクライアントではなんとかアップできるので、実装の問題ではないかと思っていますが、見様見真似で作ったサーバなので認証など設定の問題がある可能性もあります。
ただGET、DELETEも別途実装していますがこちらは問題なく動作しています。

下記のソースは、ローカル"c:\\ccc.docx"→ サーバ "/DAV/ccc.docx" にアップロードする実装になります。

宜しくお願いいたします。

void CSendHttp::Put(CString strTarget, CString strFile)
{

    CInternetSession *iSessionP = NULL;
    CHttpConnection *httpConP = NULL;
    CHttpFile* pHttpFile = NULL;

    try {

        iSessionP = new CInternetSession;
        httpConP = iSessionP->GetHttpConnection(m_server, m_port, m_user, m_pass);

        DWORD dwFlag = INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE;

        //ヘッダ
        CString strHeader;
        strHeader.Append("Translate:f\r\n");
        strHeader.Append("Content-Type:application/octet-stream\r\n");


        //リクエストデータ作成
        pHttpFile = httpConP->OpenRequest(CHttpConnection::HTTP_VERB_PUT, strTarget, NULL, 1, NULL, "HTTP/1.1", dwFlag);
        pHttpFile->AddRequestHeaders(strHeader);

        //pFile->SendRequest();

        //送信ファイル
        char buf[2048];
        UINT size = sizeof(buf);

        CFile* readFile = new CFile();
        if (!readFile->Open(strFile, CFile::modeRead))
        {
            printf("ファイルオープン失敗[%s]\n", strFile);
        }

        DWORD fileLength = (DWORD)readFile->GetLength();
        pHttpFile->SendRequestEx(fileLength);

        while(TRUE)
        {
            memset(&buf, 0, size);
            UINT res = readFile->Read(buf, size);
            if(res > 0) {
                pHttpFile->Write(buf, res);
            } else {
                break;
            }
        }

        pHttpFile->EndRequest(); //例外発生! 12032 ERROR_INTERNET_FORCE_RETRY   

        readFile->Close();
        delete readFile;


        //レスポンス受信
        DWORD dwStatusCode;
        pHttpFile->QueryInfoStatusCode(dwStatusCode);

        if(dwStatusCode == HTTP_STATUS_OK)
        {

        } else {

        }

    } catch(CInternetException* e) {
        e->m_dwError;
        e->ReportError();
    }

    if (pHttpFile) {
        pHttpFile->Close();
        delete pHttpFile;
        pHttpFile = NULL;
    }

    if (httpConP) {
        httpConP->Close();
        delete httpConP;
        httpConP = NULL;
    }

    if (iSessionP) {
        iSessionP->Close();
        delete iSessionP;
        iSessionP = NULL;
    }
}

CSendHttp sendHttp("127.0.0.1", "user", "pass", 80);
sendHttp.Put("/DAV/ccc.docx", "c:\\ccc.docx");

2017/10/5 補足
Fiddlerでフリーソフトをモニターしたのをヒントに、
一つ目のOpenRequestの前に、下記を追加するとうまく動作しました。

    CHttpFile* pHttpFile2 = httpConP->OpenRequest(CHttpConnection::HTTP_VERB_PUT, strTarget, NULL, 1, NULL, "HTTP/1.1", dwFlag);
        //pHttpFile2->AddRequestHeaders("ALlow: PUT");
        pHttpFile2->SendRequest();
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

下記のリンクの情報をご覧ください。

ERROR_INTERNET_FORCE_RETRY

FORCE_RETRY means that WinInet wants you to resend the request. That is,
simply 'goto' back to your HttpSendRequest[Ex] call and resend the same
request using the same HTTP request handle.

とのことなので、WinINetのHttpSendRequestEx()相当の

pHttpFile->SendRequestEx(fileLength);


の部分を同じコネクションのまま再試行すると正常に完了するかもしれません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/05 01:01 編集

    ご回答いただきありがとうございます。
    エラーキャッチ後に再実行してみましたが、再度同じエラーが出ました。
    EndRequestのみの再実行ではエラーは出ませんでしたが、送信はされませんでした。

    if(e->m_dwError == ERROR_INTERNET_FORCE_RETRY) {
    pHttpFile->SendRequestEx(fileLength);
    pHttpFile->EndRequest();
    }

    ただ、参考にいただいた記事等をみると認証の影響の可能性がある様でしたので
    これの実行前に同一のセッションで空のPUTを実施したところ、送信が成功しました。
    pHttpFile2->SendRequest
    本文に補足いたしました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.61%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • HTTP

    531questions

    HTTP(Hypertext Transfer Protocol)とはweb上でHTML等のコンテンツを交換するために使われるアプリケーション層の通信プロトコルです。

  • MFC

    118questions

    MFC (Microsoft Fouondation Class)とは、MicrosoftがVC++用に開発したWindows用アプリケーションのフレームワークです。