This patch adds BigFileURL and BigSizeMB parameters.

If uploaded DIR is bigger than BigSizeMB, then it is not attached
to the case, but uploaded to BigFileURL, then a comment is added
to the case with the URL of uploaded file.

-- 
vda

diff -x '*.po' -d -urpN libreport.5/src/plugins/abrt_rh_support.c 
libreport.6/src/plugins/abrt_rh_support.c
--- libreport.5/src/plugins/abrt_rh_support.c   2013-02-07 14:31:32.000000000 
+0100
+++ libreport.6/src/plugins/abrt_rh_support.c   2013-03-22 13:53:33.069697211 
+0100
@@ -108,9 +108,11 @@ xxmlTextWriterWriteString(xmlTextWriterP
 #endif

 //
+// Reportfile helpers
+//
+
 // End the reportfile, and prepare it for delivery.
 // No more bindings can be added after this.
-//
 static void
 close_writer(reportfile_t* file)
 {
@@ -123,9 +125,7 @@ close_writer(reportfile_t* file)
     file->writer = NULL;
 }

-//
 // This allocates a reportfile_t structure and initializes it.
-//
 reportfile_t*
 new_reportfile(void)
 {
@@ -159,9 +159,7 @@ internal_reportfile_start_binding(report
         xxmlTextWriterWriteAttribute(file->writer, "type", "text");
 }

-//
 // Add a new text binding
-//
 void
 reportfile_add_binding_from_string(reportfile_t* file, const char* name, const 
char* value)
 {
@@ -171,9 +169,7 @@ reportfile_add_binding_from_string(repor
     xxmlTextWriterEndElement(file->writer);
 }

-//
 // Add a new binding to a report whose value is represented as a file.
-//
 void
 reportfile_add_binding_from_namedfile(reportfile_t* file,
                 const char* on_disk_filename, /* unused so far */
@@ -189,9 +185,7 @@ reportfile_add_binding_from_namedfile(re
     free(href_name);
 }

-//
 // Return the contents of the reportfile as a string.
-//
 const char*
 reportfile_as_string(reportfile_t* file)
 {
@@ -222,9 +216,27 @@ void free_rhts_result(rhts_result_t *p)
 }

 //
-// create_new_case()
+// Common
 //
+static const char *const text_plain_header[] = {
+    "Accept: text/plain",
+    NULL
+};

+//
+// Creating new case
+// See
+// 
https://access.redhat.com/knowledge/docs/Red_Hat_Customer_Portal/integration_guide.html
+//
+// $ curl -X POST -H 'Content-Type: application/xml' --data
+//  '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+//   <case xmlns="http://www.redhat.com/gss/strata";>
+//   <summary>Example Case</summary>
+//   <description>Example created with cURL</description>
+//   <product>Red Hat Enterprise Linux</product><version>6.0</version>
+//   </case>'
+//   https://api.access.redhat.com/rs/cases
+//
 static char*
 make_case_data(const char* summary, const char* description,
                const char* product, const char* version,
@@ -261,52 +273,6 @@ make_case_data(const char* summary, cons
     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);
-        }
-    }
-
-    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
-
-static const char *const text_plain_header[] = {
-    "Accept: text/plain",
-    NULL
-};
-
 static rhts_result_t*
 post_case_to_url(const char* url,
                 const char* username,
@@ -332,23 +298,23 @@ post_case_to_url(const char* url,

     int redirect_count = 0;
     char *errmsg;
-    post_state_t *case_state;
+    post_state_t *post_state;

- redirect_case:
-    case_state = new_post_state(0
+ redirect:
+    post_state = new_post_state(0
             + POST_WANT_HEADERS
             + POST_WANT_BODY
             + POST_WANT_ERROR_MSG
             + (ssl_verify ? POST_WANT_SSL_VERIFY : 0)
     );
-    case_state->username = username;
-    case_state->password = password;
+    post_state->username = username;
+    post_state->password = password;

-    post_string(case_state, url, "application/xml", additional_headers, 
case_data);
+    post_string(post_state, url, "application/xml", additional_headers, 
case_data);

-    char *case_location = find_header_in_post_state(case_state, "Location:");
+    char *location = find_header_in_post_state(post_state, "Location:");

-    switch (case_state->http_resp_code)
+    switch (post_state->http_resp_code)
     {
     case 404:
         /* Not strictly necessary (default branch would deal with it too),
@@ -363,12 +329,12 @@ post_case_to_url(const char* url,
     case 301: /* "301 Moved Permanently" (for example, used to move http:// to 
https://) */
     case 302: /* "302 Found" (just in case) */
     case 305: /* "305 Use Proxy" */
-        if (++redirect_count < 10 && case_location)
+        if (++redirect_count < 10 && location)
         {
             free(url_copy);
-            url = url_copy = xstrdup(case_location);
-            free_post_state(case_state);
-            goto redirect_case;
+            url = url_copy = xstrdup(location);
+            free_post_state(post_state);
+            goto redirect;
         }
         /* fall through */

@@ -388,42 +354,236 @@ post_case_to_url(const char* url,
         // '^M'
         // ' '  <------ body is useless
         result->error = -1;
-        errmsg = case_state->curl_error_msg;
+        errmsg = post_state->curl_error_msg;
         if (errmsg && errmsg[0])
         {
             result->msg = xasprintf(_("Error in case creation: %s"), errmsg);
         }
         else
         {
-            errmsg = find_header_in_post_state(case_state, "Strata-Message:");
+            errmsg = find_header_in_post_state(post_state, "Strata-Message:");
             if (!errmsg)
-                errmsg = case_state->body;
+                errmsg = post_state->body;
             if (errmsg && errmsg[0])
                 result->msg = xasprintf(_("Error in case creation, HTTP code: 
%d, server says: '%s'"),
-                        case_state->http_resp_code, errmsg);
+                        post_state->http_resp_code, errmsg);
             else
                 result->msg = xasprintf(_("Error in case creation, HTTP code: 
%d"),
-                        case_state->http_resp_code);
+                        post_state->http_resp_code);
         }
         break;

     case 200:
     case 201:
-        /* Cose created successfully */
-        result->url = xstrdup(case_location); /* note: xstrdup(NULL) returns 
NULL */
-        //result->msg = xstrdup("Case created");
+        /* Created successfully */
+        result->url = xstrdup(location); /* note: xstrdup(NULL) returns NULL */
     } /* switch (HTTP code) */

-    result->http_resp_code = case_state->http_resp_code;
-    result->body = case_state->body;
-    case_state->body = NULL;
+    result->http_resp_code = post_state->http_resp_code;
+    result->body = post_state->body;
+    post_state->body = NULL;

-    free_post_state(case_state);
+    free_post_state(post_state);
     free(case_data);
     free(url_copy);
     return result;
 }

+rhts_result_t*
+create_new_case(const char* base_url,
+                const char* username,
+                const char* password,
+                bool ssl_verify,
+                const char* release,
+                const char* summary,
+                const char* description,
+                const char* component)
+{
+    char *url = concat_path_file(base_url, "cases");
+    rhts_result_t *result = post_case_to_url(url,
+                username,
+                password,
+                ssl_verify,
+                (const char **)text_plain_header,
+                release,
+                summary,
+                description,
+                component
+    );
+    free(url);
+
+    if (!result->error && !result->url)
+    {
+        /* Case Creation returned valid code, but no location */
+        result->error = -1;
+        free(result->msg);
+        result->msg = xasprintf(_("Error in case creation: no Location URL, 
HTTP code: %d"),
+                result->http_resp_code
+        );
+    }
+
+    return result;
+}
+
+//
+// Add case comment
+//
+// $ curl -X POST -H 'Content-Type: application/xml' --data
+//  '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+//   <comment xmlns="http://www.redhat.com/gss/strata";>
+//   <text>Test comment!  This can contain lots of information, etc.</text>
+//   </comment>'
+//   https://api.access.redhat.com/rs/cases/NNNNNNN/comments
+//
+static char*
+make_comment_data(const char *comment_text)
+{
+    char *retval;
+    xmlTextWriterPtr writer;
+    xmlBufferPtr buf;
+
+    buf = xxmlBufferCreate();
+    writer = xxmlNewTextWriterMemory(buf);
+
+    xxmlTextWriterStartDocument(writer, NULL, "UTF-8", "yes");
+    xxmlTextWriterStartElement(writer, "comment");
+    xxmlTextWriterWriteAttribute(writer, "xmlns",
+                                   "http://www.redhat.com/gss/strata";);
+
+    xxmlTextWriterWriteElement(writer, "text", comment_text);
+
+    xxmlTextWriterEndDocument(writer);
+    retval = xstrdup((const char*)buf->content);
+    xmlFreeTextWriter(writer);
+    xmlBufferFree(buf);
+    return retval;
+}
+
+static rhts_result_t*
+post_comment_to_url(const char *url,
+                const char *username,
+                const char *password,
+                bool ssl_verify,
+                const char **additional_headers,
+                const char *comment_text)
+{
+    rhts_result_t *result = xzalloc(sizeof(*result));
+    char *url_copy = NULL;
+
+    char *xml = make_comment_data(comment_text);
+
+    int redirect_count = 0;
+    char *errmsg;
+    post_state_t *post_state;
+
+ redirect:
+    post_state = new_post_state(0
+            + POST_WANT_HEADERS
+            + POST_WANT_BODY
+            + POST_WANT_ERROR_MSG
+            + (ssl_verify ? POST_WANT_SSL_VERIFY : 0)
+    );
+    post_state->username = username;
+    post_state->password = password;
+
+    post_string(post_state, url, "application/xml", additional_headers, xml);
+
+    char *location = find_header_in_post_state(post_state, "Location:");
+
+    switch (post_state->http_resp_code)
+    {
+    case 404:
+        /* Not strictly necessary (default branch would deal with it too),
+         * but makes this typical error less cryptic:
+         * instead of returning html-encoded body, we show short concise 
message,
+         * and show offending URL (typos in which is a typical cause) */
+        result->error = -1;
+        result->msg = xasprintf("Error in HTTP POST, "
+                        "HTTP code: 404 (Not found), URL:'%s'", url);
+        break;
+
+    case 301: /* "301 Moved Permanently" (for example, used to move http:// to 
https://) */
+    case 302: /* "302 Found" (just in case) */
+    case 305: /* "305 Use Proxy" */
+        if (++redirect_count < 10 && location)
+        {
+            free(url_copy);
+            url = url_copy = xstrdup(location);
+            free_post_state(post_state);
+            goto redirect;
+        }
+        /* fall through */
+
+    default:
+        result->error = -1;
+        errmsg = post_state->curl_error_msg;
+        if (errmsg && errmsg[0])
+        {
+            result->msg = xasprintf(_("Error in comment creation: %s"), 
errmsg);
+        }
+        else
+        {
+            errmsg = find_header_in_post_state(post_state, "Strata-Message:");
+            if (!errmsg)
+                errmsg = post_state->body;
+            if (errmsg && errmsg[0])
+                result->msg = xasprintf(_("Error in comment creation, HTTP 
code: %d, server says: '%s'"),
+                        post_state->http_resp_code, errmsg);
+            else
+                result->msg = xasprintf(_("Error in comment creation, HTTP 
code: %d"),
+                        post_state->http_resp_code);
+        }
+        break;
+
+    case 200:
+    case 201:
+        /* Created successfully */
+        result->url = xstrdup(location); /* note: xstrdup(NULL) returns NULL */
+    } /* switch (HTTP code) */
+
+    result->http_resp_code = post_state->http_resp_code;
+    result->body = post_state->body;
+    post_state->body = NULL;
+
+    free_post_state(post_state);
+    free(xml);
+    free(url_copy);
+    return result;
+}
+
+rhts_result_t*
+add_comment_to_case(const char* base_url,
+                const char* username,
+                const char* password,
+                bool ssl_verify,
+                const char* comment_text)
+{
+    char *url = concat_path_file(base_url, "comments");
+    rhts_result_t *result = post_comment_to_url(url,
+                username,
+                password,
+                ssl_verify,
+                (const char **)text_plain_header,
+                comment_text
+    );
+    free(url);
+
+    if (!result->error && !result->url)
+    {
+        /* Creation returned valid code, but no location */
+        result->error = -1;
+        free(result->msg);
+        result->msg = xasprintf(_("Error in comment creation: no Location URL, 
HTTP code: %d"),
+                result->http_resp_code
+        );
+    }
+
+    return result;
+}
+
+//
+// Attach file to case
+//
 static rhts_result_t*
 post_file_to_url(const char* url,
                 const char* username,
@@ -522,41 +682,28 @@ post_file_to_url(const char* url,
 }

 rhts_result_t*
-create_new_case(const char* base_url,
+attach_file_to_case(const char* base_url,
                 const char* username,
                 const char* password,
                 bool ssl_verify,
-                const char* release,
-                const char* summary,
-                const char* description,
-                const char* component)
+                const char *file_name)
 {
-    char *url = concat_path_file(base_url, "cases");
-    rhts_result_t *result = post_case_to_url(url,
+    char *url = concat_path_file(base_url, "attachments");
+    rhts_result_t *result = post_file_to_url(url,
                 username,
                 password,
                 ssl_verify,
-                (const char **)text_plain_header,
-                release,
-                summary,
-                description,
-                component
+                /*post_as_form:*/ true,
+                (const char **) text_plain_header,
+                file_name
     );
     free(url);
-
-    if (!result->error && !result->url)
-    {
-        /* Case Creation returned valid code, but no location */
-        result->error = -1;
-        free(result->msg);
-        result->msg = xasprintf(_("Error in case creation: no Location URL, 
HTTP code: %d"),
-                result->http_resp_code
-        );
-    }
-
     return result;
 }

+//
+// Get hint
+//
 rhts_result_t*
 get_rhts_hints(const char* base_url,
                 const char* username,
@@ -584,25 +731,5 @@ get_rhts_hints(const char* base_url,
                 file_name
     );
     free(url);
-    return result;
-}
-
-rhts_result_t*
-attach_file_to_case(const char* base_url,
-                const char* username,
-                const char* password,
-                bool ssl_verify,
-                const char *file_name)
-{
-    char *url = concat_path_file(base_url, "attachments");
-    rhts_result_t *result = post_file_to_url(url,
-                username,
-                password,
-                ssl_verify,
-                /*post_as_form:*/ true,
-                (const char **) text_plain_header,
-                file_name
-    );
-    free(url);
     return result;
 }
diff -x '*.po' -d -urpN libreport.5/src/plugins/abrt_rh_support.h 
libreport.6/src/plugins/abrt_rh_support.h
--- libreport.5/src/plugins/abrt_rh_support.h   2013-02-07 14:31:32.000000000 
+0100
+++ libreport.6/src/plugins/abrt_rh_support.h   2013-03-22 11:57:17.860089776 
+0100
@@ -70,6 +70,13 @@ create_new_case(const char* baseURL,
 );

 rhts_result_t*
+add_comment_to_case(const char* base_url,
+                const char* username,
+                const char* password,
+                bool ssl_verify,
+                const char* comment_text);
+
+rhts_result_t*
 attach_file_to_case(const char* baseURL,
                 const char* username,
                 const char* password,
diff -x '*.po' -d -urpN libreport.5/src/plugins/reporter-rhtsupport.c 
libreport.6/src/plugins/reporter-rhtsupport.c
--- libreport.5/src/plugins/reporter-rhtsupport.c       2013-03-22 
14:56:23.241918966 +0100
+++ libreport.6/src/plugins/reporter-rhtsupport.c       2013-03-22 
12:03:39.283404448 +0100
@@ -163,6 +163,15 @@ int create_tarball(const char *tempfile,
     return 1; /* failure */
 }

+static
+char *get_param_string(const char *name, map_string_h *settings, const char 
*dflt)
+{
+    char *envname = xasprintf("RHTSupport_%s", name);
+    const char *envvar = getenv(envname);
+    free(envname);
+    return xstrdup(envvar ? envvar : (get_map_string_item_or_NULL(settings, 
name) ? : dflt));
+}
+
 int main(int argc, char **argv)
 {
     abrt_init(argv);
@@ -189,7 +198,8 @@ int main(int argc, char **argv)
         "\n"
         "If not specified, CONFFILE defaults to 
"CONF_DIR"/plugins/rhtsupport.conf\n"
         "Its lines should have 'PARAM = VALUE' format.\n"
-        "Recognized string parameters: URL, Login, Password.\n"
+        "Recognized string parameters: URL, Login, Password, BigFileURL.\n"
+        "Recognized numeric parameter: BigSizeMB.\n"
         "Recognized boolean parameter (VALUE should be 1/0, yes/no): 
SSLVerify.\n"
         "Parameters can be overridden via $RHTSupport_PARAM environment 
variables.\n"
         "\n"
@@ -233,21 +243,21 @@ int main(int argc, char **argv)
         VERB3 log("Loaded '%s'", fn);
         conf_file = g_list_remove(conf_file, fn);
     }
-    char* envvar;
-    char *url;
-    char *login;
-    char *password;
-    bool ssl_verify;
-    envvar = getenv("RHTSupport_URL");
-    url = xstrdup(envvar ? envvar : (get_map_string_item_or_NULL(settings, 
"URL") ? : "https://api.access.redhat.com/rs";));
-    envvar = getenv("RHTSupport_Login");
-    login = xstrdup(envvar ? envvar : get_map_string_item_or_empty(settings, 
"Login"));
-    envvar = getenv("RHTSupport_Password");
-    password = xstrdup(envvar ? envvar : 
get_map_string_item_or_empty(settings, "Password"));
-    envvar = getenv("RHTSupport_SSLVerify");
-    ssl_verify = string_to_bool(envvar ? envvar : 
get_map_string_item_or_empty(settings, "SSLVerify"));
+    char *url      = get_param_string("URL"       , settings, 
"https://api.access.redhat.com/rs";);
+    char *login    = get_param_string("Login"     , settings, "");
+    char *password = get_param_string("Password"  , settings, "");
+    char *bigurl   = get_param_string("BigFileURL", settings, 
"ftp://dropbox.redhat.com/incoming/";);
     if (!login[0] || !password[0])
         error_msg_and_die(_("Empty RHTS login or password"));
+    char* envvar;
+    envvar = getenv("RHTSupport_SSLVerify");
+    bool ssl_verify = string_to_bool(
+                envvar ? envvar : (get_map_string_item_or_NULL(settings, 
"SSLVerify") ? : "1")
+    );
+    envvar = getenv("RHTSupport_BigSizeMB");
+    unsigned bigsize = xatoi_positive(
+                envvar ? envvar : (get_map_string_item_or_NULL(settings, 
"BigSizeMB") ? : "1000")
+    );
     free_map_string(settings);

     if (opts & OPT_t)
@@ -471,16 +481,44 @@ int main(int argc, char **argv)
             log("URL=%s", result->url);
         }
         /* else: error msg was already emitted by dd_opendir */
+
         url = result->url;
     }

-    /* Attach the tarball of -d DIR */
-    result_atch = attach_file_to_case(url,
-            login,
-            password,
-            ssl_verify,
-            tempfile
-    );
+    char *remote_filename = NULL;
+    if (bigsize != 0 && tempfile_size / (1024*1024) >= bigsize)
+    {
+        /* Upload tarball of -d DIR to "big file" FTP */
+        remote_filename = upload_file(bigurl, tempfile);
+    }
+    if (remote_filename)
+    {
+        /* Attach a comment where to find uploaded tarball.
+         * Do not translate this message - it goes to a server
+         * where *other people* will read it
+         */
+        char *comment_text = xasprintf(
+            "Problem data was uploaded to %s",
+            remote_filename
+        );
+        free(remote_filename);
+        result_atch = add_comment_to_case(url,
+                login, password,
+                ssl_verify,
+                comment_text
+        );
+        free(comment_text);
+    }
+    else
+    {
+        /* Attach the tarball of -d DIR */
+        result_atch = attach_file_to_case(url,
+                login, password,
+                ssl_verify,
+                tempfile
+
+        );
+    }
     if (result_atch->error)
     {
         if (!(opts & OPT_t))

Reply via email to