Repository: ossrs/srs
File: trunk/src/app/srs_app_http_hooks.cpp (C++)

Code before:
    port = (int)prop->to_integer();
    
    srs_trace("http: cluster redirect %s:%d ok, url=%s, response=%s", host.c_str(), port, url.c_str(), res.c_str());
    
    return err;
}

// Request:
//      POST /api/v1/forward
//      {
//          "action": "on_forward",
//          "server_id": "vid-k21d7y2",
//          "client_id": "9o7g1330",
//          "ip": "127.0.0.1",
//          "vhost": "__defaultVhost__",
//          "app": "live",
//          "tcUrl": "rtmp://127.0.0.1:1935/live",
//          "stream": "livestream",
//          "param": "?forward=rtmp://ossrs.net/live/livestream"
//      }
// Response:
//      {
//          "code": 0,
//          "data": {
//              "forwards":[{
//                  "url": "rtmp://ossrs.net:1935/live/livestream?auth_token=xxx"
//               },{
//                  "url": "rtmp://aliyuncdn.com:1935/live/livestream?auth_token=xxx"
//               }]
//          }
//      }
srs_error_t SrsHttpHooks::on_forward_backend(string url, SrsRequest* req, std::vector<std::string>& rtmp_urls)
{
    srs_error_t err = srs_success;

    SrsContextId cid = _srs_context->get_id();

    SrsStatistic* stat = SrsStatistic::instance();

    SrsJsonObject* obj = SrsJsonAny::object();
    SrsAutoFree(SrsJsonObject, obj);

    obj->set("action", SrsJsonAny::str("on_forward"));
    obj->set("server_id", SrsJsonAny::str(stat->server_id().c_str()));
    obj->set("client_id", SrsJsonAny::str(cid.c_str()));
    obj->set("ip", SrsJsonAny::str(req->ip.c_str()));
    obj->set("vhost", SrsJsonAny::str(req->vhost.c_str()));
    obj->set("app", SrsJsonAny::str(req->app.c_str()));
    obj->set("tcUrl", SrsJsonAny::str(req->tcUrl.c_str()));
    obj->set("stream", SrsJsonAny::str(req->stream.c_str()));
    obj->set("param", SrsJsonAny::str(req->param.c_str()));

Review comment (suggestion):
```
data: {
  urls: ["rtmp://xxx", "rtmp://xxx"]
}
```

If you want to expand: 

```
data {
   forwards: xxx
}
```

`TRANS_BY_GPT3`

Code after:
    port = (int)prop->to_integer();
    
    srs_trace("http: cluster redirect %s:%d ok, url=%s, response=%s", host.c_str(), port, url.c_str(), res.c_str());
    
    return err;
}

srs_error_t SrsHttpHooks::on_forward_backend(string url, SrsRequest* req, std::vector<std::string>& rtmp_urls)
{
    srs_error_t err = srs_success;

    SrsContextId cid = _srs_context->get_id();

    SrsStatistic* stat = SrsStatistic::instance();

    SrsJsonObject* obj = SrsJsonAny::object();
    SrsAutoFree(SrsJsonObject, obj);

    obj->set("action", SrsJsonAny::str("on_forward"));
    obj->set("server_id", SrsJsonAny::str(stat->server_id().c_str()));
    obj->set("client_id", SrsJsonAny::str(cid.c_str()));
    obj->set("ip", SrsJsonAny::str(req->ip.c_str()));
    obj->set("vhost", SrsJsonAny::str(req->vhost.c_str()));
    obj->set("app", SrsJsonAny::str(req->app.c_str()));
    obj->set("tcUrl", SrsJsonAny::str(req->tcUrl.c_str()));
    obj->set("stream", SrsJsonAny::str(req->stream.c_str()));
    obj->set("param", SrsJsonAny::str(req->param.c_str()));

    std::string data = obj->dumps();
    std::string res;
    int status_code;

    SrsHttpClient http;
    if ((err = do_post(&http, url, data, status_code, res)) != srs_success) {
        return srs_error_wrap(err, "http: on_forward_backend failed, client_id=%s, url=%s, request=%s, response=%s, code=%d",
            cid.c_str(), url.c_str(), data.c_str(), res.c_str(), status_code);
    }

    // parse string res to json.
    SrsJsonAny* info = SrsJsonAny::loads(res);
    if (!info) {
        return srs_error_new(ERROR_SYSTEM_FORWARD_LOOP, "load json from %s", res.c_str());
    }
    SrsAutoFree(SrsJsonAny, info);

    // response error code in string.
    if (!info->is_object()) {
        return srs_error_new(ERROR_SYSTEM_FORWARD_LOOP, "response %s", res.c_str());
    }

    SrsJsonAny* prop = NULL;