diff options
-rw-r--r-- | lib/Plugins/rhticket.cpp | 84 | ||||
-rw-r--r-- | lib/Utils/abrt_rh_support.cpp | 246 | ||||
-rw-r--r-- | lib/Utils/abrt_rh_support.h | 11 |
3 files changed, 265 insertions, 76 deletions
diff --git a/lib/Plugins/rhticket.cpp b/lib/Plugins/rhticket.cpp index d0a72735..8a2e8325 100644 --- a/lib/Plugins/rhticket.cpp +++ b/lib/Plugins/rhticket.cpp @@ -20,6 +20,7 @@ #define _GNU_SOURCE 1 /* for stpcpy */ #include "abrtlib.h" #include "abrt_curl.h" +#include "abrt_rh_support.h" #include "CrashTypes.h" #include "DebugDump.h" #include "ABRTException.h" @@ -32,6 +33,7 @@ using namespace std; +#if 0 //unused static char *xml_escape(const char *str) { const char *s = str; @@ -80,6 +82,7 @@ static char *xml_escape(const char *str) *d = '\0'; return result; } +#endif /* @@ -104,55 +107,62 @@ string CReporterRHticket::Report(const map_crash_data_t& pCrashData, // const string& arch = get_crash_data_item_content(pCrashData, FILENAME_ARCHITECTURE); // const string& duphash = get_crash_data_item_content(pCrashData, CD_DUPHASH); const char *reason = get_crash_data_item_content_or_NULL(pCrashData, FILENAME_REASON); + const char *function = get_crash_data_item_content_or_NULL(pCrashData, FILENAME_CRASH_FUNCTION); - string summary = "[abrt] crash in " + package; - if (reason != NULL) + string summary = "[abrt] " + package; + if (function && strlen(function) < 30) + { + summary += ": "; + summary += function; + } + if (reason) { summary += ": "; summary += reason; } -// string status_whiteboard = "abrt_hash:" + duphash; - string description = "abrt "VERSION" detected a crash.\n\n"; + string description = "abrt version: "VERSION"\n"; description += make_description_bz(pCrashData); -// string product; -// string version; -// parse_release(release.c_str(), product, version); - - char *xml_summary = xml_escape(summary.c_str()); - char *xml_description = xml_escape(description.c_str()); - string postdata = ssprintf( - "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" - "<IssueTrackerCase xmlns=\"http://www.redhat.com/gss/strata\">" - "<name>%s</name>" - "<description>%s</description>" - // "<reference></reference><notes></notes><tags></tags>" - "</IssueTrackerCase>", - xml_summary, - xml_description - ); - free(xml_summary); - free(xml_description); - string url = concat_path_file(m_sStrataURL.c_str(), "cases"); - - abrt_post_state *state = new_abrt_post_state(0 - + ABRT_POST_WANT_HEADERS - + ABRT_POST_WANT_ERROR_MSG); - int http_resp_code = abrt_post_string(state, url.c_str(), "application/xml", postdata.c_str()); + reportfile_t* file = new_reportfile(); - if (http_resp_code / 100 != 2) + // TODO: some files are totally useless: + // "Reported", "Message" (plugin's output), "DumpDir", + // "Description" (package description) - maybe skip those? + map_crash_data_t::const_iterator it = pCrashData.begin(); + for (; it != pCrashData.end(); it++) { - /* not 2xx */ - string errmsg = state->curl_error_msg ? state->curl_error_msg : "(none)"; - free_abrt_post_state(state); - throw CABRTException(EXCEP_PLUGIN, _("server returned HTTP code %u, error message: %s"), - http_resp_code, errmsg.c_str()); + const char *content = it->second[CD_CONTENT].c_str(); + if (it->second[CD_TYPE] == CD_TXT) + { + reportfile_add_binding_from_string(file, it->first.c_str(), content); + } + else if (it->second[CD_TYPE] == CD_BIN) + { + reportfile_add_binding_from_namedfile(file, content, it->first.c_str(), content, /*binary:*/ 1); + } } - string result = find_header_in_abrt_post_state(state, "Location:") ? : ""; - free_abrt_post_state(state); - return result; + update_client(_("Creating a new case...")); +// const char* filename = reportfile_as_file(file); + char* result = send_report_to_new_case(m_sStrataURL.c_str(), + m_sLogin.c_str(), + m_sPassword.c_str(), + summary.c_str(), + description.c_str(), + package.c_str(), + "/dev/null" //filename + ); + VERB3 log("post result:'%s'", result); + string retval = result; + reportfile_free(file); + free(result); + + if (strncasecmp(retval.c_str(), "error", 5) == 0) + { + throw CABRTException(EXCEP_PLUGIN, "%s", retval.c_str()); + } + return retval; } void CReporterRHticket::SetSettings(const map_plugin_settings_t& pSettings) diff --git a/lib/Utils/abrt_rh_support.cpp b/lib/Utils/abrt_rh_support.cpp index 61341c0e..425c7e73 100644 --- a/lib/Utils/abrt_rh_support.cpp +++ b/lib/Utils/abrt_rh_support.cpp @@ -90,14 +90,12 @@ xxmlTextWriterEndElement(xmlTextWriterPtr writer) die_xml_oom(); } -#if 0 //unused static void xxmlTextWriterWriteElement(xmlTextWriterPtr writer, const char *name, const char *content) { if (xmlTextWriterWriteElement(writer, (unsigned char*)name, (unsigned char*)content) < 0) die_xml_oom(); } -#endif static void xxmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const char *name, const char *content) @@ -218,6 +216,9 @@ reportfile_free(reportfile_t* file) } +// +// post_signature() +// char* post_signature(const char* baseURL, const char* signature) { @@ -274,42 +275,215 @@ post_signature(const char* baseURL, const char* signature) return retval; } -#if 0 -const char* -create_case(const char* baseURL, const char* description) + +// +// send_report_to_new_case() +// + +static char* +make_case_data(const char* summary, const char* description, + const char* product, const char* version, + const char* component) { - const char* URL = concat_path_file(baseURL, "/cases"); - const char* retval; - - response_data_t* response_data = post(URL, description); - if (!response_data) - return NULL; - - switch (response_data->code) { - case 200: - case 201: - if (response_data->body && strlen(response_data->body) > 0) { - retval = response_data->body; - response_data->body = NULL; + char* retval; + xmlTextWriterPtr writer; + xmlBufferPtr buf; + + buf = xxmlBufferCreate(); + writer = xxmlNewTextWriterMemory(buf); + + xxmlTextWriterStartDocument(writer, NULL, "UTF-8", "yes"); + xxmlTextWriterStartElement(writer, "case"); + xxmlTextWriterWriteAttribute(writer, "xmlns", + "http://www.redhat.com/gss/strata"); + + xxmlTextWriterWriteElement(writer, "summary", summary); + xxmlTextWriterWriteElement(writer, "description", description); + if (product) { + xxmlTextWriterWriteElement(writer, "product", product); + } + if (version) { + xxmlTextWriterWriteElement(writer, "version", version); + } + if (component) { + xxmlTextWriterWriteElement(writer, "component", component); + } + + xxmlTextWriterEndDocument(writer); + retval = xstrdup((const char*)buf->content); + xmlFreeTextWriter(writer); + xmlBufferFree(buf); + return retval; +} + +#if 0 //unused +static char* +make_response(const char* title, const char* body, + const char* actualURL, const char* displayURL) +{ + char* retval; + xmlTextWriterPtr writer; + xmlBufferPtr buf; + + buf = xxmlBufferCreate(); + writer = xxmlNewTextWriterMemory(buf); + + xxmlTextWriterStartDocument(writer, NULL, "UTF-8", "yes"); + xxmlTextWriterStartElement(writer, "response"); + if (title) { + xxmlTextWriterWriteElement(writer, "title", title); + } + if (body) { + xxmlTextWriterWriteElement(writer, "body", body); + } + if (actualURL || displayURL) { + xxmlTextWriterStartElement(writer, "URL"); + if (actualURL) { + xxmlTextWriterWriteAttribute(writer, "href", actualURL); + } + if (displayURL) { + xxmlTextWriterWriteString(writer, displayURL); + } } - else - retval = ssprintf("Case Created: %s\n", response_data->location); - break; - default: - if (response_data->strata_message) - retval = ssprintf("Error: %s (http code %ld)", - response_data->strata_message, - response_data->code ); - else - retval = ssprintf("Error: Response Code: %ld\nBody:\n%s", response_data->code, response_data->body); - } - free_abrt_post_state(state); - free((void*)response_data->strata_message); - free((void*)response_data->body); - free((void*)response_data->location); - free((void *)response_data); - free((void*)URL); - return retval; + xxmlTextWriterEndDocument(writer); + retval = xstrdup((const char*)buf->content); + xmlFreeTextWriter(writer); + xmlBufferFree(buf); + return retval; } +//Example: +//<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +//<response><title>Case Created and Report Attached</title><body></body><URL href="http://support-services-devel.gss.redhat.com:8080/Strata/cases/00005129/attachments/ccbf3e65-b941-3db7-a016-6a3831691a32">New Case URL</URL></response> #endif + +char* +send_report_to_new_case(const char* baseURL, + const char* username, + const char* password, + const char* summary, + const char* description, + const char* component, + const char* report_file_name) +{ + string case_url = concat_path_file(baseURL, "/cases"); + + char *case_data = make_case_data(summary, description, + "Red Hat Enterprise Linux", "6.0", + component); + + int redirect_count = 0; + char *errmsg; + char *allocated = NULL; + char* retval = NULL; + abrt_post_state *case_state; + + redirect_case: + case_state = new_abrt_post_state(0 + + ABRT_POST_WANT_HEADERS + + ABRT_POST_WANT_BODY + + ABRT_POST_WANT_ERROR_MSG); + case_state->username = username; + case_state->password = password; + abrt_post_string(case_state, case_url.c_str(), "application/xml", case_data); + + char *case_location = find_header_in_abrt_post_state(case_state, "Location:"); + switch (case_state->http_resp_code) + { + case 305: /* "305 Use Proxy" */ + if (++redirect_count < 10 && case_location) { + case_url = case_location; + free_abrt_post_state(case_state); + goto redirect_case; + } + /* fall through */ + + default: + errmsg = find_header_in_abrt_post_state(case_state, "Strata-Message:"); + if (!errmsg && case_state->body && case_state->body[0]) + errmsg = case_state->body; + if (errmsg) + retval = xasprintf("error in case creation, server says: '%s'", errmsg); + else + retval = xasprintf("error in case creation, HTTP code: %d", + case_state->http_resp_code); + break; + + case 200: + case 201: + if (!case_location) { + /* Case Creation returned valid code, but no location */ + retval = xasprintf("error in case creation: no Location URL, HTTP code: %d", + case_state->http_resp_code); + break; + } + + string atch_url = concat_path_file(case_location, "/attachments"); + abrt_post_state *atch_state; + redirect_attach: + atch_state = new_abrt_post_state(0 + + ABRT_POST_WANT_HEADERS + + ABRT_POST_WANT_BODY + + ABRT_POST_WANT_ERROR_MSG); + atch_state->username = username; + atch_state->password = password; + abrt_post_file_as_form(atch_state, atch_url.c_str(), "application/binary", report_file_name); + + char *atch_location = find_header_in_abrt_post_state(atch_state, "Location:"); + switch (atch_state->http_resp_code) + { + case 305: /* "305 Use Proxy" */ + if (++redirect_count < 10 && atch_location) { + atch_url = atch_location; + free_abrt_post_state(atch_state); + goto redirect_attach; + } + /* fall through */ + + default: + /* Case Creation Succeeded, attachement FAILED */ + errmsg = find_header_in_abrt_post_state(atch_state, "Strata-Message:"); + if (!errmsg && atch_state->body && atch_state->body[0]) + errmsg = atch_state->body; + if (case_state->body && case_state->body[0]) + { + if (errmsg) /* both bodies are present */ + allocated = errmsg = xasprintf("%s. %s", + case_state->body, + errmsg); + else /* only ticket body exists */ + allocated = errmsg = xasprintf("%s. HTTP code %d", + case_state->body, + atch_state->http_resp_code); + } else { /* there were no body in ticket response */ + if (!errmsg) /* ...and neither in attach response */ + allocated = errmsg = xasprintf( + "HTTP code %d", + atch_state->http_resp_code); + /* else: only attach body exists */ + } + retval = xasprintf("Case created: %s, but report attachment failed: %s", + case_location, errmsg); + break; + + case 200: + case 201: + char *body = atch_state->body; + if (case_state->body && case_state->body[0]) + { + body = case_state->body; + if (atch_state->body && atch_state->body[0]) + allocated = body = xasprintf("%s\n%s", + case_state->body, + atch_state->body); + } + retval = xasprintf("Case created: %s", /*body,*/ case_location); + } /* switch (attach HTTP code) */ + free_abrt_post_state(atch_state); + + } /* switch (ticket HTTP code) */ + + free_abrt_post_state(case_state); + free(allocated); + return retval; +} diff --git a/lib/Utils/abrt_rh_support.h b/lib/Utils/abrt_rh_support.h index 567fd0e9..dcc87091 100644 --- a/lib/Utils/abrt_rh_support.h +++ b/lib/Utils/abrt_rh_support.h @@ -34,8 +34,13 @@ void reportfile_add_binding_from_namedfile(reportfile_t* file, const char* reportfile_as_string(reportfile_t* file); char* post_signature(const char* baseURL, const char* signature); -#if 0 -char* create_case(const char* baseURL, const char* description); -#endif +char* +send_report_to_new_case(const char* baseURL, + const char* username, + const char* password, + const char* summary, + const char* description, + const char* component, + const char* report_file_name); #endif |