From bb4b9e195dc19e62cace5fba5765880fe49a05df Mon Sep 17 00:00:00 2001 From: Stan Cox Date: Wed, 29 Nov 2017 11:30:47 -0500 Subject: [PATCH] Send client http info as a single json form. * client-http.cxx (http_client::get_data): Create and send as a single json form. * httpd/server.cxx (get_key_values): Load key values from json form. --- client-http.cxx | 87 +++++++++++++++++++++++++++++------------------- httpd/server.cxx | 30 +++++++++++++++++ 2 files changed, 82 insertions(+), 35 deletions(-) diff --git a/client-http.cxx b/client-http.cxx index aa9b73f82..6a771f7db 100644 --- a/client-http.cxx +++ b/client-http.cxx @@ -113,8 +113,6 @@ http_client::get_data (void *ptr, size_t size, size_t nitems) enum json_tokener_error json_error; root = json_tokener_parse_verbose (data.c_str(), &json_error); - if (s.verbose >= 3) - clog << json_object_to_json_string (root) << endl; if (root == NULL) throw SEMANTIC_ERROR (json_tokener_error_desc (json_error)); } @@ -534,18 +532,40 @@ http_client::post (const string & url, int still_running = false; struct curl_httppost *formpost = NULL; struct curl_httppost *lastptr = NULL; + struct json_object *jobj = json_object_new_object(); - headers = curl_slist_append (headers, "Expect:"); - - for (auto it = request_parameters.begin (); - it != request_parameters.end (); ++it) + string previous_parm_type; + string previous_json_data; + auto it = request_parameters.begin (); + while (it != request_parameters.end ()) { string parm_type = get<0>(*it); string parm_data = get<1>(*it); - curl_formadd (&formpost, &lastptr, - CURLFORM_COPYNAME, parm_type.c_str(), - CURLFORM_COPYCONTENTS, parm_data.c_str(), - CURLFORM_END); + struct json_object *json_data = json_object_new_string(parm_data.c_str()); + if (parm_type == previous_parm_type) + { + // convert original singleton to an array + struct json_object *jarr = json_object_new_array(); + json_data = json_object_new_string(previous_json_data.c_str()); + json_object_array_add(jarr, json_data); + while (parm_type == previous_parm_type) + { + json_data = json_object_new_string(parm_data.c_str()); + json_object_array_add(jarr, json_data); + previous_parm_type = parm_type; + previous_json_data = parm_data; + it++; + parm_type = get<0>(*it); + parm_data = get<1>(*it); + } + json_object_object_add(jobj, previous_parm_type.c_str(), jarr); + continue; + } + else + json_object_object_add(jobj, parm_type.c_str(), json_data); + previous_parm_type = parm_type; + previous_json_data = parm_data; + it++; } // Fill in the file upload field; libcurl will load data from the @@ -591,29 +611,25 @@ http_client::post (const string & url, // // So, the items are arranged by index - item N in each array are // related information. + struct json_object *file_pkg = json_object_new_array(); + struct json_object *file_name = json_object_new_array(); + struct json_object *file_id = json_object_new_array(); int bid_idx = 0; + for (auto it = modules.begin (); it != modules.end (); ++it, ++bid_idx) { string pkg = (*it); string buildid_file = std::get<0>(buildids[bid_idx]); string buildid = std::get<1>(buildids[bid_idx]); - curl_formadd (&formpost, &lastptr, - CURLFORM_COPYNAME, "file_pkg", - CURLFORM_CONTENTTYPE, "application/json", - CURLFORM_COPYCONTENTS, pkg.c_str(), - CURLFORM_END); - curl_formadd (&formpost, &lastptr, - CURLFORM_COPYNAME, "file_name", - CURLFORM_CONTENTTYPE, "application/json", - CURLFORM_COPYCONTENTS, buildid_file.c_str(), - CURLFORM_END); - curl_formadd (&formpost, &lastptr, - CURLFORM_COPYNAME, "file_id", - CURLFORM_CONTENTTYPE, "application/json", - CURLFORM_COPYCONTENTS, buildid.c_str(), - CURLFORM_END); + json_object_array_add(file_pkg, json_object_new_string(pkg.c_str())); + json_object_array_add(file_name, json_object_new_string(buildid_file.c_str())); + json_object_array_add(file_id, json_object_new_string(buildid.c_str())); } + json_object_object_add(jobj, "file_pkg", file_pkg); + json_object_object_add(jobj, "file_name", file_name); + json_object_object_add(jobj, "file_id", file_id); + if (! http->localization_variables.empty()) { @@ -623,19 +639,20 @@ http_client::post (const string & url, { string name = get<0>(*i); string value = get<1>(*i); - curl_formadd (&formpost, &lastptr, - CURLFORM_COPYNAME, "env_var_names", - CURLFORM_CONTENTTYPE, "application/json", - CURLFORM_COPYCONTENTS, name.c_str(), - CURLFORM_END); - curl_formadd (&formpost, &lastptr, - CURLFORM_COPYNAME, "env_var_values", - CURLFORM_CONTENTTYPE, "application/json", - CURLFORM_COPYCONTENTS, value.c_str(), - CURLFORM_END); + json_object_object_add(jobj, name.c_str(), json_object_new_string(value.c_str())); } } + curl_formadd (&formpost, &lastptr, + CURLFORM_COPYNAME, "command_environment", + CURLFORM_CONTENTTYPE, "application/json", + CURLFORM_COPYCONTENTS, + json_object_to_json_string_ext (jobj, JSON_C_TO_STRING_PLAIN), + CURLFORM_END); + json_object_put(jobj); + + headers = curl_slist_append (headers, "Expect:"); + curl_easy_setopt (curl, CURLOPT_URL, url.c_str()); curl_easy_setopt (curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt (curl, CURLOPT_HTTPPOST, formpost); diff --git a/httpd/server.cxx b/httpd/server.cxx index 881275b0f..8836d28f6 100644 --- a/httpd/server.cxx +++ b/httpd/server.cxx @@ -20,6 +20,7 @@ extern "C" #include #include #include +#include } using namespace std; @@ -29,6 +30,35 @@ get_key_values(void *cls, enum MHD_ValueKind /*kind*/, const char *key, const char *value) { post_params_t *params = static_cast(cls); + if (value[0] == '{') + { + enum json_tokener_error json_error; + json_object *root = json_tokener_parse_verbose (value, &json_error); + if (root == NULL) + { + clog << json_tokener_error_desc (json_error); + return MHD_NO; + } + + json_object_object_foreach(root, jkey, jval) + { + if (json_object_get_type(jval) == json_type_array) + { + for (int i = 0; i < json_object_array_length (jval); i++) + { + json_object *jarrval = json_object_array_get_idx(jval, i); + const char* jvalue = json_object_get_string(jarrval); + (*params)[jkey].push_back(jvalue ? jvalue : ""); + } + } + else + { + const char* jvalue = json_object_get_string(jval); + (*params)[jkey].push_back(jvalue ? jvalue : ""); + } + } + return MHD_YES; + } (*params)[key].push_back(value ? value : ""); return MHD_YES; -- 2.43.5