基于C++的http服务端开发

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接口如下

 

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

古木12345

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值