|
Packit Service |
ca3877 |
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
|
Packit Service |
ca3877 |
/*
|
|
Packit Service |
ca3877 |
* Copyright 2013 Red Hat, Inc.
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
#include "test-utils.h"
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static void
|
|
Packit Service |
ca3877 |
force_io_streams_init (void)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
SoupServer *server;
|
|
Packit Service |
ca3877 |
SoupSession *session;
|
|
Packit Service |
ca3877 |
SoupURI *base_uri;
|
|
Packit Service |
ca3877 |
SoupMessage *msg;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
/* Poke libsoup enough to cause SoupBodyInputStream and
|
|
Packit Service |
ca3877 |
* SoupBodyOutputStream to get defined, so we can find them
|
|
Packit Service |
ca3877 |
* via g_type_from_name() later.
|
|
Packit Service |
ca3877 |
*/
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
server = soup_test_server_new (TRUE);
|
|
Packit Service |
ca3877 |
base_uri = soup_test_server_get_uri (server, "http", NULL);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
session = soup_test_session_new (SOUP_TYPE_SESSION, NULL);
|
|
Packit Service |
ca3877 |
msg = soup_message_new_from_uri ("POST", base_uri);
|
|
Packit Service |
ca3877 |
soup_session_send_message (session, msg);
|
|
Packit Service |
ca3877 |
g_object_unref (msg);
|
|
Packit Service |
ca3877 |
soup_test_session_abort_unref (session);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
soup_uri_free (base_uri);
|
|
Packit Service |
ca3877 |
soup_test_server_quit_unref (server);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
typedef struct {
|
|
Packit Service |
ca3877 |
GFilterInputStream grandparent;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
gpointer *soup_filter_input_stream_private;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
gboolean is_readable;
|
|
Packit Service |
ca3877 |
} SlowInputStream;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
typedef struct {
|
|
Packit Service |
ca3877 |
GFilterInputStreamClass grandparent;
|
|
Packit Service |
ca3877 |
} SlowInputStreamClass;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
GType slow_input_stream_get_type (void);
|
|
Packit Service |
ca3877 |
static void slow_pollable_input_stream_init (GPollableInputStreamInterface *pollable_interface,
|
|
Packit Service |
ca3877 |
gpointer interface_data);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
G_DEFINE_TYPE_WITH_CODE (SlowInputStream, slow_input_stream,
|
|
Packit Service |
ca3877 |
g_type_from_name ("SoupFilterInputStream"),
|
|
Packit Service |
ca3877 |
G_IMPLEMENT_INTERFACE (G_TYPE_POLLABLE_INPUT_STREAM, slow_pollable_input_stream_init);
|
|
Packit Service |
ca3877 |
)
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static void
|
|
Packit Service |
ca3877 |
slow_input_stream_init (SlowInputStream *sis)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static gssize
|
|
Packit Service |
ca3877 |
slow_input_stream_read (GInputStream *stream,
|
|
Packit Service |
ca3877 |
void *buffer,
|
|
Packit Service |
ca3877 |
gsize count,
|
|
Packit Service |
ca3877 |
GCancellable *cancellable,
|
|
Packit Service |
ca3877 |
GError **error)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
return g_input_stream_read (G_FILTER_INPUT_STREAM (stream)->base_stream,
|
|
Packit Service |
ca3877 |
buffer, 1, cancellable, error);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static void
|
|
Packit Service |
ca3877 |
slow_input_stream_class_init (SlowInputStreamClass *sisclass)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
GInputStreamClass *input_stream_class = G_INPUT_STREAM_CLASS (sisclass);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
input_stream_class->read_fn = slow_input_stream_read;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static gboolean
|
|
Packit Service |
ca3877 |
slow_input_stream_is_readable (GPollableInputStream *stream)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
return ((SlowInputStream *)stream)->is_readable;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static gssize
|
|
Packit Service |
ca3877 |
slow_input_stream_read_nonblocking (GPollableInputStream *stream,
|
|
Packit Service |
ca3877 |
void *buffer,
|
|
Packit Service |
ca3877 |
gsize count,
|
|
Packit Service |
ca3877 |
GError **error)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
if (((SlowInputStream *)stream)->is_readable) {
|
|
Packit Service |
ca3877 |
((SlowInputStream *)stream)->is_readable = FALSE;
|
|
Packit Service |
ca3877 |
return slow_input_stream_read (G_INPUT_STREAM (stream), buffer, count,
|
|
Packit Service |
ca3877 |
NULL, error);
|
|
Packit Service |
ca3877 |
} else {
|
|
Packit Service |
ca3877 |
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK,
|
|
Packit Service |
ca3877 |
"would block");
|
|
Packit Service |
ca3877 |
return -1;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static GSource *
|
|
Packit Service |
ca3877 |
slow_input_stream_create_source (GPollableInputStream *stream,
|
|
Packit Service |
ca3877 |
GCancellable *cancellable)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
GSource *base_source, *pollable_source;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
((SlowInputStream *)stream)->is_readable = TRUE;
|
|
Packit Service |
ca3877 |
base_source = g_timeout_source_new (0);
|
|
Packit Service |
ca3877 |
g_source_set_dummy_callback (base_source);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
pollable_source = g_pollable_source_new (G_OBJECT (stream));
|
|
Packit Service |
ca3877 |
g_source_add_child_source (pollable_source, base_source);
|
|
Packit Service |
ca3877 |
g_source_unref (base_source);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
return pollable_source;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static void
|
|
Packit Service |
ca3877 |
slow_pollable_input_stream_init (GPollableInputStreamInterface *pollable_interface,
|
|
Packit Service |
ca3877 |
gpointer interface_data)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
pollable_interface->is_readable = slow_input_stream_is_readable;
|
|
Packit Service |
ca3877 |
pollable_interface->read_nonblocking = slow_input_stream_read_nonblocking;
|
|
Packit Service |
ca3877 |
pollable_interface->create_source = slow_input_stream_create_source;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
typedef struct {
|
|
Packit Service |
ca3877 |
GFilterOutputStream parent;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
gboolean is_writable;
|
|
Packit Service |
ca3877 |
} SlowOutputStream;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
typedef struct {
|
|
Packit Service |
ca3877 |
GFilterOutputStreamClass parent;
|
|
Packit Service |
ca3877 |
} SlowOutputStreamClass;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
GType slow_output_stream_get_type (void);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static void slow_pollable_output_stream_init (GPollableOutputStreamInterface *pollable_interface,
|
|
Packit Service |
ca3877 |
gpointer interface_data);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
G_DEFINE_TYPE_WITH_CODE (SlowOutputStream, slow_output_stream,
|
|
Packit Service |
ca3877 |
g_type_from_name ("GFilterOutputStream"),
|
|
Packit Service |
ca3877 |
G_IMPLEMENT_INTERFACE (G_TYPE_POLLABLE_OUTPUT_STREAM, slow_pollable_output_stream_init);
|
|
Packit Service |
ca3877 |
)
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static void
|
|
Packit Service |
ca3877 |
slow_output_stream_init (SlowOutputStream *sis)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static gssize
|
|
Packit Service |
ca3877 |
slow_output_stream_write (GOutputStream *stream,
|
|
Packit Service |
ca3877 |
const void *buffer,
|
|
Packit Service |
ca3877 |
gsize count,
|
|
Packit Service |
ca3877 |
GCancellable *cancellable,
|
|
Packit Service |
ca3877 |
GError **error)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
return g_output_stream_write (G_FILTER_OUTPUT_STREAM (stream)->base_stream,
|
|
Packit Service |
ca3877 |
buffer, 1, cancellable, error);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static void
|
|
Packit Service |
ca3877 |
slow_output_stream_class_init (SlowOutputStreamClass *sisclass)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
GOutputStreamClass *output_stream_class = G_OUTPUT_STREAM_CLASS (sisclass);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
output_stream_class->write_fn = slow_output_stream_write;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static gboolean
|
|
Packit Service |
ca3877 |
slow_output_stream_is_writable (GPollableOutputStream *stream)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
return ((SlowOutputStream *)stream)->is_writable;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static gssize
|
|
Packit Service |
ca3877 |
slow_output_stream_write_nonblocking (GPollableOutputStream *stream,
|
|
Packit Service |
ca3877 |
const void *buffer,
|
|
Packit Service |
ca3877 |
gsize count,
|
|
Packit Service |
ca3877 |
GError **error)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
if (((SlowOutputStream *)stream)->is_writable) {
|
|
Packit Service |
ca3877 |
((SlowOutputStream *)stream)->is_writable = FALSE;
|
|
Packit Service |
ca3877 |
return slow_output_stream_write (G_OUTPUT_STREAM (stream), buffer, count,
|
|
Packit Service |
ca3877 |
NULL, error);
|
|
Packit Service |
ca3877 |
} else {
|
|
Packit Service |
ca3877 |
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK,
|
|
Packit Service |
ca3877 |
"would block");
|
|
Packit Service |
ca3877 |
return -1;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static GSource *
|
|
Packit Service |
ca3877 |
slow_output_stream_create_source (GPollableOutputStream *stream,
|
|
Packit Service |
ca3877 |
GCancellable *cancellable)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
GSource *base_source, *pollable_source;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
((SlowOutputStream *)stream)->is_writable = TRUE;
|
|
Packit Service |
ca3877 |
base_source = g_timeout_source_new (0);
|
|
Packit Service |
ca3877 |
g_source_set_dummy_callback (base_source);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
pollable_source = g_pollable_source_new (G_OBJECT (stream));
|
|
Packit Service |
ca3877 |
g_source_add_child_source (pollable_source, base_source);
|
|
Packit Service |
ca3877 |
g_source_unref (base_source);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
return pollable_source;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static void
|
|
Packit Service |
ca3877 |
slow_pollable_output_stream_init (GPollableOutputStreamInterface *pollable_interface,
|
|
Packit Service |
ca3877 |
gpointer interface_data)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
pollable_interface->is_writable = slow_output_stream_is_writable;
|
|
Packit Service |
ca3877 |
pollable_interface->write_nonblocking = slow_output_stream_write_nonblocking;
|
|
Packit Service |
ca3877 |
pollable_interface->create_source = slow_output_stream_create_source;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
typedef struct {
|
|
Packit Service |
ca3877 |
GFilterOutputStream parent;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
gboolean is_broken;
|
|
Packit Service |
ca3877 |
} BreakingOutputStream;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
typedef struct {
|
|
Packit Service |
ca3877 |
GFilterOutputStreamClass parent;
|
|
Packit Service |
ca3877 |
} BreakingOutputStreamClass;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
GType breaking_output_stream_get_type (void);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static void breaking_pollable_output_stream_init (GPollableOutputStreamInterface *pollable_interface,
|
|
Packit Service |
ca3877 |
gpointer interface_data);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
G_DEFINE_TYPE_WITH_CODE (BreakingOutputStream, breaking_output_stream,
|
|
Packit Service |
ca3877 |
g_type_from_name ("GFilterOutputStream"),
|
|
Packit Service |
ca3877 |
G_IMPLEMENT_INTERFACE (G_TYPE_POLLABLE_OUTPUT_STREAM, breaking_pollable_output_stream_init);
|
|
Packit Service |
ca3877 |
)
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static void
|
|
Packit Service |
ca3877 |
breaking_output_stream_init (BreakingOutputStream *sis)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static gssize
|
|
Packit Service |
ca3877 |
breaking_output_stream_write (GOutputStream *stream,
|
|
Packit Service |
ca3877 |
const void *buffer,
|
|
Packit Service |
ca3877 |
gsize count,
|
|
Packit Service |
ca3877 |
GCancellable *cancellable,
|
|
Packit Service |
ca3877 |
GError **error)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
if (((BreakingOutputStream *)stream)->is_broken) {
|
|
Packit Service |
ca3877 |
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "failed");
|
|
Packit Service |
ca3877 |
return -1;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (count > 128) {
|
|
Packit Service |
ca3877 |
((BreakingOutputStream *)stream)->is_broken = TRUE;
|
|
Packit Service |
ca3877 |
count /= 2;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
return g_output_stream_write (G_FILTER_OUTPUT_STREAM (stream)->base_stream,
|
|
Packit Service |
ca3877 |
buffer, count, cancellable, error);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static void
|
|
Packit Service |
ca3877 |
breaking_output_stream_class_init (BreakingOutputStreamClass *sisclass)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
GOutputStreamClass *output_stream_class = G_OUTPUT_STREAM_CLASS (sisclass);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
output_stream_class->write_fn = breaking_output_stream_write;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static gboolean
|
|
Packit Service |
ca3877 |
breaking_output_stream_is_writable (GPollableOutputStream *stream)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
return TRUE;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static gssize
|
|
Packit Service |
ca3877 |
breaking_output_stream_write_nonblocking (GPollableOutputStream *stream,
|
|
Packit Service |
ca3877 |
const void *buffer,
|
|
Packit Service |
ca3877 |
gsize count,
|
|
Packit Service |
ca3877 |
GError **error)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
if (((BreakingOutputStream *)stream)->is_broken) {
|
|
Packit Service |
ca3877 |
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "failed");
|
|
Packit Service |
ca3877 |
return -1;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
if (count > 128) {
|
|
Packit Service |
ca3877 |
((BreakingOutputStream *)stream)->is_broken = TRUE;
|
|
Packit Service |
ca3877 |
count /= 2;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
return g_pollable_output_stream_write_nonblocking (G_POLLABLE_OUTPUT_STREAM (G_FILTER_OUTPUT_STREAM (stream)->base_stream),
|
|
Packit Service |
ca3877 |
buffer, count, NULL, error);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static GSource *
|
|
Packit Service |
ca3877 |
breaking_output_stream_create_source (GPollableOutputStream *stream,
|
|
Packit Service |
ca3877 |
GCancellable *cancellable)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
GSource *base_source, *pollable_source;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
base_source = g_timeout_source_new (0);
|
|
Packit Service |
ca3877 |
g_source_set_dummy_callback (base_source);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
pollable_source = g_pollable_source_new (G_OBJECT (stream));
|
|
Packit Service |
ca3877 |
g_source_add_child_source (pollable_source, base_source);
|
|
Packit Service |
ca3877 |
g_source_unref (base_source);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
return pollable_source;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static void
|
|
Packit Service |
ca3877 |
breaking_pollable_output_stream_init (GPollableOutputStreamInterface *pollable_interface,
|
|
Packit Service |
ca3877 |
gpointer interface_data)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
pollable_interface->is_writable = breaking_output_stream_is_writable;
|
|
Packit Service |
ca3877 |
pollable_interface->write_nonblocking = breaking_output_stream_write_nonblocking;
|
|
Packit Service |
ca3877 |
pollable_interface->create_source = breaking_output_stream_create_source;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
#define CHUNK_SIZE 1024
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static GString *
|
|
Packit Service |
ca3877 |
chunkify (const char *str, gsize length)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
GString *gstr;
|
|
Packit Service |
ca3877 |
int i, size;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
gstr = g_string_new (NULL);
|
|
Packit Service |
ca3877 |
for (i = 0; i < length; i += CHUNK_SIZE) {
|
|
Packit Service |
ca3877 |
size = MIN (CHUNK_SIZE, length - i);
|
|
Packit Service |
ca3877 |
g_string_append_printf (gstr, "%x\r\n", size);
|
|
Packit Service |
ca3877 |
g_string_append_len (gstr, str + i, size);
|
|
Packit Service |
ca3877 |
g_string_append (gstr, "\r\n");
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
g_string_append (gstr, "0\r\n\r\n");
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
return gstr;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
static void
|
|
Packit Service |
ca3877 |
do_io_tests (void)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
GInputStream *imem, *islow, *in;
|
|
Packit Service |
ca3877 |
GOutputStream *omem, *oslow, *out;
|
|
Packit Service |
ca3877 |
GMemoryOutputStream *mem;
|
|
Packit Service |
ca3877 |
SoupBuffer *raw_contents;
|
|
Packit Service |
ca3877 |
char *buf;
|
|
Packit Service |
ca3877 |
GString *chunkified;
|
|
Packit Service |
ca3877 |
GError *error = NULL;
|
|
Packit Service |
ca3877 |
gssize nread, nwrote, total;
|
|
Packit Service |
ca3877 |
gssize chunk_length, chunk_total;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
raw_contents = soup_test_get_index ();
|
|
Packit Service |
ca3877 |
chunkified = chunkify (raw_contents->data, raw_contents->length);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
debug_printf (1, " sync read\n");
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
imem = g_memory_input_stream_new_from_data (chunkified->str, chunkified->len, NULL);
|
|
Packit Service |
ca3877 |
islow = g_object_new (slow_input_stream_get_type (),
|
|
Packit Service |
ca3877 |
"base-stream", imem,
|
|
Packit Service |
ca3877 |
"close-base-stream", TRUE,
|
|
Packit Service |
ca3877 |
NULL);
|
|
Packit Service |
ca3877 |
in = g_object_new (g_type_from_name ("SoupBodyInputStream"),
|
|
Packit Service |
ca3877 |
"base-stream", islow,
|
|
Packit Service |
ca3877 |
"close-base-stream", TRUE,
|
|
Packit Service |
ca3877 |
"encoding", SOUP_ENCODING_CHUNKED,
|
|
Packit Service |
ca3877 |
NULL);
|
|
Packit Service |
ca3877 |
g_object_unref (imem);
|
|
Packit Service |
ca3877 |
g_object_unref (islow);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
buf = g_malloc (raw_contents->length);
|
|
Packit Service |
ca3877 |
total = 0;
|
|
Packit Service |
ca3877 |
while (TRUE) {
|
|
Packit Service |
ca3877 |
nread = g_input_stream_read (in, buf + total,
|
|
Packit Service |
ca3877 |
raw_contents->length - total,
|
|
Packit Service |
ca3877 |
NULL, &error);
|
|
Packit Service |
ca3877 |
g_assert_no_error (error);
|
|
Packit Service |
ca3877 |
g_clear_error (&error);
|
|
Packit Service |
ca3877 |
if (nread > 0)
|
|
Packit Service |
ca3877 |
total += nread;
|
|
Packit Service |
ca3877 |
else
|
|
Packit Service |
ca3877 |
break;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_input_stream_close (in, NULL, &error);
|
|
Packit Service |
ca3877 |
g_assert_no_error (error);
|
|
Packit Service |
ca3877 |
g_clear_error (&error);
|
|
Packit Service |
ca3877 |
g_object_unref (in);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
soup_assert_cmpmem (buf, total, raw_contents->data, raw_contents->length);
|
|
Packit Service |
ca3877 |
g_free (buf);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
debug_printf (1, " async read\n");
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
imem = g_memory_input_stream_new_from_data (chunkified->str, chunkified->len, NULL);
|
|
Packit Service |
ca3877 |
islow = g_object_new (slow_input_stream_get_type (),
|
|
Packit Service |
ca3877 |
"base-stream", imem,
|
|
Packit Service |
ca3877 |
"close-base-stream", TRUE,
|
|
Packit Service |
ca3877 |
NULL);
|
|
Packit Service |
ca3877 |
in = g_object_new (g_type_from_name ("SoupBodyInputStream"),
|
|
Packit Service |
ca3877 |
"base-stream", islow,
|
|
Packit Service |
ca3877 |
"close-base-stream", TRUE,
|
|
Packit Service |
ca3877 |
"encoding", SOUP_ENCODING_CHUNKED,
|
|
Packit Service |
ca3877 |
NULL);
|
|
Packit Service |
ca3877 |
g_object_unref (imem);
|
|
Packit Service |
ca3877 |
g_object_unref (islow);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
buf = g_malloc (raw_contents->length);
|
|
Packit Service |
ca3877 |
total = 0;
|
|
Packit Service |
ca3877 |
while (TRUE) {
|
|
Packit Service |
ca3877 |
nread = g_pollable_input_stream_read_nonblocking (G_POLLABLE_INPUT_STREAM (in),
|
|
Packit Service |
ca3877 |
buf + total,
|
|
Packit Service |
ca3877 |
raw_contents->length - total,
|
|
Packit Service |
ca3877 |
NULL, &error);
|
|
Packit Service |
ca3877 |
if (nread == -1 && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
|
|
Packit Service |
ca3877 |
GSource *source;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_clear_error (&error);
|
|
Packit Service |
ca3877 |
source = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM (in), NULL);
|
|
Packit Service |
ca3877 |
g_source_set_dummy_callback (source);
|
|
Packit Service |
ca3877 |
g_source_attach (source, NULL);
|
|
Packit Service |
ca3877 |
while (!g_pollable_input_stream_is_readable (G_POLLABLE_INPUT_STREAM (in)))
|
|
Packit Service |
ca3877 |
g_main_context_iteration (NULL, TRUE);
|
|
Packit Service |
ca3877 |
g_source_destroy (source);
|
|
Packit Service |
ca3877 |
g_source_unref (source);
|
|
Packit Service |
ca3877 |
continue;
|
|
Packit Service |
ca3877 |
} else if (nread == -1) {
|
|
Packit Service |
ca3877 |
g_assert_no_error (error);
|
|
Packit Service |
ca3877 |
g_clear_error (&error);
|
|
Packit Service |
ca3877 |
break;
|
|
Packit Service |
ca3877 |
} else if (nread == 0)
|
|
Packit Service |
ca3877 |
break;
|
|
Packit Service |
ca3877 |
else
|
|
Packit Service |
ca3877 |
total += nread;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_input_stream_close (in, NULL, &error);
|
|
Packit Service |
ca3877 |
g_assert_no_error (error);
|
|
Packit Service |
ca3877 |
g_clear_error (&error);
|
|
Packit Service |
ca3877 |
g_object_unref (in);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
soup_assert_cmpmem (buf, total, raw_contents->data, raw_contents->length);
|
|
Packit Service |
ca3877 |
g_free (buf);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
debug_printf (1, " sync write\n");
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
buf = g_malloc (chunkified->len);
|
|
Packit Service |
ca3877 |
omem = g_memory_output_stream_new (buf, chunkified->len, NULL, NULL);
|
|
Packit Service |
ca3877 |
oslow = g_object_new (slow_output_stream_get_type (),
|
|
Packit Service |
ca3877 |
"base-stream", omem,
|
|
Packit Service |
ca3877 |
"close-base-stream", TRUE,
|
|
Packit Service |
ca3877 |
NULL);
|
|
Packit Service |
ca3877 |
out = g_object_new (g_type_from_name ("SoupBodyOutputStream"),
|
|
Packit Service |
ca3877 |
"base-stream", oslow,
|
|
Packit Service |
ca3877 |
"close-base-stream", TRUE,
|
|
Packit Service |
ca3877 |
"encoding", SOUP_ENCODING_CHUNKED,
|
|
Packit Service |
ca3877 |
NULL);
|
|
Packit Service |
ca3877 |
g_object_unref (omem);
|
|
Packit Service |
ca3877 |
g_object_unref (oslow);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
total = chunk_length = chunk_total = 0;
|
|
Packit Service |
ca3877 |
while (total < raw_contents->length) {
|
|
Packit Service |
ca3877 |
if (chunk_total == chunk_length) {
|
|
Packit Service |
ca3877 |
chunk_length = MIN (CHUNK_SIZE, raw_contents->length - total);
|
|
Packit Service |
ca3877 |
chunk_total = 0;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
nwrote = g_output_stream_write (out, raw_contents->data + total,
|
|
Packit Service |
ca3877 |
chunk_length - chunk_total, NULL, &error);
|
|
Packit Service |
ca3877 |
g_assert_no_error (error);
|
|
Packit Service |
ca3877 |
g_clear_error (&error);
|
|
Packit Service |
ca3877 |
if (nwrote > 0) {
|
|
Packit Service |
ca3877 |
total += nwrote;
|
|
Packit Service |
ca3877 |
chunk_total += nwrote;
|
|
Packit Service |
ca3877 |
} else
|
|
Packit Service |
ca3877 |
break;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_output_stream_close (out, NULL, &error);
|
|
Packit Service |
ca3877 |
g_assert_no_error (error);
|
|
Packit Service |
ca3877 |
g_clear_error (&error);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
mem = G_MEMORY_OUTPUT_STREAM (omem);
|
|
Packit Service |
ca3877 |
soup_assert_cmpmem (g_memory_output_stream_get_data (mem),
|
|
Packit Service |
ca3877 |
g_memory_output_stream_get_data_size (mem),
|
|
Packit Service |
ca3877 |
chunkified->str, chunkified->len);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_object_unref (out);
|
|
Packit Service |
ca3877 |
g_free (buf);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
debug_printf (1, " async write\n");
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
buf = g_malloc (chunkified->len);
|
|
Packit Service |
ca3877 |
omem = g_memory_output_stream_new (buf, chunkified->len, NULL, NULL);
|
|
Packit Service |
ca3877 |
oslow = g_object_new (slow_output_stream_get_type (),
|
|
Packit Service |
ca3877 |
"base-stream", omem,
|
|
Packit Service |
ca3877 |
"close-base-stream", TRUE,
|
|
Packit Service |
ca3877 |
NULL);
|
|
Packit Service |
ca3877 |
out = g_object_new (g_type_from_name ("SoupBodyOutputStream"),
|
|
Packit Service |
ca3877 |
"base-stream", oslow,
|
|
Packit Service |
ca3877 |
"close-base-stream", TRUE,
|
|
Packit Service |
ca3877 |
"encoding", SOUP_ENCODING_CHUNKED,
|
|
Packit Service |
ca3877 |
NULL);
|
|
Packit Service |
ca3877 |
g_object_unref (omem);
|
|
Packit Service |
ca3877 |
g_object_unref (oslow);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
total = chunk_length = chunk_total = 0;
|
|
Packit Service |
ca3877 |
while (total < raw_contents->length) {
|
|
Packit Service |
ca3877 |
if (chunk_total == chunk_length) {
|
|
Packit Service |
ca3877 |
chunk_length = MIN (CHUNK_SIZE, raw_contents->length - total);
|
|
Packit Service |
ca3877 |
chunk_total = 0;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
nwrote = g_pollable_output_stream_write_nonblocking (G_POLLABLE_OUTPUT_STREAM (out),
|
|
Packit Service |
ca3877 |
raw_contents->data + total,
|
|
Packit Service |
ca3877 |
chunk_length - chunk_total,
|
|
Packit Service |
ca3877 |
NULL, &error);
|
|
Packit Service |
ca3877 |
if (nwrote == -1 && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
|
|
Packit Service |
ca3877 |
GSource *source;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_clear_error (&error);
|
|
Packit Service |
ca3877 |
source = g_pollable_output_stream_create_source (G_POLLABLE_OUTPUT_STREAM (out), NULL);
|
|
Packit Service |
ca3877 |
g_source_set_dummy_callback (source);
|
|
Packit Service |
ca3877 |
g_source_attach (source, NULL);
|
|
Packit Service |
ca3877 |
while (!g_pollable_output_stream_is_writable (G_POLLABLE_OUTPUT_STREAM (out)))
|
|
Packit Service |
ca3877 |
g_main_context_iteration (NULL, TRUE);
|
|
Packit Service |
ca3877 |
g_source_destroy (source);
|
|
Packit Service |
ca3877 |
g_source_unref (source);
|
|
Packit Service |
ca3877 |
continue;
|
|
Packit Service |
ca3877 |
} else if (nwrote == -1) {
|
|
Packit Service |
ca3877 |
g_assert_no_error (error);
|
|
Packit Service |
ca3877 |
g_clear_error (&error);
|
|
Packit Service |
ca3877 |
break;
|
|
Packit Service |
ca3877 |
} else {
|
|
Packit Service |
ca3877 |
total += nwrote;
|
|
Packit Service |
ca3877 |
chunk_total += nwrote;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_output_stream_close (out, NULL, &error);
|
|
Packit Service |
ca3877 |
g_assert_no_error (error);
|
|
Packit Service |
ca3877 |
g_clear_error (&error);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
mem = G_MEMORY_OUTPUT_STREAM (omem);
|
|
Packit Service |
ca3877 |
soup_assert_cmpmem (g_memory_output_stream_get_data (mem),
|
|
Packit Service |
ca3877 |
g_memory_output_stream_get_data_size (mem),
|
|
Packit Service |
ca3877 |
chunkified->str, chunkified->len);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_object_unref (out);
|
|
Packit Service |
ca3877 |
g_free (buf);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
debug_printf (1, " failed write\n");
|
|
Packit Service |
ca3877 |
/* this succeeds if it doesn't critical */
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
buf = g_malloc (chunkified->len);
|
|
Packit Service |
ca3877 |
omem = g_memory_output_stream_new (buf, chunkified->len, NULL, NULL);
|
|
Packit Service |
ca3877 |
oslow = g_object_new (breaking_output_stream_get_type (),
|
|
Packit Service |
ca3877 |
"base-stream", omem,
|
|
Packit Service |
ca3877 |
"close-base-stream", TRUE,
|
|
Packit Service |
ca3877 |
NULL);
|
|
Packit Service |
ca3877 |
out = g_object_new (g_type_from_name ("SoupBodyOutputStream"),
|
|
Packit Service |
ca3877 |
"base-stream", oslow,
|
|
Packit Service |
ca3877 |
"close-base-stream", TRUE,
|
|
Packit Service |
ca3877 |
"encoding", SOUP_ENCODING_CHUNKED,
|
|
Packit Service |
ca3877 |
NULL);
|
|
Packit Service |
ca3877 |
g_object_unref (omem);
|
|
Packit Service |
ca3877 |
g_object_unref (oslow);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
total = 0;
|
|
Packit Service |
ca3877 |
while (total < raw_contents->length) {
|
|
Packit Service |
ca3877 |
nwrote = g_output_stream_write (out, raw_contents->data + total,
|
|
Packit Service |
ca3877 |
raw_contents->length - total, NULL, NULL);
|
|
Packit Service |
ca3877 |
if (nwrote == -1)
|
|
Packit Service |
ca3877 |
break;
|
|
Packit Service |
ca3877 |
else
|
|
Packit Service |
ca3877 |
total += nwrote;
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_assert_cmpint (total, !=, raw_contents->length);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_output_stream_close (out, NULL, NULL);
|
|
Packit Service |
ca3877 |
g_object_unref (out);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_free (buf);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_string_free (chunkified, TRUE);
|
|
Packit Service |
ca3877 |
}
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
int
|
|
Packit Service |
ca3877 |
main (int argc, char **argv)
|
|
Packit Service |
ca3877 |
{
|
|
Packit Service |
ca3877 |
int ret;
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
test_init (argc, argv, NULL);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
force_io_streams_init ();
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
g_test_add_func ("/chunk-io", do_io_tests);
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
ret = g_test_run ();
|
|
Packit Service |
ca3877 |
|
|
Packit Service |
ca3877 |
test_cleanup ();
|
|
Packit Service |
ca3877 |
return ret;
|
|
Packit Service |
ca3877 |
}
|