web服务器为Aapache(运行在linux上)扩展模块(参看,将收到来自客户端的POST请求文本写到某个目录中,客户端发送代码如下(不完整):
strcpy(szURL, "http://www.xxx.com") // xxx 仅仅为了说明问题if (!::InternetCheckConnection(szURL, FLAG_ICC_FORCE_CONNECTION, 0)) return FALSE;TCHAR szModuleFile[MAX_PATH] = {0};::GetModuleFileName(NULL, szModuleFile, MAX_PATH);LPCTSTR lpPath = ::PathFindFileName(szModuleFile);HINTERNET hOpen = ::InternetOpen(lpPath, INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY, NULL, NULL, 0);if (NULL == hOpen) return FALSE;HINTERNET hConnect = ::InternetConnect(hOpen, lpDomain, dwPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);if (NULL == hConnect) goto FUN_END2;LPCTSTR szAccept[] = {_T("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"), NULL};DWORD dwFlag = INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_RELOAD | INTERNET_FLAG_KEEP_CONNECTION;HINTERNET hOpenRequest = ::HttpOpenRequest(hConnect, _T("POST"), _T("my_app"), _T("HTTP/1.1"), szURL, szAccept, dwFlag, 0); // my_app是apache扩展C++模块.if (NULL == hOpenRequest) goto FUN_END1;BOOL bRet = FALSE;TCHAR headerContentLength[64];_stprintf(headerContentLength, _T("Content-Length: %d\r\n\r\n"), nLen);// 这个语句向http://www.xxx.com/my_app发送数据.bRet = ::HttpSendRequest(hOpenRequest, headerContentLength, _tcslen(headerContentLength), utf8PostData, nLen);DWORD dwErr = ::GetLastError();if (!bRet) goto FUN_END1;TCHAR szBuff[BUF_LEN_1024] = {0};DWORD dwBuffSize = BUF_LEN_1024*sizeof(szBuff)-2;bRet = ::HttpQueryInfo(hOpenRequest, HTTP_QUERY_STATUS_CODE, (LPVOID)szBuff, &dwBuffSize, NULL);//Reference to http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.htmlint nStatusCode = _tstoi(szBuff);//if (nStatusCode<200 || 206
在调试过程中发现,HttpSendRequest总是返回FALSE,错误码为12152(MSDN定义,ERROR_HTTP_INVALID_SERVER_RESPONSE,The server response could not be parsed).经过抓包可知,网络正常,3次握手,4次分手都正常,说明apache确实收到了这份数据,通过浏览器访问http://www.xxx.com/my_app也正常.
有不少网友说该错误可能发生在客户端或者系统,例如杀毒软件,网络异常等等,现这里不是这种问题,经过调查发现,错误竟然出在服务端读写权限上.扩展模块my_app会将收到的数据写到目录log,但log的权限开始是"drwxr-xr-x.",后来修改了权限(chmod ugo+w log)为"drwxrwxrwx."竟然可以了.
从这个错误可以看出,当apache不能处理某个http请求时,不会将相应的数据传递给C++扩展模块,而是返回错误(12152)给发送程序.