質問編集履歴

7

コマンドプロンプトから実行してみると成功しました。VC++のコードからだと失敗してしまいます。

2023/11/22 07:56

投稿

cosmori-man
cosmori-man

スコア2

test CHANGED
File without changes
test CHANGED
@@ -186,7 +186,8 @@
186
186
  ### 【現状の原因調査結果】
187
187
  TestFuncでは文字化けせず、PushMessageでは文字化けしてしまう理由がよくわかりません。
188
188
 
189
- ヘッダーを application/jsonするか、text/plainするかで文字化けが起こっている感じです。
189
+ ちなみにコマンドプロンプトから同じjson文字列のデータをポストすると文字化けもなく、成功します。
190
+ 例)curl -X POST -H "Content-Type: application/json" -d @iOSNotifyInfo.json "http://192.168.1.175:80/ApnsPushServerDebug/API/PushMsg" -v
190
191
 
191
192
  ### 補足情報(FW/ツールのバージョンなど)
192
193
  【開発環境】

6

誤字

2023/11/22 05:59

投稿

cosmori-man
cosmori-man

スコア2

test CHANGED
File without changes
test CHANGED
@@ -62,13 +62,13 @@
62
62
  HTTPBody:同様
63
63
 
64
64
  これを実行してデバックすると、
65
- postData :{"userNo":37,"member":[12],"appId":"astrostage.AstroTalk","title":"新規メッセージ","message":"新規のメッセージがあります。","category":"comment","detail":{"commentId":19802,"talkId":21},"sound":"default"}
65
+ postData :{"userNo":37,"member":[12],"appId":"アプリ識別用ID","title":"新規メッセージ","message":"新規のメッセージがあります。","category":"comment","detail":{"commentId":19802,"talkId":21},"sound":"default"}
66
66
  となり文字化け等起こらず、成功しました。
67
67
  サーバーログでも確認済みです。
68
68
 
69
69
  ### MFC側POST処理
70
70
  ```C++
71
- BOOL CNazcaWebDisk::NotifyiOS( CString strConnectString, CString strBody )
71
+ BOOL NotifyiOS( CString strConnectString, CString strBody )
72
72
  {
73
73
  // jsonファイル読み取り
74
74
  CString strLocalTextFullPath = _T( "jsonファイルのパス" );

5

テスト用関数の修正

2023/11/22 04:25

投稿

cosmori-man
cosmori-man

スコア2

test CHANGED
File without changes
test CHANGED
@@ -48,16 +48,11 @@
48
48
  検証用にPOSTされた文字列を受け取って、そのまま返すだけのAPIを用意して検証してみた。↓
49
49
  ```C#
50
50
  [HttpPost("TestFunc")]
51
- public string TestFunc()
51
+ public string TestFunc([FromBody] string value)
52
52
  {
53
53
  var postData = "";
54
- using (var reader = new System.IO.StreamReader(HttpContext.Request.Body))
55
- {
56
- postData = reader.ReadToEnd();
54
+ postData = value;
57
- // Process the post data as needed
58
- // ...
59
- Logger.log(Logger.INFO, " postData :" + postData, true);
55
+ Logger.log(Logger.INFO, " postData :" + postData, true);
60
- }
61
56
 
62
57
  return postData != null ? postData : "no post body";
63
58
  }
@@ -190,8 +185,8 @@
190
185
 
191
186
  ### 【現状の原因調査結果】
192
187
  TestFuncでは文字化けせず、PushMessageでは文字化けしてしまう理由がよくわかりません。
193
- PushMessageの引数でBodyの内容を受け取るのですが、その引数の型がSystem::Stringでこちら調べたところ、UTF-16 を扱うようでした。
188
+
194
- ただ、HTTPヘッダー "application/json"を指定した段階エンコーディングUTF-8に決まってしまうため、MFC(C++)側エンコーディングの形式をUTF-16で指定しても結果が変わりませんでした
189
+ ヘッダー application/jsonとするか、text/plainとするか文字化け起こっている感じ
195
190
 
196
191
  ### 補足情報(FW/ツールのバージョンなど)
197
192
  【開発環境】

4

テスト用APIの文字化けは改善されましたが、問題の目的のAPIでは相変わらず、文字化けしてしまします。

2023/11/22 01:14

投稿

cosmori-man
cosmori-man

スコア2

test CHANGED
File without changes
test CHANGED
@@ -34,19 +34,18 @@
34
34
 
35
35
  で上記APIにjson形式の文字列をPOSTしたい
36
36
 
37
-
38
37
  ### 発生している問題・エラーメッセージ
39
38
  ```
40
39
  System.Text.DecoderFallbackException: Unable to translate bytes [82][DC] at index 116 from specified code page to Unicode.……
41
40
  ```
42
41
 
43
- ### 検証内容
44
42
  Header: application/json; charset=UNICODE
45
43
  とすると、API/PushMsgにたどり着いて文字列を渡すことができるが、
46
44
  引数で受け取る文字列が文字化けしてしまった。
47
45
  例)≻獵牥潎㨢㜳∬敭扭牥㨢ㅛ崲∬灡䥰≤∺獡牴獯慴敧䄮瑳潲慔歬Ⱒ琢瑩敬㨢丢睥敍獳条≥∬敭獳条≥∺潙⁵慨敶愠丠睥䴠獥慳敧∮∬慣整潧祲㨢挢浯敭瑮Ⱒ搢瑥楡≬笺挢浯敭瑮摉㨢㤱㠶ⰰ琢污䥫≤㈺紱∬潳湵≤∺敤慦汵≴}
48
46
 
47
+ ### 試したこと
49
- そこで検証用にPOSTされた文字列を受け取って、そのまま返すだけのAPIを用意して検証してみた。↓
48
+ 検証用にPOSTされた文字列を受け取って、そのまま返すだけのAPIを用意して検証してみた。↓
50
49
  ```C#
51
50
  [HttpPost("TestFunc")]
52
51
  public string TestFunc()
@@ -68,44 +67,53 @@
68
67
  HTTPBody:同様
69
68
 
70
69
  これを実行してデバックすると、
71
- {"userNo":37,"member":[12],"appId":"製品識別用ID","title":"�V�K���b�Z�[�W","message":"�V�K�̃��b�Z�[�W������܂��B","category":"comment","detail":{"commentId":19674,"talkId":21},"sound":"default"}
70
+ postData :{"userNo":37,"member":[12],"appId":"astrostage.AstroTalk","title":"新規メッセージ","message":"新規のメッセージがあります。","category":"comment","detail":{"commentId":19802,"talkId":21},"sound":"default"}
72
- 上記のように、漢字平仮名部分のみが文字化けしてしいました。
71
+ となり文字化け等起こらず、成功しました。
72
+ サーバーログでも確認済みです。
73
73
 
74
74
  ### MFC側POST処理
75
75
  ```C++
76
+ BOOL CNazcaWebDisk::NotifyiOS( CString strConnectString, CString strBody )
76
77
  {
77
- // 一部省略
78
+ // jsonファイル読み取り
79
+ CString strLocalTextFullPath = _T( "jsonファイルのパス" );
80
+
81
+ // 文字コード指定してファイルから読み取り
82
+ strBody = _T( "" );
83
+ FILE *pFile;
84
+ fopen_s( &pFile, CT2A( strLocalTextFullPath ), "r, ccs=UTF-8" );
78
- CString strURL = _T( "http://IPアドレス:ポート番号/サーバー名/API/PushMsg" );
85
+ //fopen_s( &pFile, CT2A( strLocalTextFullPath ), "r, ccs=UTF-16LE" );
86
+ if ( NULL != pFile ) {
87
+ CStdioFile file( pFile );
79
- CString strBody;
88
+ CString strJsonText;
80
- strBody.Format( _T( "{\"userNo\":%d,\"member\":[%s],\"appId\":\"%s\",\"title\":\"%s\",\"message\":\"%s\",\"category\":\"%s\",\"detail\":{%s},\"sound\":\"%s\"}" )
81
- ,nSendOwnerNo, strReceiveMem, strAppID, strTitle, strMessage, strCategory, strDetail, strSound );
89
+ while ( file.ReadString( strJsonText ) ) {
82
-
90
+ TRACE( L"%s\n", strJsonText );
83
- NotifyiOS( strURL, strBody );
91
+ strBody = strJsonText;
84
-
85
-
86
-
87
-
88
-
89
- // クラスのコンストラクタ等を通ったのち、以下が呼ばれます
90
- SyncHttpPost(strServer, strObject, nPort, m_strHeader, m_pPostData, m_nPostData, dwServiceType);
91
-
92
- }
92
+ }
93
-
94
- BOOL NotifyiOS( CString strConnectString, CString strBody )
93
+ file.Close( );
95
- {
94
+ }
95
+ fclose( pFile );
96
+
97
+ // バッファ確保、データコピー
96
- DWORD nBuff = strBody.GetLength() * 3;
98
+ DWORD nBuff = strBody.GetLength() * sizeof( TCHAR );
97
99
  char *pBuff = NULL;
98
100
  pBuff = (char *)malloc( nBuff );
101
+ if ( NULL == pBuff ) {
99
- // 省略
102
+ return FALSE;
100
-
103
+ }
101
- strcpy_s( pBuff, nBuff, CT2A( strBody ) );
104
+ strcpy_s( pBuff, nBuff, CT2A( strBody, CP_UTF8 ) );
105
+ strcpy_s( pBuff, nBuff, CT2A( strBody ) ); // こうするとTestFuncで文字化け
102
106
 
103
107
  CString strURL = strConnectString;
108
+
104
109
  CString strHttpRes;
105
110
  int nResult = -1;
106
- nResult = HttpiOSNotify( strHttpRes, CT2A( strURL ), pBuff, nBuff, 300000 );
111
+ nResult = HttpiOSNotify( strHttpRes, CT2A( strURL ), pBuff, nBuff, 300000 ); // POST
112
+
107
-
113
+ if ( 0 > nResult ) {
108
- // 省略
114
+ free( pBuff );
115
+ return FALSE;
116
+ }
109
117
 
110
118
  free( pBuff );
111
119
  return TRUE;
@@ -115,20 +123,26 @@
115
123
  {
116
124
  int nRet;
117
125
  CActiveBuffer Buff;
126
+
118
127
  if ( FALSE == Buff.Init( 32768, 32768 ) ) return 0;
119
128
 
120
129
  nRet = HttpiOSNotify( Buff, szURL, pData, nData, Timeout, szProxyServer, szProxyUser, szProxyPassword );
130
+ if ( 1 > nRet ) {
121
- // 省略
131
+ Buff.Close( );
132
+ return nRet;
133
+ }
122
134
 
123
135
  Buff.Add( "\0", 1 );
124
136
 
125
137
  csRet = (char *)Buff.DataP();
126
138
  Buff.Close( );
139
+
127
140
  return nRet;
128
141
  }
129
142
 
130
143
  int HttpiOSNotify( CActiveBuffer &Buff, const char *szURL, void *pData, int nData, DWORD Timeout, const char *szProxyServer, const char *szProxyUser, const char *szProxyPassword )
131
144
  {
145
+ char szWork[ 512 ];
132
146
  DWORD Timeout2;
133
147
  CWinInetHttpThread *thHttpGet;
134
148
  CString strHeader;
@@ -139,13 +153,12 @@
139
153
  Timeout2 = Timeout / 2;
140
154
  if ( 30000 > Timeout2 ) Timeout2 = 30000;
141
155
 
156
+ //strHeader = _T( "" ); // ヘッダー指定なし
142
- strHeader = _T( "Content-Type: application/json\r\n" ); // 失敗するがこれで動かないといけないのでは。jsonだから。
157
+ strHeader = _T( "Content-Type: application/json\n" ); // ×
143
- //strHeader = _T( "Content-Type: application/json;charset=UTF-8\r\n" ); // 失敗するがこれで動かないといけないのでは。jsonだから。Encodingの指定は冗長
158
+ //strHeader = _T( "Content-Type: application/json; charset=UTF-8\r\n" ); // ×
144
- //strHeader = _T( "Content-Type: application/json;charset=UNICODE\r\n" ); // 〇
159
+ //strHeader = _T( "Content-Type: application/json; charset=UNICODE\r\n" ); // 〇
145
- //strHeader = _T( "Content-Type: application/json;charset=UTF-16\r\n" ); // 〇
160
+ //strHeader = _T( "Content-Type: application/json; charset=UTF-16\r\n" ); // 〇
146
- //strHeader = _T( "Content-Type: application/json;charset=Shift-jis\r\n" ); // ×
147
-
148
- //strHeader = _T( "Content-Type: text/plain\r\n" ); // TestFunc用 日本語のみ化ける
161
+ //strHeader = _T( "Content-Type: text/plain\r\n" ); // TestFunc用
149
162
 
150
163
  Body.Add( pData, (DWORD)nData );
151
164
 
@@ -161,159 +174,24 @@
161
174
 
162
175
  thHttpGet->WaitForEndThread( );
163
176
 
177
+ if ( true == thHttpGet->GetErrInfo( )->IsError( ) ) {
178
+ int nErr = thHttpGet->GetErrInfo( )->ErrCode( );
179
+ delete thHttpGet;
164
- // 省略
180
+ Body.Close( );
181
+ return -nErr;
182
+ }
183
+
165
184
  delete thHttpGet;
166
185
  return (int)Buff.GetLength( );
167
186
  }
168
187
 
169
- bool CWinInetHttp::SyncHttpPost(LPCTSTR lpszHostAddress, LPCTSTR pszObjectName, UINT nHostPort, LPCTSTR pszHeader, LPVOID pPostData, int nPostData ,DWORD dwServiceType)
170
- {
171
- if (!syncHttpRequestAndResponse(
172
- lpszHostAddress,
173
- pszObjectName,
174
- nHostPort,
175
- _T("POST"),
176
- pszHeader,
177
- pPostData,
178
- nPostData,
179
- dwServiceType)) {
188
+ その他一般的なHTTPセッション処理
180
- return false;
181
- }
182
-
183
- return true;
184
- }
185
-
186
- bool CWinInetHttp::syncHttpRequestAndResponse(
187
- LPCTSTR lpszHostAddress,
188
- LPCTSTR pszObjectName,
189
- UINT nHostPort,
190
- LPCTSTR pszVerb,
191
- LPCTSTR pszContentType,
192
- LPVOID pPostData,
193
- int nPostData,
194
- DWORD dwServiceType)
195
- {
196
- ::ResetEvent(m_hEventCancel);
197
- m_dwStatusCode = 0;
198
- m_bAllDone = false;
199
- bool bSuccess = false;
200
-
201
- // First call that will actually complete asynchronously even
202
- // though there is no network traffic
203
-
204
- m_hInetConnect = ::InternetConnect(
205
- m_hInternet, // HINTERNET hInternet,
206
- lpszHostAddress, // LPCTSTR lpszServerName
207
- nHostPort, // INTERNET_PORT nServerPort
208
- NULL, // LPCTSTR lpszUsername
209
- NULL, // LPCTSTR lpszPassword
210
- INTERNET_SERVICE_HTTP, // DWORD dwService
211
- 0, // DWORD dwFlags
212
- 0); // DWORD_PTR dwContext
213
-
214
- if (m_hInetConnect == NULL) {
215
- // 省略
216
- }
217
-
218
- VERIFY(INTERNET_INVALID_STATUS_CALLBACK != ::InternetSetStatusCallback(m_hInetConnect, (INTERNET_STATUS_CALLBACK)myInternetCallback));
219
- // Creates an HTTP request handle
220
-
221
- DWORD dwFlags = INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE;
222
- if (dwServiceType == AFX_INET_SERVICE_HTTPS) {
223
-
224
- dwFlags |= INTERNET_FLAG_SECURE;
225
- dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;
226
- dwFlags |= SECURITY_FLAG_IGNORE_CERT_CN_INVALID;
227
- dwFlags |= SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;
228
- dwFlags |= SECURITY_FLAG_IGNORE_REDIRECT_TO_HTTP;
229
- dwFlags |= SECURITY_FLAG_IGNORE_REDIRECT_TO_HTTPS;
230
- }
231
-
232
- m_hInetRequest = NULL;
233
- m_hInetRequest = ::HttpOpenRequest(
234
- m_hInetConnect, // HINTERNET hConnect
235
- pszVerb, // LPCTSTR lpszVerb
236
- pszObjectName, // LPCTSTR lpszObjectName
237
- NULL, // LPCTSTR lpszVersion
238
- NULL, // LPCTSTR lpszReferer
239
- NULL, // LPCTSTR* lpszAcceptTypes
240
- dwFlags, // DWORD dwFlags
241
- (DWORD)this); // DWORD_PTR dwContext
242
-
243
- if (m_hInetRequest == NULL) {
244
- // 省略
245
- }
246
-
247
- // Sends the specified request to the HTTP server
248
- const int nContentTypeLen = pszContentType ? strlen(CT2A(pszContentType)) : 0;
249
- const int nPostDataLen = pPostData ? nPostData : 0;
250
-
251
- if (!::HttpSendRequest(
252
- m_hInetRequest, // HINTERNET hRequest
253
- pszContentType, // LPCTSTR lpszHeaders
254
- nContentTypeLen, // DWORD dwHeadersLength
255
- pPostData, // LPVOID lpOptional
256
- nPostDataLen)) { // DWORD dwOptionalLength
257
-
258
- //オリジナル
259
- if (!checkIoPending(::GetLastError(), CErrInfo::errSend, _T("HttpSendRequest failed"))) {
260
- // 省略
261
- }
262
-
263
- } else if (IsCanceled()) {
264
- // 省略
265
- return bSuccess;
266
- }
267
-
268
- {
269
- CMyTimer timerSend(m_timeoutSend);
270
- if (!waitForAsyncOperation(&timerSend, m_hEventRequestComplete)) {
271
- // 省略
272
- }
273
- }
274
-
275
- // Reads data from a handle opened by the InternetOpenUrl or HttpOpenRequest function.
276
- while (!m_bAllDone) {
277
- CByteArray bufRecv;
278
- bufRecv.SetSize(4096, 0);
279
-
280
- INTERNET_BUFFERS inetBuf;
281
- ::ZeroMemory(&inetBuf, sizeof(inetBuf));
282
- inetBuf.dwStructSize = sizeof(inetBuf);
283
- inetBuf.lpvBuffer = bufRecv.GetData();
284
- inetBuf.dwBufferLength = bufRecv.GetSize();
285
-
286
- if (!::InternetReadFileEx(
287
- m_hInetRequest, // HINTERNET hFile
288
- &inetBuf, // LPINTERNET_BUFFERS lpBuffersOut
289
- 0, // DWORD dwFlags
290
- (DWORD)this)) { // DWORD dwContext
291
- if (!checkIoPending(::GetLastError(), CErrInfo::errReceive, _T("InternetReadFileEx failed"))) {
292
- // 省略
293
- return bSuccess;
294
- }
295
-
296
- // 省略
297
- }
298
-
299
- {
300
- char szStatus[256] = { 0 };
301
- DWORD dwSize = sizeof(szStatus) - 1;
302
- if (::HttpQueryInfo(m_hInetRequest, HTTP_QUERY_STATUS_CODE, szStatus, &dwSize, NULL)) {
303
- m_dwStatusCode = atoi(szStatus); // APIにPOSTできたときはszStatus=2、失敗したときは5
304
- }
305
- }
306
- return bSuccess;
307
- }
308
-
309
-
310
- ```
189
+ ```
311
-
190
+
312
- ### 【現状の原因調査結果・考察
191
+ ### 【現状の原因調査結果】
192
+ TestFuncでは文字化けせず、PushMessageでは文字化けしてしまう理由がよくわかりません。
193
+ PushMessageの引数でBodyの内容を受け取るのですが、その引数の型がSystem::Stringでこちら調べたところ、UTF-16 を扱うようでした。
313
- ・そもそもHeaderにて、application/jsonを指定した時点エンコーディングUTF-8で実行されるとい認識のため、HeaderContent-Typecharsetの指定は不要なのではないかと考え
194
+ ただ、HTTPヘッダーで "application/json"を指定した段階でエンコーディングUTF-8に決まってしまうため、MFC(C++)側でエンコーディング形式をUTF-16で指定も結果が変わりせんでした
314
- ちなみに、charset=UTF8などいくつか試したが、APIを呼べたのはcharset=UNICODEとcharset=UTF-16のみでした(いずれも渡した文字列は文字化け)。
315
-
316
- ・漢字平仮名の文字化けの様子を見るに、Shift-JisからUTF-8に変換した際の文字化けと思われます。
317
195
 
318
196
  ### 補足情報(FW/ツールのバージョンなど)
319
197
  【開発環境】

3

タグの変更

2023/11/16 09:00

投稿

cosmori-man
cosmori-man

スコア2

test CHANGED
File without changes
test CHANGED
File without changes

2

MFC側のPOST処理を追記しました。

2023/11/16 08:08

投稿

cosmori-man
cosmori-man

スコア2

test CHANGED
File without changes
test CHANGED
@@ -71,6 +71,244 @@
71
71
  {"userNo":37,"member":[12],"appId":"製品識別用ID","title":"�V�K���b�Z�[�W","message":"�V�K�̃��b�Z�[�W������܂��B","category":"comment","detail":{"commentId":19674,"talkId":21},"sound":"default"}
72
72
  上記のように、漢字平仮名部分のみが文字化けしてしまいました。
73
73
 
74
+ ### MFC側POST処理
75
+ ```C++
76
+ {
77
+ // 一部省略
78
+ CString strURL = _T( "http://IPアドレス:ポート番号/サーバー名/API/PushMsg" );
79
+ CString strBody;
80
+ strBody.Format( _T( "{\"userNo\":%d,\"member\":[%s],\"appId\":\"%s\",\"title\":\"%s\",\"message\":\"%s\",\"category\":\"%s\",\"detail\":{%s},\"sound\":\"%s\"}" )
81
+ ,nSendOwnerNo, strReceiveMem, strAppID, strTitle, strMessage, strCategory, strDetail, strSound );
82
+
83
+ NotifyiOS( strURL, strBody );
84
+
85
+
86
+
87
+
88
+
89
+ // クラスのコンストラクタ等を通ったのち、以下が呼ばれます
90
+ SyncHttpPost(strServer, strObject, nPort, m_strHeader, m_pPostData, m_nPostData, dwServiceType);
91
+
92
+ }
93
+
94
+ BOOL NotifyiOS( CString strConnectString, CString strBody )
95
+ {
96
+ DWORD nBuff = strBody.GetLength() * 3;
97
+ char *pBuff = NULL;
98
+ pBuff = (char *)malloc( nBuff );
99
+ // 省略
100
+
101
+ strcpy_s( pBuff, nBuff, CT2A( strBody ) );
102
+
103
+ CString strURL = strConnectString;
104
+ CString strHttpRes;
105
+ int nResult = -1;
106
+ nResult = HttpiOSNotify( strHttpRes, CT2A( strURL ), pBuff, nBuff, 300000 );
107
+
108
+ // 省略
109
+
110
+ free( pBuff );
111
+ return TRUE;
112
+ }
113
+
114
+ int HttpiOSNotify( CString &csRet, const char *szURL, void *pData, int nData, DWORD Timeout, const char *szProxyServer, const char *szProxyUser, const char *szProxyPassword )
115
+ {
116
+ int nRet;
117
+ CActiveBuffer Buff;
118
+ if ( FALSE == Buff.Init( 32768, 32768 ) ) return 0;
119
+
120
+ nRet = HttpiOSNotify( Buff, szURL, pData, nData, Timeout, szProxyServer, szProxyUser, szProxyPassword );
121
+ // 省略
122
+
123
+ Buff.Add( "\0", 1 );
124
+
125
+ csRet = (char *)Buff.DataP();
126
+ Buff.Close( );
127
+ return nRet;
128
+ }
129
+
130
+ int HttpiOSNotify( CActiveBuffer &Buff, const char *szURL, void *pData, int nData, DWORD Timeout, const char *szProxyServer, const char *szProxyUser, const char *szProxyPassword )
131
+ {
132
+ DWORD Timeout2;
133
+ CWinInetHttpThread *thHttpGet;
134
+ CString strHeader;
135
+ CActiveBuffer Body;
136
+
137
+ if ( FALSE == Body.Init( 131072, 131072 ) ) return -1;
138
+
139
+ Timeout2 = Timeout / 2;
140
+ if ( 30000 > Timeout2 ) Timeout2 = 30000;
141
+
142
+ strHeader = _T( "Content-Type: application/json\r\n" ); // 失敗するがこれで動かないといけないのでは。jsonだから。
143
+ //strHeader = _T( "Content-Type: application/json;charset=UTF-8\r\n" ); // 失敗するがこれで動かないといけないのでは。jsonだから。Encodingの指定は冗長
144
+ //strHeader = _T( "Content-Type: application/json;charset=UNICODE\r\n" ); // 〇
145
+ //strHeader = _T( "Content-Type: application/json;charset=UTF-16\r\n" ); // 〇
146
+ //strHeader = _T( "Content-Type: application/json;charset=Shift-jis\r\n" ); // ×
147
+
148
+ //strHeader = _T( "Content-Type: text/plain\r\n" ); // TestFunc用 日本語のみ化ける
149
+
150
+ Body.Add( pData, (DWORD)nData );
151
+
152
+ thHttpGet = new CWinInetHttpThread( CString( szURL ), Timeout2, Timeout2, Timeout2, strHeader, Body.DataP( ), Body.GetLength( ), HttpReceiveToBuffer, &Buff, NULL, 0, CString( szProxyServer ), CString( szProxyUser ), CString( szProxyPassword ) );
153
+
154
+ if ( WAIT_OBJECT_0 != thHttpGet->WaitForThread( Timeout ) ) {
155
+ thHttpGet->SetCancel( );
156
+ thHttpGet->WaitForEndThread( );
157
+ delete thHttpGet;
158
+ Body.Close( );
159
+ return -12002;
160
+ }
161
+
162
+ thHttpGet->WaitForEndThread( );
163
+
164
+ // 省略
165
+ delete thHttpGet;
166
+ return (int)Buff.GetLength( );
167
+ }
168
+
169
+ bool CWinInetHttp::SyncHttpPost(LPCTSTR lpszHostAddress, LPCTSTR pszObjectName, UINT nHostPort, LPCTSTR pszHeader, LPVOID pPostData, int nPostData ,DWORD dwServiceType)
170
+ {
171
+ if (!syncHttpRequestAndResponse(
172
+ lpszHostAddress,
173
+ pszObjectName,
174
+ nHostPort,
175
+ _T("POST"),
176
+ pszHeader,
177
+ pPostData,
178
+ nPostData,
179
+ dwServiceType)) {
180
+ return false;
181
+ }
182
+
183
+ return true;
184
+ }
185
+
186
+ bool CWinInetHttp::syncHttpRequestAndResponse(
187
+ LPCTSTR lpszHostAddress,
188
+ LPCTSTR pszObjectName,
189
+ UINT nHostPort,
190
+ LPCTSTR pszVerb,
191
+ LPCTSTR pszContentType,
192
+ LPVOID pPostData,
193
+ int nPostData,
194
+ DWORD dwServiceType)
195
+ {
196
+ ::ResetEvent(m_hEventCancel);
197
+ m_dwStatusCode = 0;
198
+ m_bAllDone = false;
199
+ bool bSuccess = false;
200
+
201
+ // First call that will actually complete asynchronously even
202
+ // though there is no network traffic
203
+
204
+ m_hInetConnect = ::InternetConnect(
205
+ m_hInternet, // HINTERNET hInternet,
206
+ lpszHostAddress, // LPCTSTR lpszServerName
207
+ nHostPort, // INTERNET_PORT nServerPort
208
+ NULL, // LPCTSTR lpszUsername
209
+ NULL, // LPCTSTR lpszPassword
210
+ INTERNET_SERVICE_HTTP, // DWORD dwService
211
+ 0, // DWORD dwFlags
212
+ 0); // DWORD_PTR dwContext
213
+
214
+ if (m_hInetConnect == NULL) {
215
+ // 省略
216
+ }
217
+
218
+ VERIFY(INTERNET_INVALID_STATUS_CALLBACK != ::InternetSetStatusCallback(m_hInetConnect, (INTERNET_STATUS_CALLBACK)myInternetCallback));
219
+ // Creates an HTTP request handle
220
+
221
+ DWORD dwFlags = INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE;
222
+ if (dwServiceType == AFX_INET_SERVICE_HTTPS) {
223
+
224
+ dwFlags |= INTERNET_FLAG_SECURE;
225
+ dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;
226
+ dwFlags |= SECURITY_FLAG_IGNORE_CERT_CN_INVALID;
227
+ dwFlags |= SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;
228
+ dwFlags |= SECURITY_FLAG_IGNORE_REDIRECT_TO_HTTP;
229
+ dwFlags |= SECURITY_FLAG_IGNORE_REDIRECT_TO_HTTPS;
230
+ }
231
+
232
+ m_hInetRequest = NULL;
233
+ m_hInetRequest = ::HttpOpenRequest(
234
+ m_hInetConnect, // HINTERNET hConnect
235
+ pszVerb, // LPCTSTR lpszVerb
236
+ pszObjectName, // LPCTSTR lpszObjectName
237
+ NULL, // LPCTSTR lpszVersion
238
+ NULL, // LPCTSTR lpszReferer
239
+ NULL, // LPCTSTR* lpszAcceptTypes
240
+ dwFlags, // DWORD dwFlags
241
+ (DWORD)this); // DWORD_PTR dwContext
242
+
243
+ if (m_hInetRequest == NULL) {
244
+ // 省略
245
+ }
246
+
247
+ // Sends the specified request to the HTTP server
248
+ const int nContentTypeLen = pszContentType ? strlen(CT2A(pszContentType)) : 0;
249
+ const int nPostDataLen = pPostData ? nPostData : 0;
250
+
251
+ if (!::HttpSendRequest(
252
+ m_hInetRequest, // HINTERNET hRequest
253
+ pszContentType, // LPCTSTR lpszHeaders
254
+ nContentTypeLen, // DWORD dwHeadersLength
255
+ pPostData, // LPVOID lpOptional
256
+ nPostDataLen)) { // DWORD dwOptionalLength
257
+
258
+ //オリジナル
259
+ if (!checkIoPending(::GetLastError(), CErrInfo::errSend, _T("HttpSendRequest failed"))) {
260
+ // 省略
261
+ }
262
+
263
+ } else if (IsCanceled()) {
264
+ // 省略
265
+ return bSuccess;
266
+ }
267
+
268
+ {
269
+ CMyTimer timerSend(m_timeoutSend);
270
+ if (!waitForAsyncOperation(&timerSend, m_hEventRequestComplete)) {
271
+ // 省略
272
+ }
273
+ }
274
+
275
+ // Reads data from a handle opened by the InternetOpenUrl or HttpOpenRequest function.
276
+ while (!m_bAllDone) {
277
+ CByteArray bufRecv;
278
+ bufRecv.SetSize(4096, 0);
279
+
280
+ INTERNET_BUFFERS inetBuf;
281
+ ::ZeroMemory(&inetBuf, sizeof(inetBuf));
282
+ inetBuf.dwStructSize = sizeof(inetBuf);
283
+ inetBuf.lpvBuffer = bufRecv.GetData();
284
+ inetBuf.dwBufferLength = bufRecv.GetSize();
285
+
286
+ if (!::InternetReadFileEx(
287
+ m_hInetRequest, // HINTERNET hFile
288
+ &inetBuf, // LPINTERNET_BUFFERS lpBuffersOut
289
+ 0, // DWORD dwFlags
290
+ (DWORD)this)) { // DWORD dwContext
291
+ if (!checkIoPending(::GetLastError(), CErrInfo::errReceive, _T("InternetReadFileEx failed"))) {
292
+ // 省略
293
+ return bSuccess;
294
+ }
295
+
296
+ // 省略
297
+ }
298
+
299
+ {
300
+ char szStatus[256] = { 0 };
301
+ DWORD dwSize = sizeof(szStatus) - 1;
302
+ if (::HttpQueryInfo(m_hInetRequest, HTTP_QUERY_STATUS_CODE, szStatus, &dwSize, NULL)) {
303
+ m_dwStatusCode = atoi(szStatus); // APIにPOSTできたときはszStatus=2、失敗したときは5
304
+ }
305
+ }
306
+ return bSuccess;
307
+ }
308
+
309
+
310
+ ```
311
+
74
312
  ### 【現状の原因調査結果・考察】
75
313
  ・そもそもHeaderにて、application/jsonを指定した時点で、エンコーディングはUTF-8で実行されるという認識のため、HeaderのContent-Typeでcharsetの指定は不要なのではないかと考えています。
76
314
  ちなみに、charset=UTF8などいくつか試したが、APIを呼べたのはcharset=UNICODEとcharset=UTF-16のみでした(いずれも渡した文字列は文字化け)。

1

誤字の修正

2023/11/16 06:35

投稿

cosmori-man
cosmori-man

スコア2

test CHANGED
File without changes
test CHANGED
@@ -72,7 +72,7 @@
72
72
  上記のように、漢字平仮名部分のみが文字化けしてしまいました。
73
73
 
74
74
  ### 【現状の原因調査結果・考察】
75
- ・そもそもHeaderにて、application/jsonを指定した時点で、エンコーディングはUTF-8で実行されるという人強いのため、HeaderのContent-Typeでcharsetの指定は不要なのではないかと考えています。
75
+ ・そもそもHeaderにて、application/jsonを指定した時点で、エンコーディングはUTF-8で実行されるという認識のため、HeaderのContent-Typeでcharsetの指定は不要なのではないかと考えています。
76
76
  ちなみに、charset=UTF8などいくつか試したが、APIを呼べたのはcharset=UNICODEとcharset=UTF-16のみでした(いずれも渡した文字列は文字化け)。
77
77
 
78
78
  ・漢字平仮名の文字化けの様子を見るに、Shift-JisからUTF-8に変換した際の文字化けと思われます。