#include "StdAfx.h" #include "HttpService.h" #include #pragma comment(lib, "httpapi.lib") #include "AgvMainDialog.h" #include "ModuleProcess.h" CHttpService::CHttpService() { m_thread = NULL; m_req_queue = NULL; m_req_buffer = NULL; m_req_buffer_size = 4096; } BOOL CHttpService::Create(CString strIp, INT port, IHttpServiceListener *listener, CAgvMainDialog *pParentDlg) { ULONG ret; CHAR url[1024]; m_pMainDialog = pParentDlg; HTTPAPI_VERSION version = HTTP_VERSION_1_0; sprintf(url, "http://%s:%d/", strIp, port); ret = HttpInitialize(version, HTTP_INITIALIZE_SERVER, NULL); if (ret != NO_ERROR) { TRACE("HttpInitialize error(%u)!\r\n", ret); return FALSE; } ret = HttpCreateHttpHandle(&m_req_queue, 0); if (ret != NO_ERROR) { TRACE("HttpCreateHttpHandle error(%u)!\n", ret); HttpTerminate(HTTP_INITIALIZE_SERVER, NULL); return FALSE; } //ERROR_ACCESS_DENIED --- 需要管理员身份运行 USES_CONVERSION; ret = HttpAddUrl(m_req_queue, A2W(url), NULL); if (ret != NO_ERROR) { TRACE("HttpAddUrl error(%u)!\n", ret); CloseHandle(m_req_queue); HttpTerminate(HTTP_INITIALIZE_SERVER, NULL); return FALSE; } m_req_buffer = (LPBYTE)malloc(m_req_buffer_size); m_listener = listener; m_thread = AfxBeginThread(RecvRequestThread, this); return TRUE; } BOOL CHttpService::Delete(void) { if (m_req_queue) { CloseHandle(m_req_queue); HttpTerminate(HTTP_INITIALIZE_SERVER, NULL); m_req_queue = NULL; } if (m_req_buffer) { free(m_req_buffer); m_req_buffer = NULL; } if (m_thread) { m_thread->Delete(); m_thread = NULL; } return TRUE; } BOOL CHttpService::SendRequestResp(HTTP_REQUEST_ID req_id, INT status, LPCSTR reason, LPCSTR type, HANDLE file, LPVOID mem, DWORD mem_size) { HTTP_RESPONSE resp; HTTP_DATA_CHUNK chunk; DWORD ret; DWORD sent; RtlZeroMemory(&resp, sizeof(resp)); resp.StatusCode = status; resp.pReason = reason; resp.ReasonLength = (USHORT)strlen(reason); resp.Headers.KnownHeaders[HttpHeaderContentType].pRawValue = type; resp.Headers.KnownHeaders[HttpHeaderContentType].RawValueLength = (USHORT)strlen(type); resp.EntityChunkCount = 1; resp.pEntityChunks = &chunk; if (file != NULL) { chunk.DataChunkType = HttpDataChunkFromFileHandle; chunk.FromFileHandle.FileHandle = file; chunk.FromFileHandle.ByteRange.StartingOffset.QuadPart = 0; chunk.FromFileHandle.ByteRange.Length.QuadPart = HTTP_BYTE_RANGE_TO_EOF; } if (mem != NULL) { chunk.DataChunkType = HttpDataChunkFromMemory; chunk.FromMemory.pBuffer = mem; chunk.FromMemory.BufferLength = mem_size; } ret = HttpSendHttpResponse(m_req_queue, req_id, 0, &resp, NULL, &sent, NULL, 0, NULL, NULL); if (ret != NO_ERROR) { TRACE(L"HttpSendHttpResponse error(%u)!\n", ret); return FALSE; } return TRUE; } DWORD CHttpService::RecvRequestBody(HTTP_REQUEST_ID req_id, HANDLE file, char *mem, DWORD mem_size) { DWORD read = 0; if (file != NULL) { return read; } if (mem != NULL) { HttpReceiveRequestEntityBody(m_req_queue, req_id, 0, mem, mem_size, &read, NULL); mem[read] = 0; return read; } return read; } UINT CHttpService::RecvRequestThread(LPVOID param) { CHttpService *self; self = (CHttpService *)param; self->DoReceiveRequests(); Sleep(INFINITE); return 0; } BOOL CHttpService::DoReceiveRequests(void) { ULONG ret; DWORD bytes_read; PHTTP_REQUEST request; request = (PHTTP_REQUEST)m_req_buffer; while (1) { RtlZeroMemory(request, m_req_buffer_size); ret = HttpReceiveHttpRequest(m_req_queue, HTTP_NULL_ID, 0, request, m_req_buffer_size, &bytes_read, NULL); if (ret == NO_ERROR) { m_listener->OnRecvRequest(this, request); continue; } TRACE("HttpReceiveHttpRequest error(%u)!\r\n", ret); if (ret == ERROR_OPERATION_ABORTED) { return FALSE; } if (ret == ERROR_INVALID_HANDLE) { return FALSE; } } return TRUE; } BOOL CHttpService::GetRemoteAddr(PHTTP_REQUEST request, CString &text) { PSOCKADDR_IN addr = (PSOCKADDR_IN)request->Address.pRemoteAddress; text.Format("%d.%d.%d.%d", addr->sin_addr.S_un.S_un_b.s_b1, addr->sin_addr.S_un.S_un_b.s_b2, addr->sin_addr.S_un.S_un_b.s_b3, addr->sin_addr.S_un.S_un_b.s_b4); return TRUE; } BOOL HttpServiceListener::OnRecvRequest(CHttpService *inst, PHTTP_REQUEST request) { //收消息 LogOutToFile("HttpServiceListener::OnRecvRequest Begin"); CString strText; PSOCKADDR_IN addr = (PSOCKADDR_IN)request->Address.pRemoteAddress; strText.Format("%d.%d.%d.%d", addr->sin_addr.S_un.S_un_b.s_b1, addr->sin_addr.S_un.S_un_b.s_b2, addr->sin_addr.S_un.S_un_b.s_b3, addr->sin_addr.S_un.S_un_b.s_b4); //AfxMessageBox(strText); CString strRecvFunc = request->pRawUrl; CString strRecvParam = ""; //strRecvFunc += "==>"; for (;;) { char acBuffer[512] = { 0 }; int lRead = inst->RecvRequestBody(request->RequestId, NULL, acBuffer, 511); strRecvParam += acBuffer; if (lRead < 511) { break; } } //strRecvParam += "\r\n"; Json::Reader reader; Json::Value root; if (reader.parse(strRecvParam.GetBuffer(), root)) { CString strReceiver = root["receiver"].asString().c_str(); //CString strMsgType = root["type"].asString().c_str(); //CString strMsgParam = root["params"].asString().c_str(); CString strMsg = "接收到WMS的消息:" + strRecvParam; m_pMainDialog->AddLog2Edit(strMsg); if (m_pMainDialog->m_mapAllNormal.find(strReceiver) != m_pMainDialog->m_mapAllNormal.end()) { m_pMainDialog->m_mapAllNormal[strReceiver]->SendDataToModule(MAIN_2_MODULE_WMS, strRecvParam.GetBuffer(), strRecvParam.GetLength()); } } CString strRetMsg = "succeed"; //回复消息 inst->SendRequestResp(request->RequestId, 200, "OK", "application/json", NULL, strRetMsg.GetBuffer(), strRetMsg.GetLength()); LogOutToFile("HttpServiceListener::OnRecvRequest End"); return TRUE; };