欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

(原创)linux下Microsoftcpprestsdk支持https(server)

程序员文章站 2022-07-13 21:20:41
...

之前看网上一堆的资料说Microsoft/cpprestsdk不支持https或者说只支持window下的https,差点就被误导了,没办法,只好自己去翻了下源代码

先说明下linux版本把,centos7

创建ssl证书啥的,网上一堆的资料,这边就不再说了,直接贴源代码了

#include <stdio.h>
#include <cpprest/uri.h>
#include <cpprest/http_listener.h>
#include <cpprest/http_client.h>
#include <cpprest/asyncrt_utils.h>
#include <cpprest/filestream.h>

#pragma comment(lib, "cpprest_2_7.lib")
#pragma comment(lib, "bcrypt.lib")
#pragma comment(lib, "crypt32.lib")
#pragma comment(lib, "winhttp.lib")
#pragma comment(lib, "httpapi.lib")

using namespace web;
using namespace http;
using namespace utility;
using namespace http::experimental::listener;
using namespace web::http;
using namespace web::http::client;
//using namespace concurrency;
 

class CommandHandler
{
public:
    CommandHandler() {}
    CommandHandler(utility::string_t url,http_listener_config server_config);
    pplx::task<void> open() { return m_listener.open(); }
    pplx::task<void> close() { return m_listener.close(); }
private:
    void handle_get(http_request message);
    void handle_post(http_request message);
    void handle_put(http_request message);
    void handle_del(http_request message);
    http_listener m_listener;
};

CommandHandler::CommandHandler(utility::string_t url,http_listener_config server_config) : m_listener(url,server_config)
{
    m_listener.support(methods::GET, std::bind(&CommandHandler::handle_get, this, std::placeholders::_1));
    m_listener.support(methods::POST, std::bind(&CommandHandler::handle_post, this, std::placeholders::_1));
    m_listener.support(methods::PUT, std::bind(&CommandHandler::handle_put, this, std::placeholders::_1));
    m_listener.support(methods::DEL, std::bind(&CommandHandler::handle_del, this, std::placeholders::_1));
}
 
void CommandHandler::handle_get(http_request message)
{
    ucout << "Method: " << message.method() << std::endl;
    ucout << "URI: " << http::uri::decode(message.relative_uri().path()) << std::endl;
    ucout << "Query: " << http::uri::decode(message.relative_uri().query()) << std::endl << std::endl;
    message.reply(status_codes::OK, "ACCEPTED");
    }
}

void CommandHandler::handle_post(http_request message)
{
    //std::unordered_map<std::string, std::unordered_map<std::string, std::vector<unsigned char>>> multipart_form_data = granada::httpex::parserex::ParseMultipartFormData(message);
    ucout << "Method: " << message.method() << std::endl;
    ucout << "URI: " << http::uri::decode(message.relative_uri().path()) << std::endl;
    ucout << "Query: " << http::uri::decode(message.relative_uri().query()) << std::endl << std::endl;
    message.reply(status_codes::OK, "POST");
}
 

void CommandHandler::handle_put(http_request message)
{
    ucout << "Method: " << message.method() << std::endl;
    ucout << "URI: " << http::uri::decode(message.relative_uri().path()) << std::endl;
    ucout << "Query: " << http::uri::decode(message.relative_uri().query()) << std::endl << std::endl;
    message.reply(status_codes::OK, "PUT");
}

void CommandHandler::handle_del(http_request message)
{
    ucout << "Method: " << message.method() << std::endl;
    ucout << "URI: " << http::uri::decode(message.relative_uri().path()) << std::endl;
    ucout << "Query: " << http::uri::decode(message.relative_uri().query()) << std::endl << std::endl;
    message.reply(status_codes::OK, "DEL");
}

int main(int argc, char *argv[])
{
    try
    {
        //用C++ REST SDK编写HTTP服务端,需要在所有的网络接口上监听时,
        //Windows下应使用地址"http://*:8080",
        //Linux下应使用地址"http://0.0.0.0:8080"。
        
    const char * self_signed_cert = R"(
-----BEGIN CERTIFICATE-----
***************//替换成自己的证书
-----END CERTIFICATE-----
        )";
    const char * private_key = R"(
-----BEGIN PRIVATE KEY-----
*********//替换成自己的证书
-----END PRIVATE KEY-----
        )";
        boost::asio::const_buffer cert(self_signed_cert, std::strlen(self_signed_cert));
        boost::asio::const_buffer key(private_key, std::strlen(private_key));

        http_listener_config server_config;
        server_config.set_ssl_context_callback(
            [&](boost::asio::ssl::context& ctx)
            {
                ctx.set_options(boost::asio::ssl::context::default_workarounds);
                ctx.use_certificate_chain(cert);
                ctx.use_private_key(key, boost::asio::ssl::context::pem);
            });

        int nPort = 8080;
        char pAddr[32];
        memset(pAddr,0,sizeof(pAddr));
        sprintf(pAddr,"https://0.0.0.0:%d",nPort);
        utility::string_t address = pAddr;//U("http://0.0.0.0:8080");
        uri_builder uri(address);
        auto addr = uri.to_uri().to_string();
        CommandHandler handler(addr,server_config);
        handler.open().wait();
        ucout << utility::string_t(U("Listening for requests at: ")) << addr << std::endl;
        ucout << U("Press ENTER key to quit...") << std::endl;
        std::string line;
        std::getline(std::cin, line);
        handler.close().wait();
    }
    catch (std::exception& ex)
    {
        ucout << U("Exception: ") << ex.what() << std::endl;
        ucout << U("Press ENTER key to quit...") << std::endl;
        std::string line;
        std::getline(std::cin, line);
    }
    return 0;
}

下面是访问结果

ex.what() << std::endl;
ucout << U(“Press ENTER key to quit…”) << std::endl;
std::string line;
std::getline(std::cin, line);
}
return 0;
}

下面是访问结果

![image.png](https://imgconvert.csdnimg.cn/aHR0cDovL3VwbG9hZC1pbWFnZXMuamlhbnNodS5pby91cGxvYWRfaW1hZ2VzLzczMTAyNTEtNGM4MzFkNGRlMGI4NDMzOS5wbmc)
相关标签: linux cpprestsdk