Blame view

trunk/src/app/srs_app_http_api.cpp 21.5 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
/*
The MIT License (MIT)

Copyright (c) 2013-2014 winlin

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include <srs_app_http_api.hpp>
26
#ifdef SRS_AUTO_HTTP_API
winlin authored
27
winlin authored
28 29 30
#include <sstream>
using namespace std;
31 32
#include <srs_kernel_log.hpp>
#include <srs_kernel_error.hpp>
33
#include <srs_app_st_socket.hpp>
winlin authored
34
#include <srs_core_autofree.hpp>
35
#include <srs_app_json.hpp>
winlin authored
36
#include <srs_kernel_utility.hpp>
37
#include <srs_app_utility.hpp>
38
winlin authored
39 40
SrsApiRoot::SrsApiRoot()
{
41
    handlers.push_back(new SrsApiApi());
winlin authored
42 43 44 45 46 47
}

SrsApiRoot::~SrsApiRoot()
{
}
48 49 50 51 52 53 54
bool SrsApiRoot::is_handler_valid(SrsHttpMessage* req, int& status_code, std::string& reason_phrase) 
{
    if (!SrsHttpHandler::is_handler_valid(req, status_code, reason_phrase)) {
        return false;
    }
    
    if (req->match()->matched_url.length() != 1) {
winlin authored
55 56
        status_code = SRS_CONSTS_HTTP_NotFound;
        reason_phrase = SRS_CONSTS_HTTP_NotFound_str;
57 58 59 60 61 62
        return false;
    }
    
    return true;
}
63
bool SrsApiRoot::can_handle(const char* path, int /*length*/, const char** pchild)
winlin authored
64
{
65 66 67
    // reset the child path to path,
    // for child to reparse the path.
    *pchild = path;
68
    
69 70
    // only compare the first char.
    return srs_path_equals("/", path, 1);
winlin authored
71 72
}
73
int SrsApiRoot::do_process_request(SrsStSocket* skt, SrsHttpMessage* req)
winlin authored
74
{
75 76
    std::stringstream ss;
    
winlin authored
77 78 79 80 81 82
    ss << __SRS_JOBJECT_START
        << __SRS_JFIELD_ERROR(ERROR_SUCCESS) << __SRS_JFIELD_CONT
        << __SRS_JFIELD_ORG("urls", __SRS_JOBJECT_START)
            << __SRS_JFIELD_STR("api", "the api root")
        << __SRS_JOBJECT_END
        << __SRS_JOBJECT_END;
83
    
84
    return res_json(skt, req, ss.str());
85 86 87 88
}

SrsApiApi::SrsApiApi()
{
89
    handlers.push_back(new SrsApiV1());
90 91 92 93 94 95
}

SrsApiApi::~SrsApiApi()
{
}
96
bool SrsApiApi::can_handle(const char* path, int length, const char** /*pchild*/)
97
{
98
    return srs_path_equals("/api", path, length);
99 100
}
101
int SrsApiApi::do_process_request(SrsStSocket* skt, SrsHttpMessage* req)
102
{
103 104
    std::stringstream ss;
    
winlin authored
105 106 107 108 109 110
    ss << __SRS_JOBJECT_START
        << __SRS_JFIELD_ERROR(ERROR_SUCCESS) << __SRS_JFIELD_CONT
        << __SRS_JFIELD_ORG("urls", __SRS_JOBJECT_START)
            << __SRS_JFIELD_STR("v1", "the api version 1.0")
        << __SRS_JOBJECT_END
        << __SRS_JOBJECT_END;
111
    
112
    return res_json(skt, req, ss.str());
113 114 115 116 117
}

SrsApiV1::SrsApiV1()
{
    handlers.push_back(new SrsApiVersion());
winlin authored
118 119
    handlers.push_back(new SrsApiSummaries());
    handlers.push_back(new SrsApiRusages());
120 121
    handlers.push_back(new SrsApiSelfProcStats());
    handlers.push_back(new SrsApiSystemProcStats());
winlin authored
122
    handlers.push_back(new SrsApiMemInfos());
123
    handlers.push_back(new SrsApiAuthors());
124
    handlers.push_back(new SrsApiRequests());
125 126 127 128 129 130 131 132 133 134 135
}

SrsApiV1::~SrsApiV1()
{
}

bool SrsApiV1::can_handle(const char* path, int length, const char** /*pchild*/)
{
    return srs_path_equals("/v1", path, length);
}
136
int SrsApiV1::do_process_request(SrsStSocket* skt, SrsHttpMessage* req)
137 138 139
{
    std::stringstream ss;
    
winlin authored
140 141 142 143 144 145 146 147 148 149 150 151 152
    ss << __SRS_JOBJECT_START
        << __SRS_JFIELD_ERROR(ERROR_SUCCESS) << __SRS_JFIELD_CONT
        << __SRS_JFIELD_ORG("urls", __SRS_JOBJECT_START)
            << __SRS_JFIELD_STR("versions", "the version of SRS") << __SRS_JFIELD_CONT
            << __SRS_JFIELD_STR("summaries", "the summary(pid, argv, pwd, cpu, mem) of SRS") << __SRS_JFIELD_CONT
            << __SRS_JFIELD_STR("rusages", "the rusage of SRS") << __SRS_JFIELD_CONT
            << __SRS_JFIELD_STR("self_proc_stats", "the self process stats") << __SRS_JFIELD_CONT
            << __SRS_JFIELD_STR("system_proc_stats", "the system process stats") << __SRS_JFIELD_CONT
            << __SRS_JFIELD_STR("meminfos", "the meminfo of system") << __SRS_JFIELD_CONT
            << __SRS_JFIELD_STR("authors", "the primary authors and contributors") << __SRS_JFIELD_CONT
            << __SRS_JFIELD_STR("requests", "the request itself, for http debug")
        << __SRS_JOBJECT_END
        << __SRS_JOBJECT_END;
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
    
    return res_json(skt, req, ss.str());
}

SrsApiRequests::SrsApiRequests()
{
}

SrsApiRequests::~SrsApiRequests()
{
}

bool SrsApiRequests::can_handle(const char* path, int length, const char** /*pchild*/)
{
    return srs_path_equals("/requests", path, length);
}
170
int SrsApiRequests::do_process_request(SrsStSocket* skt, SrsHttpMessage* req)
171 172 173
{
    std::stringstream ss;
    
winlin authored
174 175 176 177 178
    ss << __SRS_JOBJECT_START
        << __SRS_JFIELD_ERROR(ERROR_SUCCESS) << __SRS_JFIELD_CONT
        << __SRS_JFIELD_ORG("data", __SRS_JOBJECT_START)
            << __SRS_JFIELD_STR("uri", req->uri()) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_STR("path", req->path()) << __SRS_JFIELD_CONT;
179 180 181
    
    // method
    if (req->is_http_get()) {
winlin authored
182
        ss  << __SRS_JFIELD_STR("METHOD", "GET");
183
    } else if (req->is_http_post()) {
winlin authored
184
        ss  << __SRS_JFIELD_STR("METHOD", "POST");
185
    } else if (req->is_http_put()) {
winlin authored
186
        ss  << __SRS_JFIELD_STR("METHOD", "PUT");
187
    } else if (req->is_http_delete()) {
winlin authored
188
        ss  << __SRS_JFIELD_STR("METHOD", "DELETE");
189
    } else {
winlin authored
190
        ss  << __SRS_JFIELD_ORG("METHOD", req->method());
191
    }
winlin authored
192
    ss << __SRS_JFIELD_CONT;
193 194
    
    // request headers
winlin authored
195
    ss      << __SRS_JFIELD_NAME("headers") << __SRS_JOBJECT_START;
196 197 198 199
    for (int i = 0; i < req->request_header_count(); i++) {
        std::string key = req->request_header_key_at(i);
        std::string value = req->request_header_value_at(i);
        if ( i < req->request_header_count() - 1) {
winlin authored
200
            ss      << __SRS_JFIELD_STR(key, value) << __SRS_JFIELD_CONT;
201
        } else {
winlin authored
202
            ss      << __SRS_JFIELD_STR(key, value);
203 204
        }
    }
winlin authored
205
    ss      << __SRS_JOBJECT_END << __SRS_JFIELD_CONT;
206 207
    
    // server informations
winlin authored
208 209 210 211 212 213 214 215 216
    ss      << __SRS_JFIELD_NAME("server") << __SRS_JOBJECT_START
                << __SRS_JFIELD_STR("sigature", RTMP_SIG_SRS_KEY) << __SRS_JFIELD_CONT
                << __SRS_JFIELD_STR("name", RTMP_SIG_SRS_NAME) << __SRS_JFIELD_CONT
                << __SRS_JFIELD_STR("version", RTMP_SIG_SRS_VERSION) << __SRS_JFIELD_CONT
                << __SRS_JFIELD_STR("link", RTMP_SIG_SRS_URL) << __SRS_JFIELD_CONT
                << __SRS_JFIELD_ORG("time", srs_get_system_time_ms())
            << __SRS_JOBJECT_END
        << __SRS_JOBJECT_END
        << __SRS_JOBJECT_END;
217
    
218
    return res_json(skt, req, ss.str());
219 220 221 222 223 224 225 226 227 228 229 230
}

SrsApiVersion::SrsApiVersion()
{
}

SrsApiVersion::~SrsApiVersion()
{
}

bool SrsApiVersion::can_handle(const char* path, int length, const char** /*pchild*/)
{
winlin authored
231
    return srs_path_equals("/versions", path, length);
232 233
}
234
int SrsApiVersion::do_process_request(SrsStSocket* skt, SrsHttpMessage* req)
235 236 237
{
    std::stringstream ss;
    
winlin authored
238 239 240 241 242 243 244 245 246
    ss << __SRS_JOBJECT_START
        << __SRS_JFIELD_ERROR(ERROR_SUCCESS) << __SRS_JFIELD_CONT
        << __SRS_JFIELD_ORG("data", __SRS_JOBJECT_START)
            << __SRS_JFIELD_ORG("major", VERSION_MAJOR) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("minor", VERSION_MINOR) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("revision", VERSION_REVISION) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_STR("version", RTMP_SIG_SRS_VERSION)
        << __SRS_JOBJECT_END
        << __SRS_JOBJECT_END;
247
    
248
    return res_json(skt, req, ss.str());
249 250
}
winlin authored
251 252 253 254 255 256 257 258 259 260 261 262 263
SrsApiSummaries::SrsApiSummaries()
{
}

SrsApiSummaries::~SrsApiSummaries()
{
}

bool SrsApiSummaries::can_handle(const char* path, int length, const char** /*pchild*/)
{
    return srs_path_equals("/summaries", path, length);
}
264
int SrsApiSummaries::do_process_request(SrsStSocket* skt, SrsHttpMessage* req)
winlin authored
265 266
{
    std::stringstream ss;
267
    srs_api_dump_summaries(ss);
winlin authored
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
    return res_json(skt, req, ss.str());
}

SrsApiRusages::SrsApiRusages()
{
}

SrsApiRusages::~SrsApiRusages()
{
}

bool SrsApiRusages::can_handle(const char* path, int length, const char** /*pchild*/)
{
    return srs_path_equals("/rusages", path, length);
}
284
int SrsApiRusages::do_process_request(SrsStSocket* skt, SrsHttpMessage* req)
winlin authored
285 286 287 288 289
{
    std::stringstream ss;
    
    SrsRusage* r = srs_get_system_rusage();
    
winlin authored
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312
    ss << __SRS_JOBJECT_START
        << __SRS_JFIELD_ERROR(ERROR_SUCCESS) << __SRS_JFIELD_CONT
        << __SRS_JFIELD_ORG("data", __SRS_JOBJECT_START)
            << __SRS_JFIELD_ORG("ok", (r->ok? "true":"false")) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("sample_time", r->sample_time) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("ru_utime", r->r.ru_utime.tv_sec) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("ru_stime", r->r.ru_stime.tv_sec) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("ru_maxrss", r->r.ru_maxrss) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("ru_ixrss", r->r.ru_ixrss) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("ru_idrss", r->r.ru_idrss) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("ru_isrss", r->r.ru_isrss) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("ru_minflt", r->r.ru_minflt) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("ru_majflt", r->r.ru_majflt) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("ru_nswap", r->r.ru_nswap) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("ru_inblock", r->r.ru_inblock) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("ru_oublock", r->r.ru_oublock) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("ru_msgsnd", r->r.ru_msgsnd) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("ru_msgrcv", r->r.ru_msgrcv) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("ru_nsignals", r->r.ru_nsignals) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("ru_nvcsw", r->r.ru_nvcsw) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("ru_nivcsw", r->r.ru_nivcsw)
        << __SRS_JOBJECT_END
        << __SRS_JOBJECT_END;
winlin authored
313 314 315 316
    
    return res_json(skt, req, ss.str());
}
317 318 319 320 321 322 323 324 325 326 327 328 329
SrsApiSelfProcStats::SrsApiSelfProcStats()
{
}

SrsApiSelfProcStats::~SrsApiSelfProcStats()
{
}

bool SrsApiSelfProcStats::can_handle(const char* path, int length, const char** /*pchild*/)
{
    return srs_path_equals("/self_proc_stats", path, length);
}
330
int SrsApiSelfProcStats::do_process_request(SrsStSocket* skt, SrsHttpMessage* req)
331 332 333 334 335
{
    std::stringstream ss;
    
    SrsProcSelfStat* u = srs_get_self_proc_stat();
    
winlin authored
336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387
    ss << __SRS_JOBJECT_START
        << __SRS_JFIELD_ERROR(ERROR_SUCCESS) << __SRS_JFIELD_CONT
        << __SRS_JFIELD_ORG("data", __SRS_JOBJECT_START)
            << __SRS_JFIELD_ORG("ok", (u->ok? "true":"false")) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("sample_time", u->sample_time) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("percent", u->percent) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("pid", u->pid) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_STR("comm", u->comm) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_STR("state", u->state) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("ppid", u->ppid) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("pgrp", u->pgrp) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("session", u->session) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("tty_nr", u->tty_nr) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("tpgid", u->tpgid) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("flags", u->flags) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("minflt", u->minflt) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("cminflt", u->cminflt) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("majflt", u->majflt) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("cmajflt", u->cmajflt) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("utime", u->utime) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("stime", u->stime) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("cutime", u->cutime) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("cstime", u->cstime) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("priority", u->priority) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("nice", u->nice) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("num_threads", u->num_threads) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("itrealvalue", u->itrealvalue) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("starttime", u->starttime) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("vsize", u->vsize) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("rss", u->rss) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("rsslim", u->rsslim) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("startcode", u->startcode) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("endcode", u->endcode) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("startstack", u->startstack) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("kstkesp", u->kstkesp) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("kstkeip", u->kstkeip) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("signal", u->signal) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("blocked", u->blocked) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("sigignore", u->sigignore) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("sigcatch", u->sigcatch) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("wchan", u->wchan) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("nswap", u->nswap) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("cnswap", u->cnswap) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("exit_signal", u->exit_signal) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("processor", u->processor) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("rt_priority", u->rt_priority) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("policy", u->policy) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("delayacct_blkio_ticks", u->delayacct_blkio_ticks) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("guest_time", u->guest_time) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("cguest_time", u->cguest_time)
        << __SRS_JOBJECT_END
        << __SRS_JOBJECT_END;
388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404
    
    return res_json(skt, req, ss.str());
}

SrsApiSystemProcStats::SrsApiSystemProcStats()
{
}

SrsApiSystemProcStats::~SrsApiSystemProcStats()
{
}

bool SrsApiSystemProcStats::can_handle(const char* path, int length, const char** /*pchild*/)
{
    return srs_path_equals("/system_proc_stats", path, length);
}
405
int SrsApiSystemProcStats::do_process_request(SrsStSocket* skt, SrsHttpMessage* req)
406 407 408 409 410
{
    std::stringstream ss;
    
    SrsProcSystemStat* s = srs_get_system_proc_stat();
    
winlin authored
411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427
    ss << __SRS_JOBJECT_START
        << __SRS_JFIELD_ERROR(ERROR_SUCCESS) << __SRS_JFIELD_CONT
        << __SRS_JFIELD_ORG("data", __SRS_JOBJECT_START)
            << __SRS_JFIELD_ORG("ok", (s->ok? "true":"false")) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("sample_time", s->sample_time) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("percent", s->percent) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("user", s->user) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("nice", s->nice) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("sys", s->sys) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("idle", s->idle) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("iowait", s->iowait) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("irq", s->irq) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("softirq", s->softirq) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("steal", s->steal) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("guest", s->guest)
        << __SRS_JOBJECT_END
        << __SRS_JOBJECT_END;
428 429 430 431
    
    return res_json(skt, req, ss.str());
}
winlin authored
432 433 434 435 436 437 438 439 440 441 442 443 444
SrsApiMemInfos::SrsApiMemInfos()
{
}

SrsApiMemInfos::~SrsApiMemInfos()
{
}

bool SrsApiMemInfos::can_handle(const char* path, int length, const char** /*pchild*/)
{
    return srs_path_equals("/meminfos", path, length);
}
445
int SrsApiMemInfos::do_process_request(SrsStSocket* skt, SrsHttpMessage* req)
winlin authored
446 447 448 449 450
{
    std::stringstream ss;
    
    SrsMemInfo* m = srs_get_meminfo();
    
winlin authored
451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468
    ss << __SRS_JOBJECT_START
        << __SRS_JFIELD_ERROR(ERROR_SUCCESS) << __SRS_JFIELD_CONT
        << __SRS_JFIELD_ORG("data", __SRS_JOBJECT_START)
            << __SRS_JFIELD_ORG("ok", (m->ok? "true":"false")) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("sample_time", m->sample_time) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("percent_ram", m->percent_ram) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("percent_swap", m->percent_swap) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("MemActive", m->MemActive) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("RealInUse", m->RealInUse) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("NotInUse", m->NotInUse) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("MemTotal", m->MemTotal) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("MemFree", m->MemFree) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("Buffers", m->Buffers) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("Cached", m->Cached) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("SwapTotal", m->SwapTotal) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_ORG("SwapFree", m->SwapFree)
        << __SRS_JOBJECT_END
        << __SRS_JOBJECT_END;
winlin authored
469 470 471 472
    
    return res_json(skt, req, ss.str());
}
473 474 475 476 477 478 479 480 481 482 483 484 485
SrsApiAuthors::SrsApiAuthors()
{
}

SrsApiAuthors::~SrsApiAuthors()
{
}

bool SrsApiAuthors::can_handle(const char* path, int length, const char** /*pchild*/)
{
    return srs_path_equals("/authors", path, length);
}
486
int SrsApiAuthors::do_process_request(SrsStSocket* skt, SrsHttpMessage* req)
487 488 489
{
    std::stringstream ss;
    
winlin authored
490 491 492
    ss << __SRS_JOBJECT_START
        << __SRS_JFIELD_ERROR(ERROR_SUCCESS) << __SRS_JFIELD_CONT
        << __SRS_JFIELD_ORG("data", __SRS_JOBJECT_START)
493 494
            << __SRS_JFIELD_STR("primary", RTMP_SIG_SRS_PRIMARY) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_STR("authors", RTMP_SIG_SRS_AUTHROS) << __SRS_JFIELD_CONT
winlin authored
495 496 497 498
            << __SRS_JFIELD_STR("contributors_link", RTMP_SIG_SRS_CONTRIBUTORS_URL) << __SRS_JFIELD_CONT
            << __SRS_JFIELD_STR("contributors", SRS_AUTO_CONSTRIBUTORS)
        << __SRS_JOBJECT_END
        << __SRS_JOBJECT_END;
499
    
500
    return res_json(skt, req, ss.str());
winlin authored
501 502 503
}

SrsHttpApi::SrsHttpApi(SrsServer* srs_server, st_netfd_t client_stfd, SrsHttpHandler* _handler) 
504 505
    : SrsConnection(srs_server, client_stfd)
{
winlin authored
506
    parser = new SrsHttpParser();
winlin authored
507
    handler = _handler;
508
    requires_crossdomain = false;
509 510
}
511
SrsHttpApi::~SrsHttpApi()
512
{
winlin authored
513
    srs_freep(parser);
514 515
}
516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532
void SrsHttpApi::kbps_resample()
{
    // TODO: FIXME: implements it
}

int64_t SrsHttpApi::get_send_bytes_delta()
{
    // TODO: FIXME: implements it
    return 0;
}

int64_t SrsHttpApi::get_recv_bytes_delta()
{
    // TODO: FIXME: implements it
    return 0;
}
533
int SrsHttpApi::do_cycle()
534 535 536
{
    int ret = ERROR_SUCCESS;
    
537
    srs_trace("api get peer ip success. ip=%s", ip.c_str());
538
    
winlin authored
539 540 541 542 543 544 545
    // initialize parser
    if ((ret = parser->initialize(HTTP_REQUEST)) != ERROR_SUCCESS) {
        srs_error("api initialize http parser failed. ret=%d", ret);
        return ret;
    }
    
    // underlayer socket
546
    SrsStSocket skt(stfd);
winlin authored
547 548 549 550 551 552 553 554 555 556 557 558 559 560 561
    
    // process http messages.
    for (;;) {
        SrsHttpMessage* req = NULL;
        
        // get a http message
        if ((ret = parser->parse_message(&skt, &req)) != ERROR_SUCCESS) {
            return ret;
        }

        // if SUCCESS, always NOT-NULL and completed message.
        srs_assert(req);
        srs_assert(req->is_complete());
        
        // always free it in this scope.
562
        SrsAutoFree(SrsHttpMessage, req);
winlin authored
563 564 565 566 567 568 569 570 571 572
        
        // ok, handle http request.
        if ((ret = process_request(&skt, req)) != ERROR_SUCCESS) {
            return ret;
        }
    }
        
    return ret;
}
573
int SrsHttpApi::process_request(SrsStSocket* skt, SrsHttpMessage* req) 
winlin authored
574 575
{
    int ret = ERROR_SUCCESS;
576 577 578 579 580

    // parse uri to schema/server:port/path?query
    if ((ret = req->parse_uri()) != ERROR_SUCCESS) {
        return ret;
    }
winlin authored
581
    
winlin authored
582 583
    srs_trace("HTTP %s %s, content-length=%"PRId64"", 
        req->method_str().c_str(), req->url().c_str(), req->content_length());
584
    
winlin authored
585
    // TODO: maybe need to parse the url.
586
    std::string url = req->path();
winlin authored
587
    
588 589
    SrsHttpHandlerMatch* p = NULL;
    if ((ret = handler->best_match(url.data(), url.length(), &p)) != ERROR_SUCCESS) {
winlin authored
590 591 592 593 594 595
        srs_warn("failed to find the best match handler for url. ret=%d", ret);
        return ret;
    }
    
    // if success, p and pstart should be valid.
    srs_assert(p);
596 597 598 599 600
    srs_assert(p->handler);
    srs_assert(p->matched_url.length() <= url.length());
    srs_info("best match handler, matched_url=%s", p->matched_url.c_str());
    
    req->set_match(p);
601
    req->set_requires_crossdomain(requires_crossdomain);
winlin authored
602 603
    
    // use handler to process request.
604
    if ((ret = p->handler->process_request(skt, req)) != ERROR_SUCCESS) {
winlin authored
605 606 607 608
        srs_warn("handler failed to process http request. ret=%d", ret);
        return ret;
    }
    
609 610 611 612
    if (req->requires_crossdomain()) {
        requires_crossdomain = true;
    }
    
613
    return ret;
614
}
winlin authored
615 616

#endif
617