|
Packit Service |
779887 |
/*
|
|
Packit Service |
779887 |
Copyright (C) 2010 ABRT team
|
|
Packit Service |
779887 |
Copyright (C) 2010 RedHat Inc
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
This program is free software; you can redistribute it and/or modify
|
|
Packit Service |
779887 |
it under the terms of the GNU General Public License as published by
|
|
Packit Service |
779887 |
the Free Software Foundation; either version 2 of the License, or
|
|
Packit Service |
779887 |
(at your option) any later version.
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
This program is distributed in the hope that it will be useful,
|
|
Packit Service |
779887 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
779887 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
779887 |
GNU General Public License for more details.
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
You should have received a copy of the GNU General Public License along
|
|
Packit Service |
779887 |
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
Packit Service |
779887 |
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
Packit Service |
779887 |
*/
|
|
Packit Service |
779887 |
#include <libxml/encoding.h>
|
|
Packit Service |
779887 |
#include <libxml/xmlwriter.h>
|
|
Packit Service |
779887 |
#include <curl/curl.h>
|
|
Packit Service |
779887 |
#include "internal_libreport.h"
|
|
Packit Service |
779887 |
#include "libreport_curl.h"
|
|
Packit Service |
779887 |
#include "abrt_rh_support.h"
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
struct reportfile {
|
|
Packit Service |
779887 |
xmlTextWriterPtr writer;
|
|
Packit Service |
779887 |
xmlBufferPtr buf;
|
|
Packit Service |
779887 |
};
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
static void __attribute__((__noreturn__))
|
|
Packit Service |
779887 |
die_xml_oom(void)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
error_msg_and_die("Can't create XML attribute (out of memory?)");
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
static xmlBufferPtr
|
|
Packit Service |
779887 |
xxmlBufferCreate(void)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
xmlBufferPtr r = xmlBufferCreate();
|
|
Packit Service |
779887 |
if (!r)
|
|
Packit Service |
779887 |
die_xml_oom();
|
|
Packit Service |
779887 |
return r;
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
static xmlTextWriterPtr
|
|
Packit Service |
779887 |
xxmlNewTextWriterMemory(xmlBufferPtr buf /*, int compression*/)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
xmlTextWriterPtr r = xmlNewTextWriterMemory(buf, /*compression:*/ 0);
|
|
Packit Service |
779887 |
if (!r)
|
|
Packit Service |
779887 |
die_xml_oom();
|
|
Packit Service |
779887 |
return r;
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
static void
|
|
Packit Service |
779887 |
xxmlTextWriterStartDocument(xmlTextWriterPtr writer,
|
|
Packit Service |
779887 |
const char * version,
|
|
Packit Service |
779887 |
const char * encoding,
|
|
Packit Service |
779887 |
const char * standalone)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
if (xmlTextWriterStartDocument(writer, version, encoding, standalone) < 0)
|
|
Packit Service |
779887 |
die_xml_oom();
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
static void
|
|
Packit Service |
779887 |
xxmlTextWriterEndDocument(xmlTextWriterPtr writer)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
if (xmlTextWriterEndDocument(writer) < 0)
|
|
Packit Service |
779887 |
die_xml_oom();
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
static void
|
|
Packit Service |
779887 |
xxmlTextWriterStartElement(xmlTextWriterPtr writer, const char *name)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
// these bright guys REDEFINED CHAR (!) to unsigned char...
|
|
Packit Service |
779887 |
if (xmlTextWriterStartElement(writer, (unsigned char*)name) < 0)
|
|
Packit Service |
779887 |
die_xml_oom();
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
static void
|
|
Packit Service |
779887 |
xxmlTextWriterEndElement(xmlTextWriterPtr writer)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
if (xmlTextWriterEndElement(writer) < 0)
|
|
Packit Service |
779887 |
die_xml_oom();
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
static void
|
|
Packit Service |
779887 |
xxmlTextWriterWriteElement(xmlTextWriterPtr writer, const char *name, const char *content)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
if (xmlTextWriterWriteElement(writer, (unsigned char*)name, (unsigned char*)content) < 0)
|
|
Packit Service |
779887 |
die_xml_oom();
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
static void
|
|
Packit Service |
779887 |
xxmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const char *name, const char *content)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
if (xmlTextWriterWriteAttribute(writer, (unsigned char*)name, (unsigned char*)content) < 0)
|
|
Packit Service |
779887 |
die_xml_oom();
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
#if 0 //unused
|
|
Packit Service |
779887 |
static void
|
|
Packit Service |
779887 |
xxmlTextWriterWriteString(xmlTextWriterPtr writer, const char *content)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
if (xmlTextWriterWriteString(writer, (unsigned char*)content) < 0)
|
|
Packit Service |
779887 |
die_xml_oom();
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
#endif
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
//
|
|
Packit Service |
779887 |
// Reportfile helpers
|
|
Packit Service |
779887 |
//
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
// End the reportfile, and prepare it for delivery.
|
|
Packit Service |
779887 |
// No more bindings can be added after this.
|
|
Packit Service |
779887 |
static void
|
|
Packit Service |
779887 |
close_writer(reportfile_t* file)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
if (!file->writer)
|
|
Packit Service |
779887 |
return;
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
// close off the end of the xml file
|
|
Packit Service |
779887 |
xxmlTextWriterEndDocument(file->writer);
|
|
Packit Service |
779887 |
xmlFreeTextWriter(file->writer);
|
|
Packit Service |
779887 |
file->writer = NULL;
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
// This allocates a reportfile_t structure and initializes it.
|
|
Packit Service |
779887 |
reportfile_t*
|
|
Packit Service |
779887 |
new_reportfile(void)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
// create a new reportfile_t
|
|
Packit Service |
779887 |
reportfile_t* file = (reportfile_t*)xmalloc(sizeof(*file));
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
// set up a libxml 'buffer' and 'writer' to that buffer
|
|
Packit Service |
779887 |
file->buf = xxmlBufferCreate();
|
|
Packit Service |
779887 |
file->writer = xxmlNewTextWriterMemory(file->buf);
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
// start a new xml document:
|
|
Packit Service |
779887 |
// <report xmlns="http://www.redhat.com/gss/strata">...
|
|
Packit Service |
779887 |
xxmlTextWriterStartDocument(file->writer, /*version:*/ NULL, /*encoding:*/ NULL, /*standalone:*/ NULL);
|
|
Packit Service |
779887 |
xxmlTextWriterStartElement(file->writer, "report");
|
|
Packit Service |
779887 |
xxmlTextWriterWriteAttribute(file->writer, "xmlns", "http://www.redhat.com/gss/strata");
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
return file;
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
static void
|
|
Packit Service |
779887 |
internal_reportfile_start_binding(reportfile_t* file, const char* name, int isbinary, const char* filename)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
//
|
|
Packit Service |
779887 |
xxmlTextWriterStartElement(file->writer, "binding");
|
|
Packit Service |
779887 |
xxmlTextWriterWriteAttribute(file->writer, "name", name);
|
|
Packit Service |
779887 |
if (filename)
|
|
Packit Service |
779887 |
xxmlTextWriterWriteAttribute(file->writer, "fileName", filename);
|
|
Packit Service |
779887 |
if (isbinary)
|
|
Packit Service |
779887 |
xxmlTextWriterWriteAttribute(file->writer, "type", "binary");
|
|
Packit Service |
779887 |
else
|
|
Packit Service |
779887 |
xxmlTextWriterWriteAttribute(file->writer, "type", "text");
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
// Add a new text binding
|
|
Packit Service |
779887 |
void
|
|
Packit Service |
779887 |
reportfile_add_binding_from_string(reportfile_t* file, const char* name, const char* value)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
// <binding name=NAME type=text value=VALUE>
|
|
Packit Service |
779887 |
internal_reportfile_start_binding(file, name, /*isbinary:*/ 0, /*filename:*/ NULL);
|
|
Packit Service |
779887 |
xxmlTextWriterWriteAttribute(file->writer, "value", value);
|
|
Packit Service |
779887 |
xxmlTextWriterEndElement(file->writer);
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
// Add a new binding to a report whose value is represented as a file.
|
|
Packit Service |
779887 |
void
|
|
Packit Service |
779887 |
reportfile_add_binding_from_namedfile(reportfile_t* file,
|
|
Packit Service |
779887 |
const char* on_disk_filename, /* unused so far */
|
|
Packit Service |
779887 |
const char* binding_name,
|
|
Packit Service |
779887 |
const char* recorded_filename,
|
|
Packit Service |
779887 |
int isbinary)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
//
|
|
Packit Service |
779887 |
internal_reportfile_start_binding(file, binding_name, isbinary, recorded_filename);
|
|
Packit Service |
779887 |
// ... href=content/NAME>
|
|
Packit Service |
779887 |
char *href_name = concat_path_file("content", binding_name);
|
|
Packit Service |
779887 |
xxmlTextWriterWriteAttribute(file->writer, "href", href_name);
|
|
Packit Service |
779887 |
free(href_name);
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
// Return the contents of the reportfile as a string.
|
|
Packit Service |
779887 |
const char*
|
|
Packit Service |
779887 |
reportfile_as_string(reportfile_t* file)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
close_writer(file);
|
|
Packit Service |
779887 |
// unsigned char -> char
|
|
Packit Service |
779887 |
return (char*)file->buf->content;
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
void
|
|
Packit Service |
779887 |
free_reportfile(reportfile_t* file)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
if (!file)
|
|
Packit Service |
779887 |
return;
|
|
Packit Service |
779887 |
close_writer(file);
|
|
Packit Service |
779887 |
xmlBufferFree(file->buf);
|
|
Packit Service |
779887 |
free(file);
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
void free_rhts_result(rhts_result_t *p)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
if (!p)
|
|
Packit Service |
779887 |
return;
|
|
Packit Service |
779887 |
free(p->url);
|
|
Packit Service |
779887 |
free(p->msg);
|
|
Packit Service |
779887 |
free(p->body);
|
|
Packit Service |
779887 |
free(p);
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
//
|
|
Packit Service |
779887 |
// Common
|
|
Packit Service |
779887 |
//
|
|
Packit Service |
779887 |
static const char *const text_plain_header[] = {
|
|
Packit Service |
779887 |
"Accept: text/plain",
|
|
Packit Service |
779887 |
NULL
|
|
Packit Service |
779887 |
};
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
//
|
|
Packit Service |
779887 |
// Creating new case
|
|
Packit Service |
779887 |
// See
|
|
Packit Service |
779887 |
// https://access.redhat.com/knowledge/docs/Red_Hat_Customer_Portal/integration_guide.html
|
|
Packit Service |
779887 |
//
|
|
Packit Service |
779887 |
// $ curl -X POST -H 'Content-Type: application/xml' --data
|
|
Packit Service |
779887 |
// '
|
|
Packit Service |
779887 |
// <case xmlns="http://www.redhat.com/gss/strata">
|
|
Packit Service |
779887 |
// <summary>Example Case</summary>
|
|
Packit Service |
779887 |
// <description>Example created with cURL</description>
|
|
Packit Service |
779887 |
// <product>Red Hat Enterprise Linux</product><version>6.0</version>
|
|
Packit Service |
779887 |
// </case>'
|
|
Packit Service |
779887 |
// https://api.access.redhat.com/rs/cases
|
|
Packit Service |
779887 |
//
|
|
Packit Service |
779887 |
static char*
|
|
Packit Service |
779887 |
make_case_data(const char* summary, const char* description,
|
|
Packit Service |
779887 |
const char* product, const char* version,
|
|
Packit Service |
779887 |
const char* component)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
char* retval;
|
|
Packit Service |
779887 |
xmlTextWriterPtr writer;
|
|
Packit Service |
779887 |
xmlBufferPtr buf;
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
buf = xxmlBufferCreate();
|
|
Packit Service |
779887 |
writer = xxmlNewTextWriterMemory(buf);
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
xxmlTextWriterStartDocument(writer, NULL, "UTF-8", "yes");
|
|
Packit Service |
779887 |
xxmlTextWriterStartElement(writer, "case");
|
|
Packit Service |
779887 |
xxmlTextWriterWriteAttribute(writer, "xmlns",
|
|
Packit Service |
779887 |
"http://www.redhat.com/gss/strata");
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
xxmlTextWriterWriteElement(writer, "summary", summary);
|
|
Packit Service |
779887 |
xxmlTextWriterWriteElement(writer, "description", description);
|
|
Packit Service |
779887 |
if (product) {
|
|
Packit Service |
779887 |
xxmlTextWriterWriteElement(writer, "product", product);
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
if (version) {
|
|
Packit Service |
779887 |
xxmlTextWriterWriteElement(writer, "version", version);
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
if (component) {
|
|
Packit Service |
779887 |
xxmlTextWriterWriteElement(writer, "component", component);
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
xxmlTextWriterEndDocument(writer);
|
|
Packit Service |
779887 |
retval = xstrdup((const char*)buf->content);
|
|
Packit Service |
779887 |
xmlFreeTextWriter(writer);
|
|
Packit Service |
779887 |
xmlBufferFree(buf);
|
|
Packit Service |
779887 |
return retval;
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
static rhts_result_t*
|
|
Packit Service |
779887 |
post_case_to_url(const char* url,
|
|
Packit Service |
779887 |
const char* username,
|
|
Packit Service |
779887 |
const char* password,
|
|
Packit Service |
779887 |
bool ssl_verify,
|
|
Packit Service |
779887 |
const char **additional_headers,
|
|
Packit Service |
779887 |
const char* product,
|
|
Packit Service |
779887 |
const char* version,
|
|
Packit Service |
779887 |
const char* summary,
|
|
Packit Service |
779887 |
const char* description,
|
|
Packit Service |
779887 |
const char* component)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
rhts_result_t *result = xzalloc(sizeof(*result));
|
|
Packit Service |
779887 |
char *url_copy = NULL;
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
char *case_data = make_case_data(summary, description,
|
|
Packit Service |
779887 |
product, version,
|
|
Packit Service |
779887 |
component);
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
int redirect_count = 0;
|
|
Packit Service |
779887 |
char *errmsg;
|
|
Packit Service |
779887 |
post_state_t *post_state;
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
redirect:
|
|
Packit Service |
779887 |
post_state = new_post_state(0
|
|
Packit Service |
779887 |
+ POST_WANT_HEADERS
|
|
Packit Service |
779887 |
+ POST_WANT_BODY
|
|
Packit Service |
779887 |
+ POST_WANT_ERROR_MSG
|
|
Packit Service |
779887 |
+ (ssl_verify ? POST_WANT_SSL_VERIFY : 0)
|
|
Packit Service |
779887 |
);
|
|
Packit Service |
779887 |
post_state->username = username;
|
|
Packit Service |
779887 |
post_state->password = password;
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
post_string(post_state, url, "application/xml", additional_headers, case_data);
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
char *location = find_header_in_post_state(post_state, "Location:");
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
switch (post_state->http_resp_code)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
case 404:
|
|
Packit Service |
779887 |
/* Not strictly necessary (default branch would deal with it too),
|
|
Packit Service |
779887 |
* but makes this typical error less cryptic:
|
|
Packit Service |
779887 |
* instead of returning html-encoded body, we show short concise message,
|
|
Packit Service |
779887 |
* and show offending URL (typos in which is a typical cause) */
|
|
Packit Service |
779887 |
result->error = -1;
|
|
Packit Service |
779887 |
result->msg = xasprintf("Error in HTTP POST, "
|
|
Packit Service |
779887 |
"HTTP code: 404 (Not found), URL:'%s'", url);
|
|
Packit Service |
779887 |
break;
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
case 301: /* "301 Moved Permanently" (for example, used to move http:// to https://) */
|
|
Packit Service |
779887 |
case 302: /* "302 Found" (just in case) */
|
|
Packit Service |
779887 |
case 305: /* "305 Use Proxy" */
|
|
Packit Service |
779887 |
if (++redirect_count < 10 && location)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
free(url_copy);
|
|
Packit Service |
779887 |
url = url_copy = xstrdup(location);
|
|
Packit Service |
779887 |
free_post_state(post_state);
|
|
Packit Service |
779887 |
goto redirect;
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
/* fall through */
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
default:
|
|
Packit Service |
779887 |
// TODO: error messages in headers
|
|
Packit Service |
779887 |
// are observed to be more informative than the body:
|
|
Packit Service |
779887 |
//
|
|
Packit Service |
779887 |
// 'HTTP/1.1 400 Bad Request'
|
|
Packit Service |
779887 |
// 'Date: Mon, 10 Oct 2011 13:31:56 GMT^M'
|
|
Packit Service |
779887 |
// 'Server: Apache^M'
|
|
Packit Service |
779887 |
// 'Strata-Message: The supplied parameter Fedora value can not be processed^M'
|
|
Packit Service |
779887 |
// ^^^^^^^^^^^^^^^^^^^^^^^^^ useful message
|
|
Packit Service |
779887 |
// 'Strata-Code: BAD_PARAMETER^M'
|
|
Packit Service |
779887 |
// 'Content-Length: 1^M'
|
|
Packit Service |
779887 |
// 'Content-Type: text/plain; charset=UTF-8^M'
|
|
Packit Service |
779887 |
// 'Connection: close^M'
|
|
Packit Service |
779887 |
// '^M'
|
|
Packit Service |
779887 |
// ' ' <------ body is useless
|
|
Packit Service |
779887 |
result->error = -1;
|
|
Packit Service |
779887 |
errmsg = post_state->curl_error_msg;
|
|
Packit Service |
779887 |
if (errmsg && errmsg[0])
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
result->msg = xasprintf(_("Error in case creation at '%s': %s"),
|
|
Packit Service |
779887 |
url, errmsg);
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
else
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
errmsg = find_header_in_post_state(post_state, "Strata-Message:");
|
|
Packit Service |
779887 |
if (!errmsg)
|
|
Packit Service |
779887 |
errmsg = post_state->body;
|
|
Packit Service |
779887 |
if (errmsg && errmsg[0])
|
|
Packit Service |
779887 |
result->msg = xasprintf(_("Error in case creation at '%s',"
|
|
Packit Service |
779887 |
" HTTP code: %d, server says: '%s'"),
|
|
Packit Service |
779887 |
url, post_state->http_resp_code, errmsg);
|
|
Packit Service |
779887 |
else
|
|
Packit Service |
779887 |
result->msg = xasprintf(_("Error in case creation at '%s',"
|
|
Packit Service |
779887 |
" HTTP code: %d"),
|
|
Packit Service |
779887 |
url, post_state->http_resp_code);
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
break;
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
case 200:
|
|
Packit Service |
779887 |
case 201:
|
|
Packit Service |
779887 |
/* Created successfully */
|
|
Packit Service |
779887 |
result->url = xstrdup(location); /* note: xstrdup(NULL) returns NULL */
|
|
Packit Service |
779887 |
} /* switch (HTTP code) */
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
result->http_resp_code = post_state->http_resp_code;
|
|
Packit Service |
779887 |
result->body = post_state->body;
|
|
Packit Service |
779887 |
post_state->body = NULL;
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
free_post_state(post_state);
|
|
Packit Service |
779887 |
free(case_data);
|
|
Packit Service |
779887 |
free(url_copy);
|
|
Packit Service |
779887 |
return result;
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
rhts_result_t*
|
|
Packit Service |
779887 |
create_new_case(const char* base_url,
|
|
Packit Service |
779887 |
const char* username,
|
|
Packit Service |
779887 |
const char* password,
|
|
Packit Service |
779887 |
bool ssl_verify,
|
|
Packit Service |
779887 |
const char* product,
|
|
Packit Service |
779887 |
const char* version,
|
|
Packit Service |
779887 |
const char* summary,
|
|
Packit Service |
779887 |
const char* description,
|
|
Packit Service |
779887 |
const char* component)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
char *url = concat_path_file(base_url, "cases");
|
|
Packit Service |
779887 |
rhts_result_t *result = post_case_to_url(url,
|
|
Packit Service |
779887 |
username,
|
|
Packit Service |
779887 |
password,
|
|
Packit Service |
779887 |
ssl_verify,
|
|
Packit Service |
779887 |
(const char **)text_plain_header,
|
|
Packit Service |
779887 |
product,
|
|
Packit Service |
779887 |
version,
|
|
Packit Service |
779887 |
summary,
|
|
Packit Service |
779887 |
description,
|
|
Packit Service |
779887 |
component
|
|
Packit Service |
779887 |
);
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
if (!result->error && !result->url)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
/* Case Creation returned valid code, but no location */
|
|
Packit Service |
779887 |
result->error = -1;
|
|
Packit Service |
779887 |
free(result->msg);
|
|
Packit Service |
779887 |
result->msg = xasprintf(_("Error in case creation at '%s':"
|
|
Packit Service |
779887 |
" no Location URL, HTTP code: %d"),
|
|
Packit Service |
779887 |
url, result->http_resp_code
|
|
Packit Service |
779887 |
);
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
free(url);
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
return result;
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
//
|
|
Packit Service |
779887 |
// Add case comment
|
|
Packit Service |
779887 |
//
|
|
Packit Service |
779887 |
// $ curl -X POST -H 'Content-Type: application/xml' --data
|
|
Packit Service |
779887 |
// '
|
|
Packit Service |
779887 |
// <comment xmlns="http://www.redhat.com/gss/strata">
|
|
Packit Service |
779887 |
// <text>Test comment! This can contain lots of information, etc.</text>
|
|
Packit Service |
779887 |
// </comment>'
|
|
Packit Service |
779887 |
// https://api.access.redhat.com/rs/cases/NNNNNNN/comments
|
|
Packit Service |
779887 |
//
|
|
Packit Service |
779887 |
static char*
|
|
Packit Service |
779887 |
make_comment_data(const char *comment_text)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
char *retval;
|
|
Packit Service |
779887 |
xmlTextWriterPtr writer;
|
|
Packit Service |
779887 |
xmlBufferPtr buf;
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
buf = xxmlBufferCreate();
|
|
Packit Service |
779887 |
writer = xxmlNewTextWriterMemory(buf);
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
xxmlTextWriterStartDocument(writer, NULL, "UTF-8", "yes");
|
|
Packit Service |
779887 |
xxmlTextWriterStartElement(writer, "comment");
|
|
Packit Service |
779887 |
xxmlTextWriterWriteAttribute(writer, "xmlns",
|
|
Packit Service |
779887 |
"http://www.redhat.com/gss/strata");
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
xxmlTextWriterWriteElement(writer, "text", comment_text);
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
xxmlTextWriterEndDocument(writer);
|
|
Packit Service |
779887 |
retval = xstrdup((const char*)buf->content);
|
|
Packit Service |
779887 |
xmlFreeTextWriter(writer);
|
|
Packit Service |
779887 |
xmlBufferFree(buf);
|
|
Packit Service |
779887 |
return retval;
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
static rhts_result_t*
|
|
Packit Service |
779887 |
post_comment_to_url(const char *url,
|
|
Packit Service |
779887 |
const char *username,
|
|
Packit Service |
779887 |
const char *password,
|
|
Packit Service |
779887 |
bool ssl_verify,
|
|
Packit Service |
779887 |
const char **additional_headers,
|
|
Packit Service |
779887 |
const char *comment_text)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
rhts_result_t *result = xzalloc(sizeof(*result));
|
|
Packit Service |
779887 |
char *url_copy = NULL;
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
char *xml = make_comment_data(comment_text);
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
int redirect_count = 0;
|
|
Packit Service |
779887 |
char *errmsg;
|
|
Packit Service |
779887 |
post_state_t *post_state;
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
redirect:
|
|
Packit Service |
779887 |
post_state = new_post_state(0
|
|
Packit Service |
779887 |
+ POST_WANT_HEADERS
|
|
Packit Service |
779887 |
+ POST_WANT_BODY
|
|
Packit Service |
779887 |
+ POST_WANT_ERROR_MSG
|
|
Packit Service |
779887 |
+ (ssl_verify ? POST_WANT_SSL_VERIFY : 0)
|
|
Packit Service |
779887 |
);
|
|
Packit Service |
779887 |
post_state->username = username;
|
|
Packit Service |
779887 |
post_state->password = password;
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
post_string(post_state, url, "application/xml", additional_headers, xml);
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
char *location = find_header_in_post_state(post_state, "Location:");
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
switch (post_state->http_resp_code)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
case 404:
|
|
Packit Service |
779887 |
/* Not strictly necessary (default branch would deal with it too),
|
|
Packit Service |
779887 |
* but makes this typical error less cryptic:
|
|
Packit Service |
779887 |
* instead of returning html-encoded body, we show short concise message,
|
|
Packit Service |
779887 |
* and show offending URL (typos in which is a typical cause) */
|
|
Packit Service |
779887 |
result->error = -1;
|
|
Packit Service |
779887 |
result->msg = xasprintf("Error in HTTP POST, "
|
|
Packit Service |
779887 |
"HTTP code: 404 (Not found), URL:'%s'", url);
|
|
Packit Service |
779887 |
break;
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
case 301: /* "301 Moved Permanently" (for example, used to move http:// to https://) */
|
|
Packit Service |
779887 |
case 302: /* "302 Found" (just in case) */
|
|
Packit Service |
779887 |
case 305: /* "305 Use Proxy" */
|
|
Packit Service |
779887 |
if (++redirect_count < 10 && location)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
free(url_copy);
|
|
Packit Service |
779887 |
url = url_copy = xstrdup(location);
|
|
Packit Service |
779887 |
free_post_state(post_state);
|
|
Packit Service |
779887 |
goto redirect;
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
/* fall through */
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
default:
|
|
Packit Service |
779887 |
result->error = -1;
|
|
Packit Service |
779887 |
errmsg = post_state->curl_error_msg;
|
|
Packit Service |
779887 |
if (errmsg && errmsg[0])
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
result->msg = xasprintf(_("Error in comment creation at '%s': %s"),
|
|
Packit Service |
779887 |
url, errmsg);
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
else
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
errmsg = find_header_in_post_state(post_state, "Strata-Message:");
|
|
Packit Service |
779887 |
if (!errmsg)
|
|
Packit Service |
779887 |
errmsg = post_state->body;
|
|
Packit Service |
779887 |
if (errmsg && errmsg[0])
|
|
Packit Service |
779887 |
result->msg = xasprintf(_("Error in comment creation at '%s',"
|
|
Packit Service |
779887 |
" HTTP code: %d, server says: '%s'"),
|
|
Packit Service |
779887 |
url, post_state->http_resp_code, errmsg);
|
|
Packit Service |
779887 |
else
|
|
Packit Service |
779887 |
result->msg = xasprintf(_("Error in comment creation at '%s',"
|
|
Packit Service |
779887 |
" HTTP code: %d"),
|
|
Packit Service |
779887 |
url, post_state->http_resp_code);
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
break;
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
case 200:
|
|
Packit Service |
779887 |
case 201:
|
|
Packit Service |
779887 |
/* Created successfully */
|
|
Packit Service |
779887 |
result->url = xstrdup(location); /* note: xstrdup(NULL) returns NULL */
|
|
Packit Service |
779887 |
} /* switch (HTTP code) */
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
result->http_resp_code = post_state->http_resp_code;
|
|
Packit Service |
779887 |
result->body = post_state->body;
|
|
Packit Service |
779887 |
post_state->body = NULL;
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
free_post_state(post_state);
|
|
Packit Service |
779887 |
free(xml);
|
|
Packit Service |
779887 |
free(url_copy);
|
|
Packit Service |
779887 |
return result;
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
rhts_result_t*
|
|
Packit Service |
779887 |
add_comment_to_case(const char* base_url,
|
|
Packit Service |
779887 |
const char* username,
|
|
Packit Service |
779887 |
const char* password,
|
|
Packit Service |
779887 |
bool ssl_verify,
|
|
Packit Service |
779887 |
const char* comment_text)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
char *url = concat_path_file(base_url, "comments");
|
|
Packit Service |
779887 |
rhts_result_t *result = post_comment_to_url(url,
|
|
Packit Service |
779887 |
username,
|
|
Packit Service |
779887 |
password,
|
|
Packit Service |
779887 |
ssl_verify,
|
|
Packit Service |
779887 |
// NB! text_plain_header here was causing error 404 instead of 201 (Created)!
|
|
Packit Service |
779887 |
// NULL makes curl use "Accept: */*" instead and creation works.
|
|
Packit Service |
779887 |
// Likely a bug on the server!
|
|
Packit Service |
779887 |
(const char **) NULL, //text_plain_header,
|
|
Packit Service |
779887 |
comment_text
|
|
Packit Service |
779887 |
);
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
if (!result->error && !result->url)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
/* Creation returned valid code, but no location */
|
|
Packit Service |
779887 |
result->error = -1;
|
|
Packit Service |
779887 |
free(result->msg);
|
|
Packit Service |
779887 |
result->msg = xasprintf(_("Error in comment creation at '%s':"
|
|
Packit Service |
779887 |
" no Location URL, HTTP code: %d"),
|
|
Packit Service |
779887 |
url, result->http_resp_code
|
|
Packit Service |
779887 |
);
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
free(url);
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
return result;
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
//
|
|
Packit Service |
779887 |
// Attach file to case
|
|
Packit Service |
779887 |
//
|
|
Packit Service |
779887 |
static rhts_result_t*
|
|
Packit Service |
779887 |
post_file_to_url(const char* url,
|
|
Packit Service |
779887 |
const char* username,
|
|
Packit Service |
779887 |
const char* password,
|
|
Packit Service |
779887 |
bool ssl_verify,
|
|
Packit Service |
779887 |
bool post_as_form,
|
|
Packit Service |
779887 |
const char **additional_headers,
|
|
Packit Service |
779887 |
const char *file_name)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
rhts_result_t *result = xzalloc(sizeof(*result));
|
|
Packit Service |
779887 |
char *url_copy = NULL;
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
int redirect_count = 0;
|
|
Packit Service |
779887 |
char *errmsg;
|
|
Packit Service |
779887 |
post_state_t *atch_state;
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
redirect_attach:
|
|
Packit Service |
779887 |
atch_state = new_post_state(0
|
|
Packit Service |
779887 |
+ POST_WANT_HEADERS
|
|
Packit Service |
779887 |
+ POST_WANT_BODY
|
|
Packit Service |
779887 |
+ POST_WANT_ERROR_MSG
|
|
Packit Service |
779887 |
+ (ssl_verify ? POST_WANT_SSL_VERIFY : 0)
|
|
Packit Service |
779887 |
);
|
|
Packit Service |
779887 |
atch_state->username = username;
|
|
Packit Service |
779887 |
atch_state->password = password;
|
|
Packit Service |
779887 |
if (post_as_form)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
/* Sends data in multipart/mixed document. One detail is that
|
|
Packit Service |
779887 |
* file *name* is also sent to the server.
|
|
Packit Service |
779887 |
*/
|
|
Packit Service |
779887 |
post_file_as_form(atch_state,
|
|
Packit Service |
779887 |
url,
|
|
Packit Service |
779887 |
"application/octet-stream",
|
|
Packit Service |
779887 |
additional_headers,
|
|
Packit Service |
779887 |
file_name
|
|
Packit Service |
779887 |
);
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
else
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
/* Sends file's raw contents */
|
|
Packit Service |
779887 |
post_file(atch_state,
|
|
Packit Service |
779887 |
url,
|
|
Packit Service |
779887 |
"application/octet-stream",
|
|
Packit Service |
779887 |
additional_headers,
|
|
Packit Service |
779887 |
file_name
|
|
Packit Service |
779887 |
);
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
char *atch_location = find_header_in_post_state(atch_state, "Location:");
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
switch (atch_state->http_resp_code)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
case 305: /* "305 Use Proxy" */
|
|
Packit Service |
779887 |
if (++redirect_count < 10 && atch_location)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
free(url_copy);
|
|
Packit Service |
779887 |
url = url_copy = xstrdup(atch_location);
|
|
Packit Service |
779887 |
free_post_state(atch_state);
|
|
Packit Service |
779887 |
goto redirect_attach;
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
/* fall through */
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
default:
|
|
Packit Service |
779887 |
/* Error */
|
|
Packit Service |
779887 |
result->error = -1;
|
|
Packit Service |
779887 |
errmsg = atch_state->curl_error_msg;
|
|
Packit Service |
779887 |
if (errmsg && errmsg[0])
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
result->msg = xasprintf("Error in file upload at '%s': %s",
|
|
Packit Service |
779887 |
url, errmsg);
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
else
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
errmsg = atch_state->body;
|
|
Packit Service |
779887 |
if (errmsg && errmsg[0])
|
|
Packit Service |
779887 |
result->msg = xasprintf("Error in file upload at '%s',"
|
|
Packit Service |
779887 |
" HTTP code: %d, server says: '%s'",
|
|
Packit Service |
779887 |
url, atch_state->http_resp_code, errmsg);
|
|
Packit Service |
779887 |
else
|
|
Packit Service |
779887 |
result->msg = xasprintf("Error in file upload at '%s',"
|
|
Packit Service |
779887 |
" HTTP code: %d",
|
|
Packit Service |
779887 |
url, atch_state->http_resp_code);
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
break;
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
case 200:
|
|
Packit Service |
779887 |
case 201:
|
|
Packit Service |
779887 |
result->url = xstrdup(atch_location); /* note: xstrdup(NULL) returns NULL */
|
|
Packit Service |
779887 |
//result->msg = xstrdup("File uploaded successfully");
|
|
Packit Service |
779887 |
} /* switch (HTTP code) */
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
result->http_resp_code = atch_state->http_resp_code;
|
|
Packit Service |
779887 |
result->body = atch_state->body;
|
|
Packit Service |
779887 |
atch_state->body = NULL;
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
free_post_state(atch_state);
|
|
Packit Service |
779887 |
free(url_copy);
|
|
Packit Service |
779887 |
return result;
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
rhts_result_t*
|
|
Packit Service |
779887 |
attach_file_to_case(const char* base_url,
|
|
Packit Service |
779887 |
const char* username,
|
|
Packit Service |
779887 |
const char* password,
|
|
Packit Service |
779887 |
bool ssl_verify,
|
|
Packit Service |
779887 |
const char *file_name)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
char *url = concat_path_file(base_url, "attachments");
|
|
Packit Service |
779887 |
rhts_result_t *result = post_file_to_url(url,
|
|
Packit Service |
779887 |
username,
|
|
Packit Service |
779887 |
password,
|
|
Packit Service |
779887 |
ssl_verify,
|
|
Packit Service |
779887 |
/*post_as_form:*/ true,
|
|
Packit Service |
779887 |
(const char **) text_plain_header,
|
|
Packit Service |
779887 |
file_name
|
|
Packit Service |
779887 |
);
|
|
Packit Service |
779887 |
free(url);
|
|
Packit Service |
779887 |
return result;
|
|
Packit Service |
779887 |
}
|
|
Packit Service |
779887 |
|
|
Packit Service |
779887 |
//
|
|
Packit Service |
779887 |
// Get hint
|
|
Packit Service |
779887 |
//
|
|
Packit Service |
779887 |
rhts_result_t*
|
|
Packit Service |
779887 |
get_rhts_hints(const char* base_url,
|
|
Packit Service |
779887 |
const char* username,
|
|
Packit Service |
779887 |
const char* password,
|
|
Packit Service |
779887 |
bool ssl_verify,
|
|
Packit Service |
779887 |
const char* file_name)
|
|
Packit Service |
779887 |
{
|
|
Packit Service |
779887 |
char *url = concat_path_file(base_url, "problems");
|
|
Packit Service |
779887 |
// rhts_result_t *result = post_case_to_url(url,
|
|
Packit Service |
779887 |
// username,
|
|
Packit Service |
779887 |
// password,
|
|
Packit Service |
779887 |
// ssl_verify,
|
|
Packit Service |
779887 |
// NULL,
|
|
Packit Service |
779887 |
// release,
|
|
Packit Service |
779887 |
// summary,
|
|
Packit Service |
779887 |
// description,
|
|
Packit Service |
779887 |
// component
|
|
Packit Service |
779887 |
// );
|
|
Packit Service |
779887 |
rhts_result_t *result = post_file_to_url(url,
|
|
Packit Service |
779887 |
username,
|
|
Packit Service |
779887 |
password,
|
|
Packit Service |
779887 |
ssl_verify,
|
|
Packit Service |
779887 |
/*post_as_form:*/ false,
|
|
Packit Service |
779887 |
/*headers:*/ NULL,
|
|
Packit Service |
779887 |
file_name
|
|
Packit Service |
779887 |
);
|
|
Packit Service |
779887 |
free(url);
|
|
Packit Service |
779887 |
return result;
|
|
Packit Service |
779887 |
}
|