static SoupMessage * ews_create_msg_for_url (const gchar *url, xmlOutputBuffer *buf) { SoupMessage *msg; gconstpointer buf_content; gsize buf_size; msg = soup_message_new (buf != NULL ? "POST" : "GET", url); soup_message_headers_append ( msg->request_headers, "User-Agent", "libews/0.1"); if (buf != NULL) { buf_content = compat_libxml_output_buffer_get_content (buf, &buf_size); soup_message_set_request ( msg, "text/xml; charset=utf-8", SOUP_MEMORY_COPY, buf_content, buf_size); g_signal_connect ( msg, "restarted", G_CALLBACK (ews_post_restarted_cb), buf); } soup_buffer_free ( soup_message_body_flatten ( SOUP_MESSAGE (msg)->request_body)); g_debug ("The request headers"); g_debug ("==================="); g_debug ("%s", SOUP_MESSAGE (msg)->request_body->data); return msg; }
SoupSoapMessage * e_gw_message_new_with_header (const gchar *uri, const gchar *session_id, const gchar *method_name) { SoupSoapMessage *msg; msg = soup_soap_message_new (SOUP_METHOD_POST, uri, FALSE, NULL, NULL, NULL); if (!msg) { g_warning (G_STRLOC ": Could not build SOAP message"); return NULL; } soup_message_headers_append (SOUP_MESSAGE (msg)->request_headers, "Content-Type", "text/xml"); soup_message_headers_append (SOUP_MESSAGE (msg)->request_headers, "User-Agent", "Evolution/" VERSION); soup_message_headers_append (SOUP_MESSAGE (msg)->request_headers,"Connection", "Keep-Alive"); soup_message_headers_append (SOUP_MESSAGE (msg)->request_headers, "SOAPAction", method_name); soup_soap_message_start_envelope (msg); if (session_id && *session_id) { soup_soap_message_start_element (msg, "Header","SOAP-ENV", NULL); soup_soap_message_add_attribute (msg, "encodingStyle", "", "SOAP-ENV", NULL); /* FIXME: cannot use e_gw_message_write_string_parameter as it sets prefix -types*/ soup_soap_message_start_element (msg, "session", NULL, NULL); soup_soap_message_write_string (msg, session_id); soup_soap_message_end_element (msg); soup_soap_message_end_element (msg); } soup_soap_message_start_body (msg); soup_soap_message_add_attribute (msg, "encodingStyle", "", "SOAP-ENV", NULL); soup_soap_message_add_namespace (msg, "types", "http://schemas.novell.com/2003/10/NCSP/types.xsd"); soup_soap_message_start_element (msg, method_name, NULL, NULL); return msg; }
ESoapMessage * e_ews_message_new_with_header (const gchar *uri, const gchar *method_name, const gchar *attribute_name, const gchar *attribute_value, EwsServerVersion server_info) { ESoapMessage *msg; const gchar *server_ver; msg = e_soap_message_new (SOUP_METHOD_POST, uri, FALSE, NULL, NULL, NULL); if (!msg) { g_warning (G_STRLOC ": Could not build SOAP message"); return NULL; } soup_message_headers_append (SOUP_MESSAGE (msg)->request_headers, "Content-Type", "text/xml; charset=utf-8"); soup_message_headers_append (SOUP_MESSAGE (msg)->request_headers, "User-Agent", "Evolution/" VERSION); soup_message_headers_append (SOUP_MESSAGE (msg)->request_headers,"Connection", "Keep-Alive"); e_soap_message_start_envelope (msg); /* server info */ if (server_info == EWS_EXCHANGE_2007_SP1) server_ver = "Exchange2007_SP1"; else server_ver = "Exchange2007"; e_soap_message_start_header (msg); e_soap_message_start_element (msg, "RequestServerVersion", "types", "http://schemas.microsoft.com/exchange/services/2006/types"); e_soap_message_add_attribute (msg, "Version", server_ver, NULL, NULL); e_soap_message_end_element (msg); e_soap_message_end_header (msg); e_soap_message_start_body (msg); e_soap_message_add_namespace(msg, "messages", "http://schemas.microsoft.com/exchange/services/2006/messages"); e_soap_message_start_element(msg, method_name, "messages", NULL); e_soap_message_set_default_namespace (msg, "http://schemas.microsoft.com/exchange/services/2006/types"); if (attribute_name) e_soap_message_add_attribute (msg, attribute_name, attribute_value, NULL, NULL); return msg; }
/** * e_soap_message_new: * @method: the HTTP method for the created request. * @uri_string: the destination endpoint (as a string). * @standalone: ??? FIXME * @xml_encoding: ??? FIXME * @env_prefix: ??? FIXME * @env_uri: ??? FIXME * * Creates a new empty #ESoapMessage, which will connect to @uri_string. * * Returns: the new #ESoapMessage (or %NULL if @uri_string could not be * parsed). * * Since: 2.92 */ ESoapMessage * e_soap_message_new (const gchar *method, const gchar *uri_string, gboolean standalone, const gchar *xml_encoding, const gchar *env_prefix, const gchar *env_uri) { ESoapMessage *msg; SoupURI *uri; uri = soup_uri_new (uri_string); if (!uri) return NULL; msg = e_soap_message_new_from_uri (method, uri, standalone, xml_encoding, env_prefix, env_uri); soup_uri_free (uri); /* Don't accumulate body data into a huge buffer. * Instead, parse it as it arrives. */ soup_message_body_set_accumulate (SOUP_MESSAGE (msg)->response_body, FALSE); g_signal_connect (msg, "got-headers", G_CALLBACK (soap_got_headers), NULL); g_signal_connect (msg, "got-chunk", G_CALLBACK (soap_got_chunk), NULL); g_signal_connect (msg, "restarted", G_CALLBACK (soap_restarted), NULL); return msg; }
int main (int argc, char **argv) { SoupSession *session; SoupURI *proxy = NULL; SoupMessage *msg; const char *uri = "http://bugzilla.redhat.com/bugzilla/xmlrpc.cgi"; int opt, bug; g_thread_init (NULL); g_type_init (); while ((opt = getopt (argc, argv, "p:")) != -1) { switch (opt) { case 'p': proxy = soup_uri_new (optarg); if (!proxy) { fprintf (stderr, "Could not parse %s as URI\n", optarg); exit (1); } break; case '?': usage (); break; } } argc -= optind; argv += optind; if (argc > 1) { uri = argv[0]; argc--; argv++; } if (argc != 1 || (bug = atoi (argv[0])) == 0) usage (); session = soup_session_async_new_with_options ( SOUP_SESSION_PROXY_URI, proxy, NULL); msg = soup_xmlrpc_request_new (uri, "bugzilla.getBug", G_TYPE_INT, bug, G_TYPE_INVALID); if (!msg) { fprintf (stderr, "Could not create web service request to '%s'\n", uri); exit (1); } soup_session_queue_message (session, SOUP_MESSAGE (msg), got_response, NULL); loop = g_main_loop_new (NULL, TRUE); g_main_loop_run (loop); g_main_loop_unref (loop); return 0; }
void e_gw_message_write_footer (SoupSoapMessage *msg) { soup_soap_message_end_element (msg); soup_soap_message_end_body (msg); soup_soap_message_end_envelope (msg); soup_soap_message_persist (msg); if (g_getenv ("GROUPWISE_DEBUG") && (atoi (g_getenv ("GROUPWISE_DEBUG")) == 1)) { const gchar *header = soup_message_headers_get (SOUP_MESSAGE (msg)->request_headers, "SOAPAction"); soup_buffer_free (soup_message_body_flatten (SOUP_MESSAGE (msg)->request_body)); if (header && g_str_equal (header, "loginRequest")) { gchar *body; gchar *begin = NULL; gchar *end = NULL; body = g_strdup (SOUP_MESSAGE (msg)->request_body->data); begin = g_strrstr (body, "<types:password>"); if (begin) begin = begin + strlen ("<types:password>"); end = g_strrstr (body , "</types:password>"); if (begin && end) { gchar *tmp; for (tmp = begin; tmp < end; tmp++) *tmp='X'; } fputc ('\n', stdout); fputs (body, stdout); fputc ('\n', stdout); g_free (body); } else { /* print request's body */ fputc ('\n', stdout); fputs (SOUP_MESSAGE (msg)->request_body->data, stdout); fputc ('\n', stdout); } } }
static VALUE WebNetworkResponse_message(VALUE self) { VALUE __p_retval = Qnil; WebKitNetworkResponse *_self = ((WebKitNetworkResponse*)RVAL2GOBJ(self)); #line 217 "/home/geoff/Projects/gtk-webkit-ruby/ext/webkit/webkit.cr" do { __p_retval = GOBJ2RVAL(SOUP_MESSAGE(webkit_network_response_get_message(_self))); goto out; } while(0); out: return __p_retval; }
static void webkit_network_request_set_property(GObject* object, guint propertyID, const GValue* value, GParamSpec* pspec) { WebKitNetworkRequest* request = WEBKIT_NETWORK_REQUEST(object); WebKitNetworkRequestPrivate* priv = request->priv; switch(propertyID) { case PROP_URI: webkit_network_request_set_uri(request, g_value_get_string(value)); break; case PROP_MESSAGE: priv->message = SOUP_MESSAGE(g_value_dup_object(value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyID, pspec); } }
/** * e_soap_message_persist: * @msg: the #ESoapMessage. * * Writes the serialized XML tree to the #SoupMessage's buffer. * * Since: 2.92 */ void e_soap_message_persist (ESoapMessage *msg) { ESoapMessagePrivate *priv; xmlChar *body; gint len; g_return_if_fail (E_IS_SOAP_MESSAGE (msg)); priv = E_SOAP_MESSAGE_GET_PRIVATE (msg); xmlDocDumpMemory (priv->doc, &body, &len); /* serialize to SoupMessage class */ soup_message_set_request (SOUP_MESSAGE (msg), "text/xml; charset=utf-8", SOUP_MEMORY_TAKE, (gchar *) body, len); }
static gboolean _soup_xmlrpc_call(gchar * method, SyncNetAction * sna, SoupMessageCallbackFn callback) { SoupXmlrpcMessage *msg; sna->error = NULL; msg = soup_xmlrpc_message_new(XMLRPC_SERVER_URI); if (!msg) return FALSE; DEBUG("calling xmlrpc method %s", method); soup_xmlrpc_message_start_call(msg, method); soup_xmlrpc_message_end_call(msg); soup_xmlrpc_message_persist(msg); soup_session_queue_message(session, SOUP_MESSAGE(msg), callback, sna); g_main_run(loop); return TRUE; }
static gboolean send_chunks (gpointer user_data) { SoupMessage *msg = SOUP_MESSAGE (user_data); char *s; SoupBuffer *buf; s = g_strdup_printf ("%d %d %d %d\n", server_count, server_count, server_count, server_count); buf = soup_buffer_new (SOUP_MEMORY_TAKE, s, strlen (s)); soup_message_body_append_buffer (msg->response_body, buf); soup_server_unpause_message (server, msg); if (++server_count == NUM_CHUNKS) { soup_message_body_complete (msg->response_body); return FALSE; } else { return TRUE; } }
static gboolean _soup_xmlrpc_call_with_parameters(gchar * method, SyncNetAction * sna, SoupMessageCallbackFn callback, ...) { SoupXmlrpcMessage *msg; gchar *argument; va_list ap; sna->error = NULL; msg = soup_xmlrpc_message_new(XMLRPC_SERVER_URI); if (!msg) return FALSE; DEBUG("calling xmlrpc method %s", method); soup_xmlrpc_message_start_call(msg, method); va_start(ap, callback); while ((argument = va_arg(ap, gchar *))) { soup_xmlrpc_message_start_param(msg); soup_xmlrpc_message_write_string(msg, argument); soup_xmlrpc_message_end_param(msg); DEBUG("with parameter: %s", argument); } va_end(ap); soup_xmlrpc_message_end_call(msg); soup_xmlrpc_message_persist(msg); soup_session_queue_message(session, SOUP_MESSAGE(msg), callback, sna); g_main_run(loop); return TRUE; }
static void ews_autodiscover_response_cb (SoupSession *session, SoupMessage *msg, gpointer user_data) { GSimpleAsyncResult *simple; AutodiscoverData *data; gboolean success = FALSE; guint status; gint idx; gsize size; xmlDoc *doc; xmlNode *node; GError *error = NULL; simple = G_SIMPLE_ASYNC_RESULT (user_data); data = g_simple_async_result_get_op_res_gpointer (simple); status = msg->status_code; if (status == SOUP_STATUS_CANCELLED) return; size = sizeof (data->msgs) / sizeof (data->msgs[0]); for (idx = 0; idx < size; idx++) { if (data->msgs[idx] == msg) break; } if (idx == size) return; data->msgs[idx] = NULL; if (status != SOUP_STATUS_OK) { g_set_error ( &error, GOA_ERROR, GOA_ERROR_FAILED, /* TODO: more specific */ _("Code: %u — Unexpected response from server"), status); goto out; } soup_buffer_free ( soup_message_body_flatten ( SOUP_MESSAGE (msg)->response_body)); g_debug ("The response headers"); g_debug ("==================="); g_debug ("%s", SOUP_MESSAGE (msg)->response_body->data); doc = xmlReadMemory ( msg->response_body->data, msg->response_body->length, "autodiscover.xml", NULL, 0); if (doc == NULL) { g_set_error ( &error, GOA_ERROR, GOA_ERROR_FAILED, /* TODO: more specific */ _("Failed to parse autodiscover response XML")); goto out; } node = xmlDocGetRootElement (doc); if (g_strcmp0 ((gchar *) node->name, "Autodiscover") != 0) { g_set_error ( &error, GOA_ERROR, GOA_ERROR_FAILED, /* TODO: more specific */ _("Failed to find Autodiscover element")); goto out; } for (node = node->children; node; node = node->next) { if (ews_check_node (node, "Response")) break; } if (node == NULL) { g_set_error ( &error, GOA_ERROR, GOA_ERROR_FAILED, /* TODO: more specific */ _("Failed to find Response element")); goto out; } for (node = node->children; node; node = node->next) { if (ews_check_node (node, "Account")) break; } if (node == NULL) { g_set_error ( &error, GOA_ERROR, GOA_ERROR_FAILED, /* TODO: more specific */ _("Failed to find Account element")); goto out; } for (node = node->children; node; node = node->next) { if (ews_check_node (node, "Protocol")) { success = ews_autodiscover_parse_protocol (node, data); break; } } if (!success) { g_set_error ( &error, GOA_ERROR, GOA_ERROR_FAILED, /* TODO: more specific */ _("Failed to find ASUrl and OABUrl in autodiscover response")); goto out; } for (idx = 0; idx < size; idx++) { if (data->msgs[idx] != NULL) { /* Since we are cancelling from the same thread * that we queued the message, the callback (ie. * this function) will be invoked before * soup_session_cancel_message returns. */ soup_session_cancel_message ( data->session, data->msgs[idx], SOUP_STATUS_CANCELLED); data->msgs[idx] = NULL; } } out: if (error != NULL) { for (idx = 0; idx < size; idx++) { if (data->msgs[idx] != NULL) { /* There's another request outstanding. * Hope that it has better luck. */ g_clear_error (&error); return; } } g_simple_async_result_take_error (simple, error); } g_simple_async_result_complete_in_idle (simple); g_object_unref (simple); }
"text/xml; charset=utf-8", SOUP_MEMORY_COPY, #ifdef LIBXML2_NEW_BUFFER (gchar *) xmlOutputBufferGetContent(buf), xmlOutputBufferGetSize(buf)); #else (gchar *) buf->buffer->content, buf->buffer->use); #endif g_signal_connect (msg, "restarted", G_CALLBACK (ews_client_post_restarted_cb), buf); } soup_buffer_free (soup_message_body_flatten (SOUP_MESSAGE (msg)->request_body)); g_debug ("The request headers"); g_debug ("==================="); g_debug ("%s", SOUP_MESSAGE (msg)->request_body->data); return msg; } void goa_ews_client_autodiscover (GoaEwsClient *client, const gchar *email, const gchar *password, const gchar *username, const gchar *server, gboolean accept_ssl_errors, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) {
// fetch contents of inventory folder void fetch_system_folders(simgroup_ctx *sgrp, user_ctx *user, void *user_priv) { uuid_t u; char tmp[40]; char uri[256]; GRID_PRIV_DEF_SGRP(sgrp); USER_PRIV_DEF(user_priv); xmlTextWriterPtr writer; xmlBufferPtr buf; SoupMessage *msg; inv_items_req *req; assert(grid->inventory_server != NULL); buf = xmlBufferCreate(); if(buf == NULL) goto fail; writer = xmlNewTextWriterMemory(buf, 0); if(writer == NULL) goto free_fail_1; if(xmlTextWriterStartDocument(writer,NULL,"UTF-8",NULL) < 0) goto free_fail; if(xmlTextWriterStartElement(writer, BAD_CAST "RestSessionObjectOfGuid") < 0) goto free_fail; user_get_session_id(user, u); uuid_unparse(u, tmp); if(xmlTextWriterWriteFormatElement(writer,BAD_CAST "SessionID", "%s",tmp) < 0) goto free_fail; user_get_uuid(user, u); uuid_unparse(u, tmp); if(xmlTextWriterWriteFormatElement(writer,BAD_CAST "AvatarID", "%s",tmp) < 0) goto free_fail; if(xmlTextWriterWriteFormatElement(writer,BAD_CAST "Body", "%s",tmp) < 0) goto free_fail; if(xmlTextWriterEndElement(writer) < 0) goto free_fail; if(xmlTextWriterEndDocument(writer) < 0) { printf("DEBUG: couldn't end XML document\n"); goto fail; } // FIXME - don't use fixed-length buffer, and handle missing trailing / snprintf(uri, 256, "%sSystemFolders/", grid->inventory_server); printf("DEBUG: sending inventory request to %s\n", uri); msg = soup_message_new ("POST", uri); // FIXME - avoid unnecessary strlen soup_message_set_request (msg, "application/xml", SOUP_MEMORY_COPY, (char*)buf->content, strlen ((char*)buf->content)); req = new inv_items_req(); req->user_glue = user_glue; user_grid_glue_ref(user_glue); caj_queue_soup_message(sgrp, SOUP_MESSAGE(msg), got_system_folders_resp, req); xmlFreeTextWriter(writer); xmlBufferFree(buf); return; free_fail: xmlFreeTextWriter(writer); free_fail_1: xmlBufferFree(buf); fail: printf("DEBUG: ran into issues sending inventory request\n"); // FIXME - handle this }
void add_inventory_item(simgroup_ctx *sgrp, user_ctx *user, void *user_priv, inventory_item *inv, void(*cb)(void* priv, int success, uuid_t item_id), void *cb_priv) { uuid_t u, user_id; char tmp[40]; char uri[256]; GRID_PRIV_DEF_SGRP(sgrp); USER_PRIV_DEF(user_priv); xmlTextWriterPtr writer; xmlBufferPtr buf; SoupMessage *msg; add_inv_item_req *req; struct os_inv_item invitem; assert(grid->inventory_server != NULL); buf = xmlBufferCreate(); if(buf == NULL) goto fail; writer = xmlNewTextWriterMemory(buf, 0); if(writer == NULL) goto free_fail_1; if(xmlTextWriterStartDocument(writer,NULL,"UTF-8",NULL) < 0) goto free_fail; if(xmlTextWriterStartElement(writer, BAD_CAST "RestSessionObjectOfInventoryItemBase") < 0) goto free_fail; user_get_session_id(user, u); uuid_unparse(u, tmp); if(xmlTextWriterWriteFormatElement(writer,BAD_CAST "SessionID", "%s",tmp) < 0) goto free_fail; user_get_uuid(user, user_id); uuid_unparse(user_id, tmp); if(xmlTextWriterWriteFormatElement(writer,BAD_CAST "AvatarID", "%s",tmp) < 0) goto free_fail; if(xmlTextWriterStartElement(writer,BAD_CAST "Body") < 0) goto free_fail; inv_item_to_opensim(inv, invitem); osglue_serialise_xml(writer, deserialise_inv_item, &invitem); if(xmlTextWriterEndElement(writer) < 0) goto free_fail; if(xmlTextWriterEndElement(writer) < 0) goto free_fail; if(xmlTextWriterEndDocument(writer) < 0) { printf("DEBUG: couldn't end XML document\n"); goto fail; } // FIXME - don't use fixed-length buffer, and handle missing trailing / // (note: not AddNewItem, as that's not meant for sim use!) snprintf(uri, 256, "%sNewItem/", grid->inventory_server); printf("DEBUG: sending inventory add request to %s\n", uri); msg = soup_message_new ("POST", uri); // FIXME - avoid unnecessary strlen soup_message_set_request (msg, "text/xml", SOUP_MEMORY_COPY, (char*)buf->content, strlen ((char*)buf->content)); req = new add_inv_item_req(); req->user_glue = user_glue; req->cb = cb; req->cb_priv = cb_priv; uuid_copy(req->item_id, inv->item_id); user_grid_glue_ref(user_glue); caj_queue_soup_message(sgrp, SOUP_MESSAGE(msg), got_add_inv_item_resp, req); xmlFreeTextWriter(writer); xmlBufferFree(buf); return; free_fail: xmlFreeTextWriter(writer); free_fail_1: xmlBufferFree(buf); fail: printf("DEBUG: ran into issues sending inventory NewItem request\n"); uuid_clear(u); cb(cb_priv, FALSE, u); }
void fetch_inventory_item(simgroup_ctx *sgrp, user_ctx *user, void *user_priv, const uuid_t item_id, void(*cb)(struct inventory_item* item, void* priv), void *cb_priv) { uuid_t u, user_id; char tmp[40]; char uri[256]; GRID_PRIV_DEF_SGRP(sgrp); USER_PRIV_DEF(user_priv); xmlTextWriterPtr writer; xmlBufferPtr buf; SoupMessage *msg; inv_item_req *req; struct os_inv_item invitem; // don't ask. Please. assert(grid->inventory_server != NULL); buf = xmlBufferCreate(); if(buf == NULL) goto fail; writer = xmlNewTextWriterMemory(buf, 0); if(writer == NULL) goto free_fail_1; if(xmlTextWriterStartDocument(writer,NULL,"UTF-8",NULL) < 0) goto free_fail; if(xmlTextWriterStartElement(writer, BAD_CAST "RestSessionObjectOfInventoryItemBase") < 0) goto free_fail; user_get_session_id(user, u); uuid_unparse(u, tmp); if(xmlTextWriterWriteFormatElement(writer,BAD_CAST "SessionID", "%s",tmp) < 0) goto free_fail; user_get_uuid(user, user_id); uuid_unparse(user_id, tmp); if(xmlTextWriterWriteFormatElement(writer,BAD_CAST "AvatarID", "%s",tmp) < 0) goto free_fail; // okay, this is just painful... we have to serialise an entire complex // object in this cruddy .Net XML serialisation format... and the only bit // they actually use or need is a single UUID. Bletch *vomit*. if(xmlTextWriterStartElement(writer,BAD_CAST "Body") < 0) goto free_fail; memset(&invitem, 0, sizeof(invitem)); invitem.name = invitem.description = const_cast<char*>(""); invitem.creator_id = const_cast<char*>(""); uuid_copy(invitem.owner_id, user_id); uuid_copy(invitem.item_id, item_id); osglue_serialise_xml(writer, deserialise_inv_item, &invitem); if(xmlTextWriterEndElement(writer) < 0) goto free_fail; // now we should be done serialising the XML crud. if(xmlTextWriterEndElement(writer) < 0) goto free_fail; if(xmlTextWriterEndDocument(writer) < 0) { printf("DEBUG: couldn't end XML document\n"); goto fail; } // FIXME - don't use fixed-length buffer, and handle missing trailing / snprintf(uri, 256, "%sQueryItem/", grid->inventory_server); printf("DEBUG: sending inventory request to %s\n", uri); msg = soup_message_new ("POST", uri); // FIXME - avoid unnecessary strlen soup_message_set_request (msg, "text/xml", SOUP_MEMORY_COPY, (char*)buf->content, strlen ((char*)buf->content)); req = new inv_item_req(); req->user_glue = user_glue; req->cb = cb; req->cb_priv = cb_priv; uuid_copy(req->item_id, item_id); user_grid_glue_ref(user_glue); caj_queue_soup_message(sgrp, SOUP_MESSAGE(msg), got_inventory_item_resp, req); xmlFreeTextWriter(writer); xmlBufferFree(buf); return; free_fail: xmlFreeTextWriter(writer); free_fail_1: xmlBufferFree(buf); fail: printf("DEBUG: ran into issues sending inventory QueryItem request\n"); cb(NULL, cb_priv); // FIXME - handle this }
static void ews_client_autodiscover_response_cb (SoupSession *session, SoupMessage *msg, gpointer user_data) { GError *error; AutodiscoverData *data = user_data; gboolean op_res; guint status; gint idx; gsize size; xmlDoc *doc; xmlNode *node; error = NULL; op_res = FALSE; size = sizeof (data->msgs) / sizeof (data->msgs[0]); for (idx = 0; idx < size; idx++) { if (data->msgs[idx] == msg) break; } if (idx == size || data->pending == 0) return; data->msgs[idx] = NULL; status = msg->status_code; /* status == SOUP_STATUS_CANCELLED, if we are being aborted by the * GCancellable, an SSL error or another message that was * successful. */ if (status == SOUP_STATUS_CANCELLED) goto out; else if (status != SOUP_STATUS_OK) { g_set_error (&error, GOA_ERROR, GOA_ERROR_FAILED, /* TODO: more specific */ _("Code: %u — Unexpected response from server"), status); goto out; } soup_buffer_free (soup_message_body_flatten (SOUP_MESSAGE (msg)->response_body)); g_debug ("The response headers"); g_debug ("==================="); g_debug ("%s", SOUP_MESSAGE (msg)->response_body->data); doc = xmlReadMemory (msg->response_body->data, msg->response_body->length, "autodiscover.xml", NULL, 0); if (doc == NULL) { g_set_error (&error, GOA_ERROR, GOA_ERROR_FAILED, /* TODO: more specific */ _("Failed to parse autodiscover response XML")); goto out; } node = xmlDocGetRootElement (doc); if (g_strcmp0 ((gchar *) node->name, "Autodiscover")) { g_set_error (&error, GOA_ERROR, GOA_ERROR_FAILED, /* TODO: more specific */ /* Translators: the parameter is an XML element name. */ _("Failed to find ‘%s’ element"), "Autodiscover"); goto out; } for (node = node->children; node; node = node->next) { if (ews_client_check_node (node, "Response")) break; } if (node == NULL) { g_set_error (&error, GOA_ERROR, GOA_ERROR_FAILED, /* TODO: more specific */ /* Translators: the parameter is an XML element name. */ _("Failed to find ‘%s’ element"), "Response"); goto out; } for (node = node->children; node; node = node->next) { if (ews_client_check_node (node, "Account")) break; } if (node == NULL) { g_set_error (&error, GOA_ERROR, GOA_ERROR_FAILED, /* TODO: more specific */ /* Translators: the parameter is an XML element name. */ _("Failed to find ‘%s’ element"), "Account"); goto out; } for (node = node->children; node; node = node->next) { if (ews_client_check_node (node, "Protocol")) { op_res = ews_client_autodiscover_parse_protocol (node); /* Since the server may send back multiple <Protocol> nodes * don't break unless we found the one we want. */ if (op_res) break; } } if (!op_res) { g_set_error (&error, GOA_ERROR, GOA_ERROR_FAILED, /* TODO: more specific*/ _("Failed to find ASUrl and OABUrl in autodiscover response")); goto out; } for (idx = 0; idx < size; idx++) { if (data->msgs[idx] != NULL) { /* The callback (ie. this function) will be invoked after we * have returned to the main loop. */ soup_session_cancel_message (data->session, data->msgs[idx], SOUP_STATUS_CANCELLED); } } out: /* error == NULL, if we are being aborted by the GCancellable, an * SSL error or another message that was successful. */ if (!op_res) { /* There's another request outstanding. * Hope that it has better luck. */ if (data->pending > 1) g_clear_error (&error); if (error != NULL) g_simple_async_result_take_error (data->res, error); } data->pending--; if (data->pending == 0) { GMainContext *context; GSource *source; g_simple_async_result_set_op_res_gboolean (data->res, op_res); source = g_idle_source_new (); g_source_set_priority (source, G_PRIORITY_DEFAULT_IDLE); g_source_set_callback (source, ews_client_autodiscover_data_free, data, NULL); g_source_set_name (source, "[goa] ews_client_autodiscover_data_free"); context = g_main_context_get_thread_default (); g_source_attach (source, context); g_source_unref (source); } }