//
// request_handler.cpp
// ~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// #include "log4z.h"
#include "stdafx.h"
#include "request_handler.hpp"
#include <fstream>
#include <sstream>
#include <string>
#include <iostream>
#include "mime_types.hpp"
#include "reply.hpp"
#include "request.hpp"
#include <stdio.h>
#include<string.h>
#include <io.h>
#include <atlbase.h>
#include <iostream>
#include <fstream>
#include <atlbase.h>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp> #include <iostream>
#include <cstdlib>
#include <winsock2.h>
#include <windows.h>
#include <wincodec.h>
#include "mongo\client\dbclient.h"
#include "CrashRptProbe.h"
#include "CrashRpt.h"
#include "resource.h"
#include "DbgHelp.h"
#pragma comment(lib, "dbghelp.lib")
#ifndef verify
#define verify(x) MONGO_verify(x)
#endif #include "F:\Http_Mongo\GDIPlus\Includes/gdiplus.h"
using namespace Gdiplus;
#pragma comment(lib, "F:/Http_Mongo/GDIPlus/lib/gdiplus.lib") using namespace zsummer;
using namespace std; GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
mongo::client::GlobalInstance instance;
Bitmap *bmPhoto;
wchar_t* utftoun;
wchar_t* ansitoun;
LONG WINAPI MyUnhandledFilter(struct _EXCEPTION_POINTERS *lpExceptionInfo)
{
LONG ret = EXCEPTION_EXECUTE_HANDLER; TCHAR szFileName[64];
SYSTEMTIME st;
::GetLocalTime(&st);
wsprintf(szFileName, TEXT("TCP_%04d%02d%02d-%02d%02d%02d-%ld-%ld.dmp"), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, GetCurrentProcessId(), GetCurrentThreadId()); HANDLE hFile = ::CreateFile(szFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
MINIDUMP_EXCEPTION_INFORMATION ExInfo;
ExInfo.ThreadId = ::GetCurrentThreadId();
ExInfo.ExceptionPointers = lpExceptionInfo;
ExInfo.ClientPointers = false; // write the dump
BOOL bOK = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL);
::CloseHandle(hFile);
}
else
{
//printf("Create File %s Failed %d\n", szFileName, GetLastError());
}
::MessageBox(NULL, TEXT("程序遇到问题需要关闭!"), TEXT("提示"), MB_OK);
return ret;
} int GetEncoderClsid(const WCHAR* format, CLSID* pClsid) //GDI+取得不同类型图片编码类型的函数
{
UINT num = 0; // number of image encoders
UINT size = 0; // size of the image encoder array in bytes ImageCodecInfo* pImageCodecInfo = NULL; GetImageEncodersSize(&num, &size);
if (size == 0)
return -1; // Failure pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
if (pImageCodecInfo == NULL)
return -1; // Failure GetImageEncoders(num, size, pImageCodecInfo); for (UINT j = 0; j < num; ++j)
{
if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0)
{
*pClsid = pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j; // Success
}
} free(pImageCodecInfo);
return -1; // Failure }
wchar_t* AnsiToUnicode(const char *str)
{
DWORD dwNum = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
wchar_t *pwText;
pwText = new wchar_t[dwNum];
if (!pwText)
{
delete[]pwText;
}
MultiByteToWideChar(CP_ACP, 0, str, -1, pwText, dwNum);
ansitoun = pwText;
return pwText;
}
LPWSTR UTF82UNICODE(const char* utf8str)
{
int nLength;
wchar_t *pBuffer; nLength = MultiByteToWideChar(CP_UTF8, 0, utf8str, strlen(utf8str), NULL, 0);
pBuffer = new wchar_t[nLength + 1];
MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)utf8str, strlen(utf8str), (LPWSTR)pBuffer, nLength);
pBuffer[nLength] = 0;
utftoun = pBuffer;
return pBuffer;
}
static wstring Str2Wstr(string str)
{
if (str.length() == 0)
return L""; std::wstring wstr;
wstr.assign(str.begin(), str.end());
return wstr;
}
Image* FixedSize3(Image *imgSrc1, Image *imgSrc2)
{
bmPhoto = new Bitmap(imgSrc1->GetWidth(), imgSrc1->GetHeight() + imgSrc2->GetHeight());
bmPhoto->SetResolution(imgSrc1->GetHorizontalResolution(), imgSrc1->GetVerticalResolution());
Graphics grPhoto(bmPhoto);
grPhoto.SetInterpolationMode(InterpolationModeHighQualityBicubic); grPhoto.DrawImage(imgSrc1, 0, 0);
grPhoto.DrawImage(imgSrc2, 0, imgSrc1->GetHeight());
return bmPhoto;
} namespace http {
namespace server { request_handler::request_handler(const std::string& doc_root)
: doc_root_(doc_root)
{
} void request_handler::handle_request(const request& req, reply& rep)
{
//写DMP文件
// 初始化异常捕获
CR_INSTALL_INFO info;
memset(&info, 0, sizeof(CR_INSTALL_INFO));
info.cb = sizeof(CR_INSTALL_INFO);
info.pszAppName = TEXT("MyWin32CrashRpt");
info.dwFlags |= CR_INST_ALL_POSSIBLE_HANDLERS;
crInstall(&info);
SetUnhandledExceptionFilter(&MyUnhandledFilter); // Decode url to path.
char* data = NULL;;
long filesize = 0; string reqip = { 0 }; for (int i = 0; i < req.headers.size(); i++)
{
//获取客户端IP
string name = req.headers[i].name;
if (name == "Host")
{
reqip = req.headers[i].value;
break;
}
}
// cout << "req" << reqip << endl;
char str[20]; strcpy(str, reqip.c_str()); char *strreqip = strtok(str, ":"); std::string request_path;
if (!url_decode(req.uri, request_path))
{
rep = reply::stock_reply(reply::bad_request);
return;
} // Request path must be absolute and not contain "..".
if (request_path.empty() || request_path[0] != '/'
|| request_path.find("..") != std::string::npos)
{
rep = reply::stock_reply(reply::bad_request);
return;
} // If path ends in slash (i.e. is a directory) then add "index.html".
if (request_path[request_path.size() - 1] == '/')
{
request_path += "index.php";
} std::size_t last_slash_pos = request_path.find_first_of("?");
string wenqian = request_path.substr(0, last_slash_pos);
std::size_t last_dot_pos = wenqian.find_last_of(".");
std::string extension;
std::string kuozhan;
if (last_dot_pos != std::string::npos)
{
extension = request_path.substr(last_dot_pos + 1);
kuozhan = wenqian.substr(last_dot_pos+1);
}
std::string addra;
string InImgName;
std::string tableid;
if (kuozhan == "php")
{
//逻辑开始
//auto ques_pos = request_path.find_first_of("?");
//if (ques_pos != std::string::npos)
//{
auto vec = GetPrameter(request_path, "?"); if (vec.size() > 0)
{
//连接mongo if (!instance.initialized()) {
std::cout << "failed to initialize the client driver: " << instance.status() << std::endl;
return;
}
std::string uri = "mongodb://127.0.0.1:27017";
std::string errmsg; mongo::ConnectionString cs = mongo::ConnectionString::parse(uri, errmsg); if (!cs.isValid()) {
std::cout << "Error parsing connection string " << uri << ": " << errmsg << std::endl;
return;
}
//DBClientBase ss;
boost::scoped_ptr<mongo::DBClientBase> conn(cs.connect(errmsg));
if (!conn) {
cout << "couldn't connect : " << errmsg << endl;
return;
}
const char* ns = "majiang.records"; addra = GetUrlParam((char*)request_path.c_str(), "addra");
tableid = GetUrlParam((char*)request_path.c_str(), "tableid"); // std::string query = GetUrlParam((char*)request_path.c_str(), "query"); //创建日志
char buf[1024] = { 0 }; //请求处理
// if (query != "")
{
InImgName = doc_root_ + "image\\" + tableid;
InImgName += ".png";
WCHAR wcstr[50] = L"";
mbstowcs(wcstr, InImgName.c_str(), strlen(InImgName.c_str()));
FILE * fp = NULL;
if (access(InImgName.c_str(), 0) == -1)
{
//bu cun zai
string sqlstr = "{\"tableId\":\"" + tableid;
sqlstr += "\"}";
LOG_INFO(1, "sqlstr = " << sqlstr); mongo::BSONObj res = conn->findOne(ns, mongo::Query(sqlstr)); cout << res << endl;
if (res.isEmpty())
{
data = NULL;
}
else
{
string stattime = res["ctime"];
stattime = stattime.substr(stattime.find_first_of(" ") + 1);
string endtime = res["time"];
endtime = endtime.substr(endtime.find_first_of(" ") + 1);
double creat = atof(stattime.c_str());
double end = atof(endtime.c_str());
unsigned long lt = (unsigned long)(creat / 1000);
time_t t = (time_t)lt;
struct tm *p;
p = localtime(&t);
char creattime[80];
strftime(creattime, 80, "%Y-%m-%d %H:%M:%S", p); int shichang = (int)(atof(endtime.c_str()) - atof(stattime.c_str())) / 1000 / 60;
char strtime[20] = { 0 };
sprintf_s(strtime, "%d", shichang); int round = res.getIntField("round");
char strround[5] = { 0 };
sprintf_s(strround, "%d", round); string gameid = res["gameId"];
gameid = gameid.substr(gameid.find_first_of(" ") + 1);
gameid = gameid.substr(0, 5);
string strgame; if (gameid == "10003")
{
strgame = "经典牛牛";
}
else if (gameid == "10004")
{
strgame = "斗地主";
}
else if (gameid == "10005")
{
strgame = "跑得快";
}
else if (gameid == "10006")
{
strgame = "十三水";
}
else if (gameid == "10007")
{
strgame = "灵璧麻将";
}
else if (gameid == "10008")
{
strgame = "十点半";
}
else if (gameid == "10009")
{
strgame = "南京麻将";
}
else if (gameid == "10010")
{
strgame = "晋中麻将";
}
else if (gameid == "10013")
{
strgame = "比鸡";
}
else if (gameid == "10020")
{
strgame = "炸金花";
}
else if (gameid == "10012")
{
strgame = "推倒胡";
}
else
{
strgame = "不知道";
} mongo::BSONObj users = res.getObjectField("users"); GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
Image* m_pImageh = Image::FromFile(L"head.png");
Image* m_pImagel = Image::FromFile(L"low.png");
Image* m_pImagem = Image::FromFile(L"man.png");
Image* m_pImagewo = Image::FromFile(L"woman.png");
Image*m_pImage = m_pImageh;
//Image*m_pImagez; Graphics graphics(GetDC(0));
Graphics imageGraphics(m_pImage);
imageGraphics.SetTextRenderingHint(TextRenderingHintAntiAlias); FontFamily fontFamily(L"楷体");
Gdiplus::Font myFont(&fontFamily, 20, FontStyleRegular, UnitPoint);
SolidBrush blackBrush(Color(125, 0, 0, 0));
StringFormat format;
WCHAR roundstr[50] = { 0 };
mbstowcs(roundstr, strround, strlen(strround));
PointF school_site5((REAL)110, (REAL)174);
imageGraphics.DrawString(roundstr, wcslen(roundstr), &myFont, school_site5, &format, &blackBrush);
WCHAR timestr[50] = { 0 };
mbstowcs(timestr, strtime, strlen(strtime));
PointF school_site6((REAL)440, (REAL)174);
imageGraphics.DrawString(timestr, wcslen(timestr), &myFont, school_site6, &format, &blackBrush);
WCHAR fenzhong[] = L"分钟";
PointF school_site7((REAL)495, (REAL)174);
imageGraphics.DrawString(fenzhong, wcslen(fenzhong), &myFont, school_site7, &format, &blackBrush); auto gamestr = AnsiToUnicode(strgame.c_str());
PointF school_site8((REAL)50, (REAL)120);
imageGraphics.DrawString(gamestr, wcslen(gamestr), &myFont, school_site8, &format, &blackBrush); WCHAR cratet[50] = { 0 };
mbstowcs(cratet, creattime, strlen(creattime));
PointF school_site11((REAL)300, (REAL)120);
imageGraphics.DrawString(cratet, wcslen(cratet), &myFont, school_site11, &format, &blackBrush); auto it = users.begin();
int x = 120;
int y = 365;
int winx = 0;
int winy = 0;
int winscore = -1;
while (it.more())
{
auto doc = it.next();
cout << doc << endl;
string name = doc["name"];
string score = doc["score"];
string sex = doc["sex"];
sex = sex.substr(sex.find_first_of(" ") + 1); if (sex == "\"1\"")
m_pImage = FixedSize3(m_pImage, m_pImagem);
else
m_pImage = FixedSize3(m_pImage, m_pImagewo);
Graphics graphics1(GetDC(0));
Graphics imageGraphics1(m_pImage);
imageGraphics1.SetTextRenderingHint(TextRenderingHintAntiAlias); cout << name << endl;
cout << score << endl;
name = name.substr(name.find_first_of("\"") + 1);
name = name.substr(0, name.find_last_of("\""));
score = score.substr(score.find_first_of(" ") + 1); if (winscore < atoi(score.c_str()))
{
winscore = atoi(score.c_str());
winx = x + 200;
winy = y - 12;
}
int x1 = 360;
if (atoi(score.c_str()) < 0) x1 = 346;
auto wstr = UTF82UNICODE(name.c_str()); WCHAR string4[50] = { 0 };
mbstowcs(string4, score.c_str(), strlen(score.c_str())); PointF school_site2((REAL)x, (REAL)y);
PointF school_site4((REAL)x + x1, (REAL)y); format.SetAlignment(StringAlignmentNear);
imageGraphics1.DrawString(wstr, wcslen(wstr), &myFont, school_site2, &format, &blackBrush);
imageGraphics1.DrawString(string4, wcslen(string4), &myFont, school_site4, &format, &blackBrush);
y += 111;
}
m_pImage = FixedSize3(m_pImage, m_pImagel); Image* m_pImagewin = Image::FromFile(L"mvp.png");
Graphics* g = Graphics::FromImage(m_pImage);
g->DrawImage(m_pImagewin, winx, winy); CLSID pngClsid;
GetEncoderClsid(L"image/png", &pngClsid);
Status status = m_pImage->Save(wcstr, &pngClsid, NULL);
if (status != 0)
{
wprintf(L"%d Attempt to save .png failed.\n", status); LPVOID lpMsgBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf,
0, NULL);
cout << lpMsgBuf << endl;
}
if (utftoun) delete utftoun;
if (ansitoun) delete ansitoun;
ifstream in(InImgName, ios::in | ios::binary | ios::ate);
filesize = in.tellg();
in.seekg(0, ios::beg);
data = new char[filesize];
in.read(data, filesize);
in.close();
}
}
else
{
//you tu pian
ifstream in(InImgName, ios::in | ios::binary | ios::ate);
filesize = in.tellg(); in.seekg(0, ios::beg);
data = new char[filesize];
in.read(data, filesize);
in.close();
}
}
}
char imge[10240] = { 0 };
if (addra == "")
{
addra = "#";
}
string imgsrc ="/image/" + tableid + ".png";
sprintf_s(imge, "<html> <body border=\"0\"> <a href=\"%s\"><img src=\"%s\" width=\"100%%\" height=\"100%%\" border=\"0\" alt=\"\"/></a><br> </body> </html>", addra.c_str(), imgsrc.c_str()); rep.content.append(imge, strlen(imge));
rep.headers.resize(3);
rep.headers[0].name = "Content-Length";
rep.headers[0].value = std::to_string(rep.content.size());
rep.headers[1].name = "Content-Type";
rep.headers[1].value = "text/html";
rep.headers[2].name = "Access-Control-Allow-Origin";//可跨域访问
rep.headers[2].value = "*";
return;
} // Open the file to send back.
std::string full_path = doc_root_ + request_path;
std::ifstream is(full_path.c_str(), std::ios::in | std::ios::binary);
if (!is)
{
rep = reply::stock_reply(reply::not_found);
return;
} // Fill out the reply to be sent to the client.
rep.status = reply::ok;
char buf[1024] = "\0"; while (is.read(buf, sizeof(buf)).gcount() > 0)
rep.content.append(buf, is.gcount()); //添加消息,反馈给客户端 // char str[255] = "{\"code\":\"404\"}";
rep.content.append(buf, strlen(buf));
rep.headers.resize(3);
rep.headers[0].name = "Content-Length";
rep.headers[0].value = std::to_string(rep.content.size());
rep.headers[1].name = "Content-Type";
rep.headers[1].value = mime_types::extension_to_type(extension);
rep.headers[2].name = "Access-Control-Allow-Origin";//可跨域访问
rep.headers[2].value = "*"; } bool request_handler::url_decode(const std::string& in, std::string& out)
{
out.clear();
out.reserve(in.size());
for (std::size_t i = 0; i < in.size(); ++i)
{
if (in[i] == '%')
{
if (i + 3 <= in.size())
{
int value = 0;
std::istringstream is(in.substr(i + 1, 2));
if (is >> std::hex >> value)
{
out += static_cast<char>(value);
i += 2;
}
else
{
return false;
}
}
else
{
return false;
}
}
else if (in[i] == '+')
{
out += ' ';
}
else
{
out += in[i];
}
}
return true;
} } // namespace server
} // namespace http