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

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

新規登録して質問してみよう
ただいま回答率
85.48%
MFC

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

HTTP

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

Q&A

解決済

1回答

3025閲覧

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

Yussa

総合スコア26

MFC

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

HTTP

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

0グッド

0クリップ

投稿2017/10/04 06:49

編集2017/10/04 16:07

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

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

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

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

c++

1void CSendHttp::Put(CString strTarget, CString strFile) 2{ 3 4 CInternetSession *iSessionP = NULL; 5 CHttpConnection *httpConP = NULL; 6 CHttpFile* pHttpFile = NULL; 7 8 try { 9 10 iSessionP = new CInternetSession; 11 httpConP = iSessionP->GetHttpConnection(m_server, m_port, m_user, m_pass); 12 13 DWORD dwFlag = INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE; 14 15 //ヘッダ 16 CString strHeader; 17 strHeader.Append("Translate:f\r\n"); 18 strHeader.Append("Content-Type:application/octet-stream\r\n"); 19 20 21 //リクエストデータ作成 22 pHttpFile = httpConP->OpenRequest(CHttpConnection::HTTP_VERB_PUT, strTarget, NULL, 1, NULL, "HTTP/1.1", dwFlag); 23 pHttpFile->AddRequestHeaders(strHeader); 24 25 //pFile->SendRequest(); 26 27 //送信ファイル 28 char buf[2048]; 29 UINT size = sizeof(buf); 30 31 CFile* readFile = new CFile(); 32 if (!readFile->Open(strFile, CFile::modeRead)) 33 { 34 printf("ファイルオープン失敗[%s]\n", strFile); 35 } 36 37 DWORD fileLength = (DWORD)readFile->GetLength(); 38 pHttpFile->SendRequestEx(fileLength); 39 40 while(TRUE) 41 { 42 memset(&buf, 0, size); 43 UINT res = readFile->Read(buf, size); 44 if(res > 0) { 45 pHttpFile->Write(buf, res); 46 } else { 47 break; 48 } 49 } 50 51 pHttpFile->EndRequest(); //例外発生! 12032 ERROR_INTERNET_FORCE_RETRY 52 53 readFile->Close(); 54 delete readFile; 55 56 57 //レスポンス受信 58 DWORD dwStatusCode; 59 pHttpFile->QueryInfoStatusCode(dwStatusCode); 60 61 if(dwStatusCode == HTTP_STATUS_OK) 62 { 63 64 } else { 65 66 } 67 68 } catch(CInternetException* e) { 69 e->m_dwError; 70 e->ReportError(); 71 } 72 73 if (pHttpFile) { 74 pHttpFile->Close(); 75 delete pHttpFile; 76 pHttpFile = NULL; 77 } 78 79 if (httpConP) { 80 httpConP->Close(); 81 delete httpConP; 82 httpConP = NULL; 83 } 84 85 if (iSessionP) { 86 iSessionP->Close(); 87 delete iSessionP; 88 iSessionP = NULL; 89 } 90} 91 92CSendHttp sendHttp("127.0.0.1", "user", "pass", 80); 93sendHttp.Put("/DAV/ccc.docx", "c:\ccc.docx"); 94

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

c++

1    CHttpFile* pHttpFile2 = httpConP->OpenRequest(CHttpConnection::HTTP_VERB_PUT, strTarget, NULL, 1, NULL, "HTTP/1.1", dwFlag); 2 //pHttpFile2->AddRequestHeaders("ALlow: PUT"); 3 pHttpFile2->SendRequest();

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

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()相当の

C++

1pHttpFile->SendRequestEx(fileLength);

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

投稿2017/10/04 08:57

dodox86

総合スコア9183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Yussa

2017/10/04 16:10 編集

ご回答いただきありがとうございます。 エラーキャッチ後に再実行してみましたが、再度同じエラーが出ました。 EndRequestのみの再実行ではエラーは出ませんでしたが、送信はされませんでした。 if(e->m_dwError == ERROR_INTERNET_FORCE_RETRY) { pHttpFile->SendRequestEx(fileLength); pHttpFile->EndRequest(); } ただ、参考にいただいた記事等をみると認証の影響の可能性がある様でしたので これの実行前に同一のセッションで空のPUTを実施したところ、送信が成功しました。 pHttpFile2->SendRequest 本文に補足いたしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問