使用restbed 构建了一个C++ 嵌入式 web server。api 使用了POST json 实现
#include <string>
#include <cstring>
#include <memory>
#include <cstdlib>
#include <fstream>
#include <restbed>
#include <chrono>
#include <streambuf>
#include <sstream>
#include <restbed>
#include <iostream>
using namespace std;
using namespace restbed;
class splitstring : public string {
vector<string> flds;
public:
splitstring(char *s) : string(s) { };
vector<string>& split(char delim, int rep=0);
};
vector<string>& splitstring::split(char delim, int rep) {
if (!flds.empty()) flds.clear(); // empty vector if necessary
string work = data();
string buf = "";
int i = 0;
while (i < work.length()) {
if (work[i] != delim)
buf += work[i];
else if (rep == 1) {
flds.push_back(buf);
buf = "";
} else if (buf.length() > 0) {
flds.push_back(buf);
buf = "";
}
i++;
}
if (!buf.empty())
flds.push_back(buf);
return flds;
}
bool sendFile(string path,string type,const shared_ptr< Session > session )
{
ifstream stream( path, ifstream::in );
if ( stream.is_open() )
{
const string body = string( istreambuf_iterator< char >( stream ), istreambuf_iterator< char >( ) );
const multimap< string, string > headers
{
{ "Content-Type", type },
{ "Content-Length", to_string( body.length( ) ) }
};
session->close( OK, body, headers );
}
else
{
session->close( NOT_FOUND );
};
return true;
}
void post_method_handler( const shared_ptr< Session > session )
{
const auto& request = session->get_request( );
string path=request->get_path();
cout<<"request path: "<<path<<endl;
const string body ="{\"jsonrpc\":\"2.0\",\"result\":\"OK\"}";
const multimap< string, string > headers
{
{ "Content-Type", "application/x-www-form-urlencoded"},
{ "Content-Length", to_string( body.length( ) ) }
};
session->close( OK, body, headers );
}
void get_method_handler( const shared_ptr< Session > session )
{
const auto& request = session->get_request( );
string path=request->get_path();
cout<<"request path: "<<path<<endl;
char * writable = new char[path.size() + 1];
std::copy(path.begin(), path.end(), writable);
writable[path.size()] = '\0';
splitstring uri(writable);
vector<string> detail= uri.split('/') ;
delete[] writable;
const string filename = detail[2];
string type=detail[1];
if (type.compare("views")==0)
{
sendFile("./views/"+filename,"text/html",session);
}
else if (type.compare("css")==0)
{
sendFile("./css/"+filename,"text/css",session);
}
else if (type.compare("js")==0)
{
sendFile("./js/"+filename,"text/js",session);
} else if (type.compare("images")==0)
{ char * p=strchr(path.c_str(), '.');
string ext(p);
sendFile("./images/"+filename,"image/"+ext,session);
} else
session->close( NOT_FOUND );
}
int main( const int, const char** )
{
auto resource = make_shared< Resource >( );
resource->set_path( "/home/.*/.*" );
resource->set_method_handler( "GET", get_method_handler );
auto resource1 = make_shared< Resource >( );
resource1->set_path( "/api/.*" );
resource1->set_method_handler( "POST", post_method_handler );
auto settings = make_shared< Settings >( );
settings->set_port( 2019 );
settings->set_default_header( "Connection", "close" );
Service service;
service.publish( resource );
service.publish( resource1 );
service.start( settings );
return EXIT_SUCCESS;
}
test.html
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>C++ App</title>
<link rel="stylesheet" href="/home/css/bootstrap.css">
<script src="/home/js/jquery.js" type="text/javascript"></script>
<script>
function api_request()
{
var jsonrpc={
"jsonrpc":"2.0",
"method":"hello",
}
console.log(jsonrpc);
$.ajax({ type: "POST",
url: "/api/hello",
contentType: "application/x-www-form-urlencoded",
data: JSON.stringify(jsonrpc) ,
dataType: "json",
success:function (message) {
console.log(message);
console.log(message.result);
},
error:function (message) { console.log("error"+JSON.parse(message)); } });
}
</script>
</head>
<body class="container">
<h1 class="text-info"> websocketpp </h1>
<p> hello the world </p>
<img src="/home/images/logo.png" width="300"></img>
<button class="btn-info btn" onclick="api_request()">API Request</button>
</body>
</html>
浏览器访问:
http://localhost:2019/home/views/test.html
供参考。