1、同时支持get、post接口请求
2、支持文件流下载接口
完整源代码下载地址:https://download.csdn.net/download/GUMU12345/81103130
//
// sample.cc
//
// Copyright (c) 2019 Yuji Hirose. All rights reserved.
// MIT License
//
#include <chrono>
#include <cstdio>
#include "httplib.h"
using namespace httplib;
char* file(const std::wstring &filepath) {
std::string s;
OutputDebugString(L"+++++++++++++++++++++++++++++++++");
HANDLE hFile;
hFile = CreateFile(filepath.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
return false;
}
DWORD dFileSize = GetFileSize(hFile, NULL);
char * pBuffer = new char[dFileSize + 1];
if (pBuffer == NULL)
return false;
memset(pBuffer, 0, dFileSize);
DWORD dReadSize(0);
if (!ReadFile(hFile, pBuffer, dFileSize, &dReadSize, NULL))
{
delete[]pBuffer;
CloseHandle(hFile);
return false;
}
delete[]pBuffer;
//delete[]pBuffer;
CloseHandle(hFile);
OutputDebugString(L"________________________________");
return pBuffer;
}
DWORD filesize(const std::wstring &filepath) {
std::string s;
HANDLE hFile;
hFile = CreateFile(filepath.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
return 0;
}
DWORD dFileSize = GetFileSize(hFile, NULL);
CloseHandle(hFile);
return dFileSize;
}
std::string dump_headers(const Headers& headers ) {
std::string s;
char buf[BUFSIZ];
for (auto it = headers.begin(); it != headers.end(); ++it) {
const auto &x = *it;
snprintf(buf, sizeof(buf), "%s: %s\n", x.first.c_str(), x.second.c_str());
s += buf;
}
return s;
}
std::string log(const Request &req, const Response &res) {
std::string s;
char buf[BUFSIZ];
s += "================================\n";
snprintf(buf, sizeof(buf), "%s %s %s", req.method.c_str(),
req.version.c_str(), req.path.c_str());
s += buf;
std::string query;
for (auto it = req.params.begin(); it != req.params.end(); ++it) {
const auto &x = *it;
snprintf(buf, sizeof(buf), "%c%s=%s",
(it == req.params.begin()) ? '?' : '&', x.first.c_str(),
x.second.c_str());
query += buf;
}
snprintf(buf, sizeof(buf), "%s\n", query.c_str());
s += buf;
s += dump_headers(req.headers);
s += "--------------------------------\n";
snprintf(buf, sizeof(buf), "%d %s\n", res.status, res.version.c_str());
s += buf;
s += dump_headers(res.headers);
s += "\n";
if (!res.body.empty()) { s += res.body; }
s += "\n";
return s;
}
static std::string g_strVersion = "0.0.0.0";
static char * g_pUpdateFileBuffer = nullptr;
static DWORD g_UpdateFileSzie = 0;
bool InitializeUpgradePackage()
{
char val[256];
memset(val, 0, sizeof(val));
GetPrivateProfileStringA("sys","version","0", val, 256, "./config.ini");
g_strVersion = val;
if (g_strVersion == "0")
{
printf("请配置config.ini中[version]版本信息\n");
return false;
}
memset(val, 0, sizeof(val));
GetPrivateProfileStringA("sys", "package", "", val, 256, "./config.ini");
std::string fileName = val;
if (fileName == "")
{
printf("请配置config.ini中[package]升级包名称\n");
return false;
}
std::string filepath = "./";
filepath += fileName;
OutputDebugString(L"+++++++++++++++++++++++++++++++++");
HANDLE hFile;
hFile = CreateFileA(filepath.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
printf("读取升级包名称失败,请检查当前目录是否存在\n");
return false;
}
DWORD dFileSize = GetFileSize(hFile, NULL);
g_UpdateFileSzie = dFileSize;
g_pUpdateFileBuffer = new char[dFileSize + 1];
if (g_pUpdateFileBuffer == NULL)
return false;
memset(g_pUpdateFileBuffer, 0, dFileSize);
DWORD dReadSize(0);
if (!ReadFile(hFile, g_pUpdateFileBuffer, dFileSize, &dReadSize, NULL))
{
delete[]g_pUpdateFileBuffer;
CloseHandle(hFile);
return false;
}
CloseHandle(hFile);
OutputDebugString(L"________________________________");
return true;
}
int main(void) {
Server svr;
if (InitializeUpgradePackage() == false)
{
return 0;
}
if (!svr.is_valid()) {
printf("server has an error...\n");
return -1;
}
svr.Get("/", [=](const Request & /*req*/, Response &res) {
res.set_redirect("/version");
});
svr.Post("/", [=](const Request & /*req*/, Response &res) {
res.set_redirect("/version");
});
svr.Get("/version", [](const Request & /*req*/, Response &res) {
res.set_content(g_strVersion, "text/plain");
});
svr.Post("/version", [](const Request & /*req*/, Response &res) {
res.set_content(g_strVersion, "text/plain");
});
svr.Get("/getfile", [](const Request &req, Response &res) {
res.set_content(g_pUpdateFileBuffer, g_UpdateFileSzie, "application/octet-stream");
});
svr.Post("/getfile", [](const Request &req, Response &res) {
res.set_content(g_pUpdateFileBuffer, g_UpdateFileSzie, "application/octet-stream");
});
svr.set_error_handler([](const Request & /*req*/, Response &res) {
const char *fmt = "<p>Error Status: <span style='color:red;'>%d</span></p>";
char buf[BUFSIZ];
snprintf(buf, sizeof(buf), fmt, res.status);
res.set_content(buf, "text/html");
});
svr.set_logger([](const Request &req, const Response &res) {
printf("%s", log(req, res).c_str());
});
printf("HTTP Server Run....ok");
//svr.listen("192.168.0.111", 8080);
svr.listen("0.0.0.0", 8080);
return 0;
}
测试截图:
1、服务端运行截图
2、浏览器测试http接口如下