/** Implementation of rpc_send function required by the management API. * * This is the function that will be called whenever a management function * asks the management interface to send the reply to the client. * The SIP/HTTP reply sent to * the client will be always 200 OK, if an error ocurred on the server then it * will be indicated in the html document in body. * * @param ctx A pointer to the context structure of the xhttp_rpc request that * generated the reply. * @return 1 if the reply was already sent, 0 on success, a negative number on * error */ static int rpc_send(rpc_ctx_t* ctx) { struct xhttp_rpc_reply* reply; if (ctx->reply_sent) return 1; reply = &ctx->reply; if (0!=xhttp_rpc_build_page(ctx)){ rpc_fault(ctx, 500, "Internal Server Error"); } ctx->reply_sent = 1; if (reply->body.len) xhttp_api.reply(ctx->msg, reply->code, &reply->reason, &XHTTP_RPC_CONTENT_TYPE_TEXT_HTML, &reply->body); else xhttp_api.reply(ctx->msg, reply->code, &reply->reason, &XHTTP_RPC_CONTENT_TYPE_TEXT_HTML, &reply->reason); if (reply->buf.s) { pkg_free(reply->buf.s); reply->buf.s = NULL; reply->buf.len = 0; } if (ctx->arg.s) { pkg_free(ctx->arg.s); ctx->arg.s = NULL; ctx->arg.len = 0; } if (ctx->data_structs) { free_data_struct(ctx->data_structs); ctx->data_structs = NULL; } return 0; }
/** Implementation of rpc_send function required by the management API. * * This is the function that will be called whenever a management function * asks the management interface to send the reply to the client. * The SIP/HTTP reply sent to * the client will be always 200 OK, if an error ocurred on the server then it * will be indicated in the html document in body. * * @param ctx A pointer to the context structure of the jsonrpc request that * generated the reply. * @return 1 if the reply was already sent, 0 on success, a negative number on * error */ static int jsonrpc_send(jsonrpc_ctx_t* ctx) { srjson_t *nj = NULL; int i; str rbuf; if (ctx->reply_sent) return 1; ctx->reply_sent = 1; if(ctx->error_code != 0) { /* fault handling */ nj = srjson_CreateObject(ctx->jrpl); if(nj!=NULL) { srjson_AddNumberToObject(ctx->jrpl, nj, "code", ctx->error_code); for(i=0; _jsonrpc_error_table[i].code!=0 && _jsonrpc_error_table[i].code!=ctx->error_code; i++); if(_jsonrpc_error_table[i].code!=0) { srjson_AddStrStrToObject(ctx->jrpl, nj, "message", 7, _jsonrpc_error_table[i].text.s, _jsonrpc_error_table[i].text.len); } else { srjson_AddStrStrToObject(ctx->jrpl, nj, "message", 7, "Unexpected Error", 16); } srjson_AddItemToObject(ctx->jrpl, ctx->jrpl->root, "error", nj); } } else { nj = srjson_GetObjectItem(ctx->jrpl, ctx->jrpl->root, "result"); if(nj==NULL) { if (!ctx->rpl_node) { if(ctx->flags & RET_ARRAY) { ctx->rpl_node = srjson_CreateArray(ctx->jrpl); } else { ctx->rpl_node = srjson_CreateObject(ctx->jrpl); } if(ctx->rpl_node == 0) { LM_ERR("failed to create the root array node\n"); } } srjson_AddItemToObject(ctx->jrpl, ctx->jrpl->root, "result", ctx->rpl_node); ctx->rpl_node = 0; } } nj = srjson_GetObjectItem(ctx->jreq, ctx->jreq->root, "id"); if(nj!=NULL) { if(nj->valuestring!=NULL) { srjson_AddStrStrToObject(ctx->jrpl, ctx->jrpl->root, "id", 2, nj->valuestring, strlen(nj->valuestring)); } else { srjson_AddNumberToObject(ctx->jrpl, ctx->jrpl->root, "id", nj->valuedouble); } } if(jsonrpc_pretty_format==0) { rbuf.s = srjson_PrintUnformatted(ctx->jrpl, ctx->jrpl->root); } else { rbuf.s = srjson_Print(ctx->jrpl, ctx->jrpl->root); } if(rbuf.s!=NULL) { rbuf.len = strlen(rbuf.s); } if (rbuf.s!=NULL) { LM_DBG("sending response with body: %p - %d %.*s\n", ctx->msg, ctx->http_code, ctx->http_text.len, ctx->http_text.s); if(ctx->msg) { xhttp_api.reply(ctx->msg, ctx->http_code, &ctx->http_text, &JSONRPC_CONTENT_TYPE_HTML, &rbuf); } else { jsonrpc_set_plain_reply(ctx->http_code, &ctx->http_text, &rbuf, ctx->jrpl->free_fn); rbuf.s=NULL; } } else { LM_DBG("sending response without body: %p - %d %.*s\n", ctx->msg, ctx->http_code, ctx->http_text.len, ctx->http_text.s); if(ctx->msg) { xhttp_api.reply(ctx->msg, ctx->http_code, &ctx->http_text, NULL, NULL); } else { jsonrpc_set_plain_reply(ctx->http_code, &ctx->http_text, NULL, ctx->jrpl->free_fn); } } if (rbuf.s!=NULL) { ctx->jrpl->free_fn(rbuf.s); } return 0; }