예제 #1
0
/**
 * soup_message_body_free:
 * @body: a #SoupMessageBody
 *
 * Frees @body. You will not normally need to use this, as
 * #SoupMessage frees its associated message bodies automatically.
 **/
void
soup_message_body_free (SoupMessageBody *body)
{
	SoupMessageBodyPrivate *priv = (SoupMessageBodyPrivate *)body;

	if (--priv->ref_count == 0) {
		soup_message_body_truncate (body);
		g_slice_free (SoupMessageBodyPrivate, priv);
	}
}
예제 #2
0
void
soup_soap_message_persist (SoupSoapMessage *msg)
{
	g_return_if_fail (SOUP_SOAP_IS_MESSAGE (msg));

	xmlChar *buffer;
	const gchar *contents;

	SoupSoapMessagePrivate *priv = msg->priv;

	xmlDocPtr doc = xmlNewDoc (BAD_CAST "1.0");


	xmlNodePtr envelope_node = xmlNewNode (NULL, BAD_CAST "Envelope");
	xmlSetNs (envelope_node,
	          xmlNewNs (envelope_node,
	                    BAD_CAST SOAP_ENV_NAMESPACE,
	                    BAD_CAST "SOAP-ENV"));
	xmlNewNs (envelope_node,
	          BAD_CAST XSD_NAMESPACE,
	          BAD_CAST "xsd");
	xmlNewNs (envelope_node,
	          BAD_CAST XSI_NAMESPACE,
	          BAD_CAST "xsi");
	xmlNewNs (envelope_node,
	          BAD_CAST SOAP_ENC_NAMESPACE,
	          BAD_CAST "SOAP-ENC");
	xmlSetProp (envelope_node,
	            BAD_CAST "SOAP-ENV:encodingStyle",
	            BAD_CAST SOAP_ENCODING_STYLE);
	xmlDocSetRootElement (doc, envelope_node);

	create_param_node (doc, SOUP_SOAP_PARAM (priv->header), envelope_node);

	xmlNodePtr body_node = xmlNewChild (envelope_node, NULL, BAD_CAST "Body", NULL);
	create_param_node (doc, SOUP_SOAP_PARAM (priv->body), body_node);


	xmlDocDumpFormatMemoryEnc (doc, &buffer, NULL, "UTF-8", 0);

	contents = (gchar *) buffer;
	soup_message_body_truncate (priv->message_body);
	soup_message_body_append (priv->message_body, SOUP_MEMORY_COPY,
	                          contents, strlen (contents));
	soup_message_body_complete (priv->message_body);

	xmlFree (buffer);


	xmlFreeDoc (doc);


	soup_message_headers_set_content_type (priv->message_headers,
	                                       "text/xml", NULL);
}
예제 #3
0
static void
restarted_streaming_hack (SoupMessage *msg, gpointer user_data)
{
	PutTestData *ptd = user_data;

	/* We're streaming, and we had to restart. So the data need
	   to be regenerated. That's the *point* of this test; we don't
	   *want* it to accumulate in the request body */
	make_put_chunk (&ptd->chunks[0], "one\r\n");
	make_put_chunk (&ptd->chunks[1], "two\r\n");
	make_put_chunk (&ptd->chunks[2], "three\r\n");
	ptd->next = ptd->nwrote = ptd->nfreed = 0;

	debug_printf (2, "  truncating request body on restart\n");
	soup_message_body_truncate (msg->request_body);

	/* The redirect will turn it into a GET request. Fix that... */
	soup_message_headers_set_encoding (msg->request_headers, SOUP_ENCODING_CHUNKED);
	msg->method = SOUP_METHOD_PUT;
}
static void
restarted_streaming_hack (SoupMessage *msg, gpointer user_data)
{
	restarted_streaming (msg, user_data);
	soup_message_body_truncate (msg->request_body);
}
static void
handle_partial_get (SoupMessage *msg)
{
	SoupRange *ranges;
	int nranges;
	SoupBuffer *full_response;

	/* Make sure the message is set up right for us to return a
	 * partial response; it has to be a GET, the status must be
	 * 200 OK (and in particular, NOT already 206 Partial
	 * Content), and the SoupServer must have already filled in
	 * the response body
	 */
	if (msg->method != SOUP_METHOD_GET ||
	    msg->status_code != SOUP_STATUS_OK ||
	    soup_message_headers_get_encoding (msg->response_headers) !=
	    SOUP_ENCODING_CONTENT_LENGTH ||
	    msg->response_body->length == 0 ||
	    !soup_message_body_get_accumulate (msg->response_body))
		return;

	/* Oh, and there has to have been a valid Range header on the
	 * request, of course.
	 */
	if (!soup_message_headers_get_ranges (msg->request_headers,
					      msg->response_body->length,
					      &ranges, &nranges))
		return;

	full_response = soup_message_body_flatten (msg->response_body);
	if (!full_response) {
		soup_message_headers_free_ranges (msg->request_headers, ranges);
		return;
	}

	soup_message_set_status (msg, SOUP_STATUS_PARTIAL_CONTENT);
	soup_message_body_truncate (msg->response_body);

	if (nranges == 1) {
		SoupBuffer *range_buf;

		/* Single range, so just set Content-Range and fix the body. */

		soup_message_headers_set_content_range (msg->response_headers,
							ranges[0].start,
							ranges[0].end,
							full_response->length);
		range_buf = soup_buffer_new_subbuffer (full_response,
						       ranges[0].start,
						       ranges[0].end - ranges[0].start + 1);
		soup_message_body_append_buffer (msg->response_body, range_buf);
		soup_buffer_free (range_buf);
	} else {
		SoupMultipart *multipart;
		SoupMessageHeaders *part_headers;
		SoupBuffer *part_body;
		const char *content_type;
		int i;

		/* Multiple ranges, so build a multipart/byteranges response
		 * to replace msg->response_body with.
		 */

		multipart = soup_multipart_new ("multipart/byteranges");
		content_type = soup_message_headers_get_one (msg->response_headers,
							     "Content-Type");
		for (i = 0; i < nranges; i++) {
			part_headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_MULTIPART);
			if (content_type) {
				soup_message_headers_append (part_headers,
							     "Content-Type",
							     content_type);
			}
			soup_message_headers_set_content_range (part_headers,
								ranges[i].start,
								ranges[i].end,
								full_response->length);
			part_body = soup_buffer_new_subbuffer (full_response,
							       ranges[i].start,
							       ranges[i].end - ranges[i].start + 1);
			soup_multipart_append_part (multipart, part_headers,
						    part_body);
			soup_message_headers_free (part_headers);
			soup_buffer_free (part_body);
		}

		soup_multipart_to_message (multipart, msg->response_headers,
					   msg->response_body);
		soup_multipart_free (multipart);
	}

	soup_buffer_free (full_response);
	soup_message_headers_free_ranges (msg->request_headers, ranges);
}
예제 #6
0
static void
handle_received_chunk (SoupMessage * msg, SoupBuffer * chunk,
    SnraClient * client)
{
  const gchar *ptr;
  gsize length;
  SnraClientFlags flag = get_flag_from_msg (msg);

  if (client->was_connected & flag) {
    g_print ("Successfully connected %s to server %s:%d\n",
        flag == SNRA_CLIENT_PLAYER ? "player" : "controller",
        client->connected_server, client->connected_port);
    client->was_connected |= flag;
  }

  /* Successful server connection, stop avahi discovery */
  if (client->avahi_client) {
    avahi_client_free (client->avahi_client);
    client->avahi_sb = NULL;
    client->avahi_client = NULL;
  }

  if (client->json == NULL)
    client->json = json_parser_new ();
#if 0
  {
    gchar *tmp = g_strndup (chunk->data, chunk->length);
    g_print ("%s\n", tmp);
    g_free (tmp);
  }
#endif

  ptr = memchr (chunk->data, '\0', chunk->length);
  if (!ptr)
    return;

  /* Save remaining portion */
  ptr += 1;
  length =(chunk->length - (ptr - chunk->data));

  chunk = soup_message_body_flatten (msg->response_body);
  if (json_parser_load_from_data (client->json, chunk->data, chunk->length,
          NULL)) {
    JsonNode *root = json_parser_get_root (client->json);
    GstStructure *s = snra_json_to_gst_structure (root);

    if (s == NULL)
      goto end;                   /* Invalid chunk */

    if (flag == SNRA_CLIENT_PLAYER)
      handle_player_message (client, s);
    else
      handle_controller_message (client, s);

    gst_structure_free (s);
  }

end:
  soup_message_body_truncate (msg->response_body);
  /* Put back remaining part */
  if (length)
    soup_message_body_append (msg->response_body, SOUP_MEMORY_COPY, ptr, length);
}
예제 #7
0
static void
handle_received_chunk (SoupMessage * msg, SoupBuffer * chunk,
    AurClient * client)
{
  const gchar *ptr;
  gsize length;
  AurClientFlags flag = get_flag_from_msg (msg);
  JsonNode *root;
  GstStructure *s;
  GError *err = NULL;
  gchar *json_str = NULL;

  if (client->was_connected & flag) {
    g_print ("Successfully connected %s to server %s:%d\n",
        flag == AUR_CLIENT_PLAYER ? "player" : "controller",
        client->connected_server, client->connected_port);
    client->was_connected |= flag;
  }

  /* Set up or re-trigger 20 second idle timeout for ping messages */
  if (client->idle_timeout)
    g_source_remove (client->idle_timeout);
  client->idle_timeout = g_timeout_add_seconds (20,
      (GSourceFunc) conn_idle_timeout, client);

#if HAVE_AVAHI
  /* Successful server connection, stop avahi discovery */
  if (client->avahi_client) {
    avahi_client_free (client->avahi_client);
    client->avahi_sb = NULL;
    client->avahi_client = NULL;
  }
#endif

  if (client->json == NULL)
    client->json = json_parser_new ();

  ptr = memchr (chunk->data, '\0', chunk->length);
  if (!ptr)
    return;

  /* Save remaining portion */
  ptr += 1;
  length = (chunk->length - (ptr - chunk->data));

  chunk = soup_message_body_flatten (msg->response_body);

  // Ignore null string chunks
  if (chunk->length < 2)
    goto end;

  /* Workaround: Copy to a string to avoid stupid
   * UTF-8 validation bug in json-glib 1.0.2 */
  json_str = g_strndup (chunk->data, chunk->length);

#if 0
  g_print ("%s\n", json_str);
#endif

  if (!json_parser_load_from_data (client->json, json_str, -1,
          &err) || err != NULL)
    goto fail;

  root = json_parser_get_root (client->json);
  s = aur_json_to_gst_structure (root);

  if (s == NULL)
    goto fail;                  /* Invalid chunk */

  if (flag == AUR_CLIENT_PLAYER)
    handle_player_message (client, s);
  else
    handle_controller_message (client, s);

  gst_structure_free (s);

end:
  g_free (json_str);

  soup_message_body_truncate (msg->response_body);
  /* Put back remaining part */
  if (length)
    soup_message_body_append (msg->response_body, SOUP_MEMORY_COPY, ptr,
        length);
  return;

fail:{
    g_print ("Failed to parse message '%s'\n", json_str);
    if (err) {
      g_print ("Error: %s\n", err->message);
      g_error_free (err);
    }
    goto end;
  }
}