Signed-off-by: Jakub Filak jfilak@redhat.com --- src/plugins/ureport.c | 108 +++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 91 insertions(+), 17 deletions(-)
diff --git a/src/plugins/ureport.c b/src/plugins/ureport.c index ed01cc7..777e454 100644 --- a/src/plugins/ureport.c +++ b/src/plugins/ureport.c @@ -17,9 +17,66 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
+#include <json/json.h> #include "internal_libreport.h" #include "abrt_curl.h"
+enum response_type +{ + UREPORT_SERVER_RESP_UNKNOWN_TYPE, + UREPORT_SERVER_RESP_KNOWN, + UREPORT_SERVER_RESP_ERROR, +}; + +struct ureport_server_response { + enum response_type type; + const char *value; +}; + +/* + * Reponse samples: + * {"type":"error", "value":"field 'foo' is required"} + * {"type":"known", "value":true} + * {"type":"known", "value":false} + */ +static bool ureport_server_parse_json(json_object *json, struct ureport_server_response *out_response) +{ + { + json_object *const j = json_object_object_get(json, "type"); + if (!j) + { + log("'type' section is not available"); + return false; + } + + const char *type = json_object_to_json_string(j); + + if (!strcmp(type,""known"")) + out_response->type = UREPORT_SERVER_RESP_KNOWN; + else if (!strcmp(type,""error"")) + out_response->type = UREPORT_SERVER_RESP_ERROR; + else + { + log("unknow server response type : '%s'", type); + out_response = UREPORT_SERVER_RESP_UNKNOWN_TYPE; + return true; + } + } + + { + json_object *const j = json_object_object_get(json, "value"); + if (!j) + { + log("'value' section is not available"); + return false; + } + + out_response->value = xstrdup(json_object_to_json_string(j)); + } + + return true; +} + int main(int argc, char **argv) { abrt_init(argv); @@ -63,30 +120,47 @@ int main(int argc, char **argv) } }
- // TODO : parse JSON response - char *line = strtok(post_state->body, "\n"); - VERB2 log("Response:\n----\n%s\n----", line); + int ret = 1; /* return 1 by default */ + json_object *const json = json_tokener_parse(post_state->body);
- int ret = 0; - while (line) + if (is_error(json)) + error_msg("fatal: unable parse response from ureport server"); + else { - if (!prefixcmp(line, "ERROR ")) - { - log("%s", line); - ret = 1; - break; - } + struct ureport_server_response response = {.type=UREPORT_SERVER_RESP_UNKNOWN_TYPE, + .value=NULL}; + const bool is_valid_response = ureport_server_parse_json(json, &response);
- if (!prefixcmp(line, "NEEDMORE")) + if (!is_valid_response) + error_msg("fatal: wrong format of response from ureport server"); + else { - log("%s", line); - ret = 0; - break; + switch (response.type) + { + case UREPORT_SERVER_RESP_KNOWN: + VERB1 log("is known: %s", response.value); + ret = 0; + /* If a reported problem is not known then emit NEEDMORE */ + if (strcmp("true",response.value)) + log("NEEDMORE"); + break; + case UREPORT_SERVER_RESP_ERROR: + ret = 1; /* just to be sure */ + break; + case UREPORT_SERVER_RESP_UNKNOWN_TYPE: + error_msg("invalid server response: %s", response.value); + ret = 1; /* just to be sure */ + break; + default: + error_msg("reporter internal error: missing handler for response type"); + ret = 1; /* just to be sure */ + break; + } + free((void*)response.value); } - - line = strtok(NULL, "\n"); }
+ json_object_put(json); free_abrt_post_state(post_state);
return ret;