test_httpApi.cpp 4.52 KB
Newer Older
xiongziliang committed
1
/*
xiongziliang committed
2
 * Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
xiongziliang committed
3 4 5
 *
 * This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
 *
xiongziliang committed
6 7 8
 * Use of this source code is governed by MIT license that can be found in the
 * LICENSE file in the root of the source tree. All contributing project authors
 * may be found in the AUTHORS file in the root of the source tree.
xiongziliang committed
9 10 11 12 13 14
 */

#include <map>
#include <signal.h>
#include <iostream>
#include "Util/File.h"
xiongziliang committed
15
#include "Util/SSLBox.h"
xiongziliang committed
16 17
#include "Util/logger.h"
#include "Util/onceToken.h"
xiongziliang committed
18
#include "Util/NoticeCenter.h"
xiongziliang committed
19 20
#include "Network/TcpServer.h"
#include "Poller/EventPoller.h"
xiongziliang committed
21 22
#include "Common/config.h"
#include "Http/WebSocketSession.h"
xiongziliang committed
23 24

using namespace std;
xiongziliang committed
25 26
using namespace toolkit;
using namespace mediakit;
xiongziliang committed
27

xiongziliang committed
28 29 30 31 32 33 34 35 36
namespace mediakit {
////////////HTTP配置///////////
namespace Http {
#define HTTP_FIELD "http."
#define HTTP_PORT 80
const char kPort[] = HTTP_FIELD"port";
#define HTTPS_PORT 443
extern const char kSSLPort[] = HTTP_FIELD"sslport";
onceToken token1([](){
37 38
    mINI::Instance()[kPort] = HTTP_PORT;
    mINI::Instance()[kSSLPort] = HTTPS_PORT;
xiongziliang committed
39 40 41 42
},nullptr);
}//namespace Http
}  // namespace mediakit

xiongziliang committed
43
void initEventListener(){
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
    static onceToken s_token([](){
        NoticeCenter::Instance().addListener(nullptr,Broadcast::kBroadcastHttpRequest,[](BroadcastHttpRequestArgs){
            //const Parser &parser,HttpSession::HttpResponseInvoker &invoker,bool &consumed
            if(strstr(parser.Url().data(),"/api/") != parser.Url().data()){
                return;
            }
            //url以"/api/起始,说明是http api"
            consumed = true;//该http请求已被消费

            _StrPrinter printer;
            ////////////////method////////////////////
            printer << "\r\nmethod:\r\n\t" << parser.Method();
            ////////////////url/////////////////
            printer << "\r\nurl:\r\n\t" << parser.Url();
            ////////////////protocol/////////////////
            printer << "\r\nprotocol:\r\n\t" << parser.Tail();
            ///////////////args//////////////////
            printer << "\r\nargs:\r\n";
            for(auto &pr : parser.getUrlArgs()){
                printer <<  "\t" << pr.first << " : " << pr.second << "\r\n";
            }
            ///////////////header//////////////////
            printer << "\r\nheader:\r\n";
xiongziliang committed
67
            for(auto &pr : parser.getHeader()){
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
                printer <<  "\t" << pr.first << " : " << pr.second << "\r\n";
            }
            ////////////////content/////////////////
            printer << "\r\ncontent:\r\n" << parser.Content();
            auto contentOut = printer << endl;

            ////////////////我们测算异步回复,当然你也可以同步回复/////////////////
            EventPollerPool::Instance().getPoller()->async([invoker,contentOut](){
                HttpSession::KeyValue headerOut;
                //你可以自定义header,如果跟默认header重名,则会覆盖之
                //默认header有:Server,Connection,Date,Content-Type,Content-Length
                //请勿覆盖Connection、Content-Length键
                //键名覆盖时不区分大小写
                headerOut["TestHeader"] = "HeaderValue";
                invoker("200 OK",headerOut,contentOut);
            });
        });
    }, nullptr);
xiongziliang committed
86
}
xiongziliang committed
87 88

int main(int argc,char *argv[]){
89 90 91
    //设置退出信号处理函数
    static semaphore sem;
    signal(SIGINT, [](int) { sem.post(); });// 设置退出信号
92

93 94 95
    //设置日志
    Logger::Instance().add(std::make_shared<ConsoleChannel>());
    Logger::Instance().setWriter(std::make_shared<AsyncLogWriter>());
96

97 98 99
    //加载配置文件,如果配置文件不存在就创建一个
    loadIniConfig();
    initEventListener();
xiongziliang committed
100

101 102 103 104 105 106
    //加载证书,证书包含公钥和私钥
    SSL_Initor::Instance().loadCertificate((exeDir() + "ssl.p12").data());
    //信任某个自签名证书
    SSL_Initor::Instance().trustCertificate((exeDir() + "ssl.p12").data());
    //不忽略无效证书证书(例如自签名或过期证书)
    SSL_Initor::Instance().ignoreInvalidCertificate(false);
107

xiongziliang committed
108

109 110 111
    //开启http服务器
    TcpServer::Ptr httpSrv(new TcpServer());
    httpSrv->start<HttpSession>(mINI::Instance()[Http::kPort]);//默认80
xiongziliang committed
112 113

    //如果支持ssl,还可以开启https服务器
114 115
    TcpServer::Ptr httpsSrv(new TcpServer());
    httpsSrv->start<HttpsSession>(mINI::Instance()[Http::kSSLPort]);//默认443
xiongziliang committed
116

117
    InfoL << "你可以在浏览器输入:http://127.0.0.1/api/my_api?key0=val0&key1=参数1" << endl;
xiongziliang committed
118

119 120
    sem.wait();
    return 0;
xiongziliang committed
121 122
}