static gboolean _xr_servlet_do_call(xr_servlet* servlet, xr_call* call) { xr_servlet_method_def* method; gboolean retval = FALSE; servlet->call = call; /* find method and perform a call */ method = _find_servlet_method_def(servlet, xr_call_get_method(call)); if (method) { if (servlet->def->pre_call) { if (!servlet->def->pre_call(servlet, call)) { // FALSE returned if (xr_call_get_retval(call) == NULL && !xr_call_get_error_code(call)) xr_call_set_error(call, -1, "Pre-call did not returned value or set error."); goto out; } } retval = method->cb(servlet, call); if (servlet->def->post_call) servlet->def->post_call(servlet, call); } else if (servlet->def->fallback) { if (servlet->def->fallback(servlet, call)) { // call should be handled if (xr_call_get_retval(call) == NULL && !xr_call_get_error_code(call)) xr_call_set_error(call, -1, "Fallback did not returned value or set error."); } else xr_call_set_error(call, -1, "Method %s not found in %s servlet.", xr_call_get_method(call), servlet->def->name); } else xr_call_set_error(call, -1, "Method %s not found in %s servlet.", xr_call_get_method(call), servlet->def->name); out: servlet->call = NULL; return retval; }
gboolean xr_client_call(xr_client_conn* conn, xr_call* call, GError** err) { char* buffer; int length; gboolean rs; gboolean write_success; GString* response; xr_trace(XR_DEBUG_CLIENT_TRACE, "(conn=%p, call=%p)", conn, call); g_return_val_if_fail(conn != NULL, FALSE); g_return_val_if_fail(call != NULL, FALSE); g_return_val_if_fail(err == NULL || *err == NULL, FALSE); if (!conn->is_open) { g_set_error(err, XR_CLIENT_ERROR, XR_CLIENT_ERROR_CLOSED, "Can't perform RPC on closed connection."); return FALSE; } /* serialize nad send XML-RPC request */ xr_call_set_transport(call, conn->transport); xr_call_serialize_request(call, &buffer, &length); xr_http_setup_request(conn->http, "POST", conn->resource, conn->host); g_hash_table_foreach(conn->headers, (GHFunc)_add_http_header, conn->http); if (conn->transport == XR_CALL_XML_RPC) xr_http_set_header(conn->http, "Content-Type", "text/xml"); #ifdef XR_JSON_ENABLED else if (conn->transport == XR_CALL_JSON_RPC) xr_http_set_header(conn->http, "Content-Type", "text/json"); #endif xr_http_set_message_length(conn->http, length); write_success = xr_http_write_all(conn->http, buffer, length, err); xr_call_free_buffer(call, buffer); if (!write_success) { xr_client_close(conn); return FALSE; } /* receive HTTP response header */ if (!xr_http_read_header(conn->http, err)) return FALSE; /* check if some dumb bunny sent us wrong message type */ if (xr_http_get_message_type(conn->http) != XR_HTTP_RESPONSE) return FALSE; response = xr_http_read_all(conn->http, err); if (response == NULL) { xr_client_close(conn); return FALSE; } rs = xr_call_unserialize_response(call, response->str, response->len); g_string_free(response, TRUE); if (!rs) { g_set_error(err, 0, xr_call_get_error_code(call), "%s", xr_call_get_error_message(call)); if (xr_debug_enabled & XR_DEBUG_CALL) xr_call_dump(call, 0); return FALSE; } if (xr_debug_enabled & XR_DEBUG_CALL) xr_call_dump(call, 0); return TRUE; }