summaryrefslogtreecommitdiff
path: root/lib/c_glib
diff options
context:
space:
mode:
authorGonzalo Aguilar Delgado <gaguilar@level2crm.com>2017-09-15 12:26:02 +0200
committerJames E. King, III <jking@apache.org>2017-11-18 21:10:18 -0500
commit87ad2bcaaa5a9fe224ad7a9826b676ca9721ddd1 (patch)
treeb8aca3ee0e996f76f9881e1306d6e5bb8ed3b371 /lib/c_glib
parent95d5fb3a1e38125b9eabcbe9cda1a6c7bbe3e93d (diff)
downloadthrift-87ad2bcaaa5a9fe224ad7a9826b676ca9721ddd1.tar.gz
THRIFT-4329: multiplexed processor, client and server for c_glib
Client: c_glib This closes #1361
Diffstat (limited to 'lib/c_glib')
-rw-r--r--lib/c_glib/CMakeLists.txt3
-rwxr-xr-xlib/c_glib/Makefile.am9
-rw-r--r--lib/c_glib/src/thrift/c_glib/processor/thrift_multiplexed_processor.c346
-rw-r--r--lib/c_glib/src/thrift/c_glib/processor/thrift_multiplexed_processor.h114
-rw-r--r--lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c2
-rw-r--r--lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.c3
-rw-r--r--lib/c_glib/src/thrift/c_glib/protocol/thrift_stored_message_protocol.c192
-rw-r--r--lib/c_glib/src/thrift/c_glib/protocol/thrift_stored_message_protocol.h78
-rw-r--r--lib/c_glib/src/thrift/c_glib/transport/thrift_platform_socket.h12
-rw-r--r--lib/c_glib/src/thrift/c_glib/transport/thrift_socket.c41
-rw-r--r--lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.c234
-rw-r--r--lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.h16
-rw-r--r--lib/c_glib/test/CMakeLists.txt2
-rwxr-xr-xlib/c_glib/test/testbufferedtransport.c318
-rwxr-xr-xlib/c_glib/test/testframedtransport.c311
-rwxr-xr-xlib/c_glib/test/testtransportsocket.c312
-rw-r--r--lib/c_glib/test/testtransportsslsocket.c462
17 files changed, 1665 insertions, 790 deletions
diff --git a/lib/c_glib/CMakeLists.txt b/lib/c_glib/CMakeLists.txt
index 5e277f05b..3743a68dd 100644
--- a/lib/c_glib/CMakeLists.txt
+++ b/lib/c_glib/CMakeLists.txt
@@ -33,9 +33,12 @@ set(thrift_c_glib_SOURCES
src/thrift/c_glib/thrift_application_exception.c
src/thrift/c_glib/processor/thrift_processor.c
src/thrift/c_glib/processor/thrift_dispatch_processor.c
+ src/thrift/c_glib/processor/thrift_multiplexed_processor.c
src/thrift/c_glib/protocol/thrift_protocol.c
src/thrift/c_glib/protocol/thrift_protocol_factory.c
+ src/thrift/c_glib/protocol/thrift_protocol_decorator.c
src/thrift/c_glib/protocol/thrift_binary_protocol.c
+ src/thrift/c_glib/protocol/thrift_stored_message_protocol.c
src/thrift/c_glib/protocol/thrift_binary_protocol_factory.c
src/thrift/c_glib/protocol/thrift_compact_protocol.c
src/thrift/c_glib/protocol/thrift_compact_protocol_factory.c
diff --git a/lib/c_glib/Makefile.am b/lib/c_glib/Makefile.am
index 871766bdf..49b5b238c 100755
--- a/lib/c_glib/Makefile.am
+++ b/lib/c_glib/Makefile.am
@@ -34,10 +34,12 @@ libthrift_c_glib_la_SOURCES = src/thrift/c_glib/thrift.c \
src/thrift/c_glib/thrift_application_exception.c \
src/thrift/c_glib/processor/thrift_processor.c \
src/thrift/c_glib/processor/thrift_dispatch_processor.c \
+ src/thrift/c_glib/processor/thrift_multiplexed_processor.c \
src/thrift/c_glib/protocol/thrift_protocol.c \
src/thrift/c_glib/protocol/thrift_protocol_decorator.c \
src/thrift/c_glib/protocol/thrift_protocol_factory.c \
src/thrift/c_glib/protocol/thrift_binary_protocol.c \
+ src/thrift/c_glib/protocol/thrift_stored_message_protocol.c \
src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c \
src/thrift/c_glib/protocol/thrift_binary_protocol_factory.c \
src/thrift/c_glib/protocol/thrift_compact_protocol.c \
@@ -75,7 +77,9 @@ include_protocol_HEADERS = src/thrift/c_glib/protocol/thrift_protocol.h \
src/thrift/c_glib/protocol/thrift_binary_protocol_factory.h \
src/thrift/c_glib/protocol/thrift_compact_protocol.h \
src/thrift/c_glib/protocol/thrift_compact_protocol_factory.h \
- src/thrift/c_glib/protocol/thrift_multiplexed_protocol.h
+ src/thrift/c_glib/protocol/thrift_multiplexed_protocol.h \
+ src/thrift/c_glib/protocol/thrift_stored_message_protocol.h
+
include_transportdir = $(include_thriftdir)/transport
include_transport_HEADERS = src/thrift/c_glib/transport/thrift_buffered_transport.h \
@@ -98,7 +102,8 @@ include_server_HEADERS = src/thrift/c_glib/server/thrift_server.h \
include_processordir = $(include_thriftdir)/processor
include_processor_HEADERS = src/thrift/c_glib/processor/thrift_processor.h \
- src/thrift/c_glib/processor/thrift_dispatch_processor.h
+ src/thrift/c_glib/processor/thrift_dispatch_processor.h \
+ src/thrift/c_glib/processor/thrift_multiplexed_processor.h
EXTRA_DIST = \
diff --git a/lib/c_glib/src/thrift/c_glib/processor/thrift_multiplexed_processor.c b/lib/c_glib/src/thrift/c_glib/processor/thrift_multiplexed_processor.c
new file mode 100644
index 000000000..68a0f4d46
--- /dev/null
+++ b/lib/c_glib/src/thrift/c_glib/processor/thrift_multiplexed_processor.c
@@ -0,0 +1,346 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include <string.h>
+#include <stdio.h>
+
+#include <thrift/c_glib/thrift.h>
+#include <thrift/c_glib/processor/thrift_processor.h>
+#include <thrift/c_glib/processor/thrift_multiplexed_processor.h>
+#include <thrift/c_glib/protocol/thrift_multiplexed_protocol.h>
+#include <thrift/c_glib/protocol/thrift_stored_message_protocol.h>
+#include <thrift/c_glib/thrift_application_exception.h>
+
+G_DEFINE_TYPE(ThriftMultiplexedProcessor, thrift_multiplexed_processor, THRIFT_TYPE_PROCESSOR)
+
+
+enum
+{
+ PROP_THRIFT_MULTIPLEXED_PROCESSOR_DEFAULT_SERVICE_NAME = 1,
+ PROP_THRIFT_MULTIPLEXED_PROCESSOR_END
+};
+
+static GParamSpec *thrift_multiplexed_processor_obj_properties[PROP_THRIFT_MULTIPLEXED_PROCESSOR_END] = { NULL, };
+
+
+static gboolean
+thrift_multiplexed_processor_register_processor_impl(ThriftProcessor *processor, const gchar * multiplexed_processor_name, ThriftProcessor * multiplexed_processor , GError **error)
+{
+ ThriftMultiplexedProcessor *self = THRIFT_MULTIPLEXED_PROCESSOR(processor);
+ g_hash_table_replace(self->multiplexed_services,
+ g_strdup(multiplexed_processor_name),
+ g_object_ref (multiplexed_processor));
+
+ /* Make first registered become default */
+ if(!self->default_processor_name){
+ self->default_processor_name = g_strdup(multiplexed_processor_name);
+ }
+ return TRUE;
+}
+
+
+static gboolean
+thrift_multiplexed_processor_process_impl (ThriftProcessor *processor, ThriftProtocol *in,
+ ThriftProtocol *out, GError **error)
+{
+ gboolean retval = FALSE;
+ gboolean token_error = FALSE;
+ ThriftApplicationException *xception;
+ ThriftStoredMessageProtocol *stored_message_protocol = NULL;
+ ThriftMessageType message_type;
+ ThriftMultiplexedProcessor *self = THRIFT_MULTIPLEXED_PROCESSOR(processor);
+ ThriftProcessor *multiplexed_processor = NULL;
+ ThriftTransport *transport;
+ char *token=NULL;
+ int token_index=0;
+ char *state=NULL;
+ gchar *fname=NULL;
+ gint32 seqid, result;
+
+ /* FIXME It seems that previous processor is not managing error correctly */
+ if(*error!=NULL) {
+ g_debug ("thrift_multiplexed_processor: last error not removed: %s",
+ *error != NULL ? (*error)->message : "(null)");
+ g_clear_error (error);
+ }
+
+
+ THRIFT_PROTOCOL_GET_CLASS(in)->read_message_begin(in, &fname, &message_type, &seqid, error);
+
+ if(!(message_type == T_CALL || message_type == T_ONEWAY)) {
+ g_set_error (error,
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR,
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR_MESSAGE_TYPE,
+ "message type invalid for this processor");
+ }else{
+ /* Split by the token */
+ for (token = strtok_r(fname, THRIFT_MULTIPLEXED_PROTOCOL_DEFAULT_SEPARATOR, &state),
+ token_index=0;
+ token != NULL && !token_error;
+ token = strtok_r(NULL, THRIFT_MULTIPLEXED_PROTOCOL_DEFAULT_SEPARATOR, &state),
+ token_index++)
+ {
+ switch(token_index){
+ case 0:
+ /* It should be the service name */
+ multiplexed_processor = g_hash_table_lookup(self->multiplexed_services, token);
+ if(multiplexed_processor==NULL){
+ token_error=TRUE;
+ }
+ break;
+ case 1:
+ /* It should be the function name */
+ stored_message_protocol = g_object_new (THRIFT_TYPE_STORED_MESSAGE_PROTOCOL,
+ "protocol", in,
+ "name", token,
+ "type", message_type,
+ "seqid", seqid,
+ NULL);
+ break;
+ default:
+ g_set_error (error,
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR,
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR_MESSAGE_WRONGLY_MULTIPLEXED,
+ "the message has more tokens than expected!");
+ token_error=TRUE;
+ break;
+ }
+ }
+ /* Set default */
+ if(!stored_message_protocol &&
+ !multiplexed_processor &&
+ token_index==1 && self->default_processor_name){
+ /* It should be the service name */
+ multiplexed_processor = g_hash_table_lookup(self->multiplexed_services, self->default_processor_name);
+ if(multiplexed_processor==NULL){
+ g_set_error (error,
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR,
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR_SERVICE_UNAVAILABLE,
+ "service %s not available on this processor",
+ self->default_processor_name);
+ }else{
+ /* Set the message name to the original name */
+ stored_message_protocol = g_object_new (THRIFT_TYPE_STORED_MESSAGE_PROTOCOL,
+ "protocol", in,
+ "name", fname,
+ "type", message_type,
+ "seqid", seqid,
+ NULL);
+ }
+
+ }
+
+ if(stored_message_protocol!=NULL && multiplexed_processor!=NULL){
+ retval = THRIFT_PROCESSOR_GET_CLASS (multiplexed_processor)->process (multiplexed_processor, (ThriftProtocol *) stored_message_protocol, out, error) ;
+ }else{
+ if(!error)
+ g_set_error (error,
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR,
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR_SERVICE_UNAVAILABLE,
+ "service %s is not multiplexed in this processor",
+ fname);
+ }
+
+
+ }
+
+ if(!retval){
+ /* By default, return an application exception to the client indicating the
+ method name is not recognized. */
+ /* Copied from dispach processor */
+
+ if ((thrift_protocol_skip (in, T_STRUCT, error) < 0) ||
+ (thrift_protocol_read_message_end (in, error) < 0))
+ return retval;
+
+ g_object_get (in, "transport", &transport, NULL);
+ result = thrift_transport_read_end (transport, error);
+ g_object_unref (transport);
+ if (result < 0) {
+ /* We must free fname */
+ g_free(fname);
+ return retval;
+ }
+
+ if (thrift_protocol_write_message_begin (out,
+ fname,
+ T_EXCEPTION,
+ seqid,
+ error) < 0){
+ /* We must free fname */
+ g_free(fname);
+
+ return retval;
+ }
+
+
+ xception =
+ g_object_new (THRIFT_TYPE_APPLICATION_EXCEPTION,
+ "type", THRIFT_APPLICATION_EXCEPTION_ERROR_UNKNOWN_METHOD,
+ "message", (*error)->message,
+ NULL);
+ result = thrift_struct_write (THRIFT_STRUCT (xception),
+ out,
+ error);
+ g_object_unref (xception);
+ if ((result < 0) ||
+ (thrift_protocol_write_message_end (out, error) < 0))
+ return retval;
+
+ g_object_get (out, "transport", &transport, NULL);
+ retval =
+ ((thrift_transport_write_end (transport, error) >= 0) &&
+ (thrift_transport_flush (transport, error) >= 0));
+ g_object_unref (transport);
+ }else{
+ /* The protocol now has a copy we can free it */
+ g_free(fname);
+
+ }
+
+ /*
+ FIXME This makes everything fail, I don't know why.
+ if(stored_message_protocol!=NULL){
+ // After its use we must free it
+ g_object_unref(stored_message_protocol);
+ }
+ */
+ return retval;
+}
+
+/* define the GError domain for Thrift transports */
+GQuark
+thrift_multiplexed_processor_error_quark (void)
+{
+ return g_quark_from_static_string (THRIFT_MULTIPLEXED_PROCESSOR_ERROR_DOMAIN);
+}
+
+
+static void
+thrift_multiplexed_processor_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ ThriftMultiplexedProcessor *self = THRIFT_MULTIPLEXED_PROCESSOR (object);
+
+ switch (property_id)
+ {
+ case PROP_THRIFT_MULTIPLEXED_PROCESSOR_DEFAULT_SERVICE_NAME:
+ self->default_processor_name = g_value_dup_string (value);
+ break;
+
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+thrift_multiplexed_processor_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ ThriftMultiplexedProcessor *self = THRIFT_MULTIPLEXED_PROCESSOR (object);
+
+ switch (property_id)
+ {
+ case PROP_THRIFT_MULTIPLEXED_PROCESSOR_DEFAULT_SERVICE_NAME:
+ g_value_set_string (value, self->default_processor_name);
+ break;
+
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+/* destructor */
+static void
+thrift_multiplexed_processor_finalize (GObject *object)
+{
+ ThriftMultiplexedProcessor *self = THRIFT_MULTIPLEXED_PROCESSOR(object);
+
+ /* Free our multiplexed hash table */
+ g_hash_table_unref (self->multiplexed_services);
+ self->multiplexed_services = NULL;
+
+ if(self->default_processor_name){
+ g_free(self->default_processor_name);
+ self->default_processor_name=NULL;
+ }
+
+ /* Chain up to parent */
+ if (G_OBJECT_CLASS (thrift_multiplexed_processor_parent_class)->finalize)
+ (*G_OBJECT_CLASS (thrift_multiplexed_processor_parent_class)->finalize) (object);
+}
+
+/* class initializer for ThriftMultiplexedProcessor */
+static void
+thrift_multiplexed_processor_class_init (ThriftMultiplexedProcessorClass *cls)
+{
+ /* Override */
+ THRIFT_PROCESSOR_CLASS(cls)->process = thrift_multiplexed_processor_process_impl;
+ GObjectClass *gobject_class = G_OBJECT_CLASS (cls);
+
+ /* Object methods */
+ gobject_class->set_property = thrift_multiplexed_processor_set_property;
+ gobject_class->get_property = thrift_multiplexed_processor_get_property;
+ gobject_class->finalize = thrift_multiplexed_processor_finalize;
+
+ /* Class methods */
+ cls->register_processor = thrift_multiplexed_processor_register_processor_impl;
+
+
+ thrift_multiplexed_processor_obj_properties[PROP_THRIFT_MULTIPLEXED_PROCESSOR_DEFAULT_SERVICE_NAME] =
+ g_param_spec_string ("default",
+ "Default service name the protocol points to where no multiplexed client used",
+ "Set the default service name",
+ NULL,
+ (G_PARAM_READWRITE));
+
+ g_object_class_install_properties (gobject_class,
+ PROP_THRIFT_MULTIPLEXED_PROCESSOR_END,
+ thrift_multiplexed_processor_obj_properties);
+
+}
+
+static void
+thrift_multiplexed_processor_init (ThriftMultiplexedProcessor *self)
+{
+
+ /* Create our multiplexed services hash table */
+ self->multiplexed_services = g_hash_table_new_full (
+ g_str_hash,
+ g_str_equal,
+ g_free,
+ g_object_unref);
+ self->default_processor_name = NULL;
+}
+
+
+gboolean
+thrift_multiplexed_processor_register_processor(ThriftProcessor *processor, const gchar * multiplexed_processor_name, ThriftProcessor * multiplexed_processor , GError **error)
+{
+ return THRIFT_MULTIPLEXED_PROCESSOR_GET_CLASS(processor)->register_processor(processor, multiplexed_processor_name, multiplexed_processor, error);
+}
+
+
diff --git a/lib/c_glib/src/thrift/c_glib/processor/thrift_multiplexed_processor.h b/lib/c_glib/src/thrift/c_glib/processor/thrift_multiplexed_processor.h
new file mode 100644
index 000000000..6406616c2
--- /dev/null
+++ b/lib/c_glib/src/thrift/c_glib/processor/thrift_multiplexed_processor.h
@@ -0,0 +1,114 @@
+/*
+ * thrift_multiplexed_processor.h
+ *
+ * Created on: 14 sept. 2017
+ * Author: gaguilar
+ */
+
+#ifndef _THRIFT_MULTIPLEXED_MULTIPLEXED_PROCESSOR_H_
+#define _THRIFT_MULTIPLEXED_MULTIPLEXED_PROCESSOR_H_
+
+
+#include <glib-object.h>
+
+#include <thrift/c_glib/processor/thrift_processor.h>
+
+
+G_BEGIN_DECLS
+
+/*! \file thrift_multiplexed_processor.h
+ * \brief The multiplexed processor for c_glib.
+ */
+
+/* type macros */
+#define THRIFT_TYPE_MULTIPLEXED_PROCESSOR (thrift_multiplexed_processor_get_type ())
+#define THRIFT_MULTIPLEXED_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_MULTIPLEXED_PROCESSOR, ThriftMultiplexedProcessor))
+#define THRIFT_IS_MULTIPLEXED_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_MULTIPLEXED_PROCESSOR))
+#define THRIFT_MULTIPLEXED_PROCESSOR_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_MULTIPLEXED_PROCESSOR, ThriftMultiplexedProcessorClass))
+#define THRIFT_IS_MULTIPLEXED_PROCESSOR_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_MULTIPLEXED_PROCESSOR))
+#define THRIFT_MULTIPLEXED_PROCESSOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_MULTIPLEXED_PROCESSOR, ThriftMultiplexedProcessorClass))
+
+/* define the GError domain string */
+#define THRIFT_MULTIPLEXED_PROCESSOR_ERROR_DOMAIN "thrift-multiplexed-processor-error-quark"
+
+
+/*!
+ * Thrift MultiplexedProcessor object
+ */
+struct _ThriftMultiplexedProcessor
+{
+ ThriftProcessor parent;
+
+ /* private */
+ gchar * default_processor_name;
+ GHashTable *multiplexed_services;
+};
+typedef struct _ThriftMultiplexedProcessor ThriftMultiplexedProcessor;
+
+/*!
+ * Thrift MultiplexedProcessor class
+ */
+struct _ThriftMultiplexedProcessorClass
+{
+ ThriftProcessorClass parent;
+
+ gboolean (* register_processor) (ThriftProcessor *self, const gchar * multiplexed_processor_name, ThriftProcessor * multiplexed_processor , GError **error);
+
+};
+typedef struct _ThriftMultiplexedProcessorClass ThriftMultiplexedProcessorClass;
+
+/* used by THRIFT_TYPE_MULTIPLEXED_PROCESSOR */
+GType thrift_multiplexed_processor_get_type (void);
+
+/*!
+ * Processes the request.
+ * \public \memberof ThriftMultiplexedProcessorClass
+ */
+gboolean thrift_multiplexed_processor_process (ThriftMultiplexedProcessor *processor,
+ ThriftProtocol *in, ThriftProtocol *out,
+ GError **error);
+
+
+/* Public API */
+
+/**
+ * @brief Registers a processor in the multiplexed processor under its name. It
+ * will take a reference to the processor so refcount will be incremented.
+ * It will also be decremented on object destruction.
+ *
+ * The first registered processor becomes default. But you can override it with
+ * "default" property.
+ *
+ * It returns a compliant error if it cannot be registered.
+ *
+ * @param processor Pointer to the multiplexed processor.
+ * @param multiplexed_processor_name Name of the processor you want to register
+ * @param multiplexed_processor Pointer to implemented processor you want multiplex.
+ * @param error Error object where we should store errors.
+ *
+ * @see https://developer.gnome.org/glib/stable/glib-Error-Reporting.html#g-set-error
+ */
+gboolean thrift_multiplexed_processor_register_processor(ThriftProcessor *processor, const gchar * multiplexed_processor_name, ThriftProcessor * multiplexed_processor , GError **error);
+
+
+/* define error/exception types */
+typedef enum
+{
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR_UNKNOWN,
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR_SERVICE_UNAVAILABLE,
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR_MESSAGE_TYPE,
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR_MESSAGE_WRONGLY_MULTIPLEXED,
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR_SEND,
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR_RECEIVE,
+ THRIFT_MULTIPLEXED_PROCESSOR_ERROR_CLOSE
+} ThriftMultiplexedProcessorError;
+
+
+GQuark thrift_multiplexed_processor_error_quark (void);
+#define THRIFT_MULTIPLEXED_PROCESSOR_ERROR (thrift_multiplexed_processor_error_quark ())
+
+
+G_END_DECLS
+
+
+#endif /* _THRIFT_MULTIPLEXED_MULTIPLEXED_PROCESSOR_H_ */
diff --git a/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c b/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c
index c74f048c9..727f4a87c 100644
--- a/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c
+++ b/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c
@@ -57,7 +57,7 @@ thrift_multiplexed_protocol_write_message_begin (ThriftMultiplexedProtocol *prot
service_name = g_strdup(name);
}
- // relay to the protocol_decorator
+ /* relay to the protocol_decorator */
ret = thrift_protocol_decorator_write_message_begin(protocol, service_name, message_type, seqid, error);
g_free(service_name);
diff --git a/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.c b/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.c
index 1feec3474..03f9420f7 100644
--- a/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.c
+++ b/lib/c_glib/src/thrift/c_glib/protocol/thrift_protocol_decorator.c
@@ -486,13 +486,11 @@ thrift_protocol_decorator_set_property (GObject *object,
GParamSpec *pspec)
{
ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (object);
- g_debug("Is protocol decorator %i", THRIFT_IS_PROTOCOL_DECORATOR(object));
switch (property_id)
{
case PROP_THRIFT_TYPE_PROTOCOL_DECORATOR_CONCRETE_PROTOCOL:
self->concrete_protocol = g_value_dup_object (value);
- g_debug("Setting concrete protocol %p to %p in %s", (void *)self, (void *)self->concrete_protocol, g_type_name(G_TYPE_FROM_INSTANCE(object)));
break;
default:
@@ -509,7 +507,6 @@ thrift_protocol_decorator_get_property (GObject *object,
GParamSpec *pspec)
{
ThriftProtocolDecorator *self = THRIFT_PROTOCOL_DECORATOR (object);
- g_debug("Is protocol decorator %i", THRIFT_IS_PROTOCOL_DECORATOR(object));
switch (property_id)
{
diff --git a/lib/c_glib/src/thrift/c_glib/protocol/thrift_stored_message_protocol.c b/lib/c_glib/src/thrift/c_glib/protocol/thrift_stored_message_protocol.c
new file mode 100644
index 000000000..a0d560bfc
--- /dev/null
+++ b/lib/c_glib/src/thrift/c_glib/protocol/thrift_stored_message_protocol.c
@@ -0,0 +1,192 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <glib.h>
+#include <glib-object.h>
+
+#include <thrift/c_glib/thrift.h>
+#include <thrift/c_glib/protocol/thrift_protocol.h>
+#include <thrift/c_glib/protocol/thrift_protocol_decorator.h>
+#include <thrift/c_glib/protocol/thrift_stored_message_protocol.h>
+
+
+enum
+{
+ PROP_THRIFT_STORED_MESSAGE_PROTOCOL_MESSAGE_NAME = 1,
+ PROP_THRIFT_STORED_MESSAGE_PROTOCOL_MESSAGE_TYPE,
+ PROP_THRIFT_STORED_MESSAGE_PROTOCOL_SEQUENCE_ID,
+ PROP_THRIFT_STORED_MESSAGE_PROTOCOL_TRANSPORT, /* TODO ugly hack */
+ PROP_THRIFT_STORED_MESSAGE_PROTOCOL_END
+};
+
+G_DEFINE_TYPE(ThriftStoredMessageProtocol, thrift_stored_message_protocol, THRIFT_TYPE_PROTOCOL_DECORATOR)
+
+
+static GParamSpec *thrift_stored_message_protocol_obj_properties[PROP_THRIFT_STORED_MESSAGE_PROTOCOL_END] = { NULL, };
+
+gint32
+thrift_stored_message_protocol_read_message_begin (ThriftProtocol *protocol,
+ gchar **name,
+ ThriftMessageType *message_type,
+ gint32 *seqid, GError **error)
+{
+ gint32 ret = 0;
+ g_return_val_if_fail (THRIFT_IS_STORED_MESSAGE_PROTOCOL (protocol), -1);
+ THRIFT_UNUSED_VAR (error);
+
+ ThriftStoredMessageProtocol *self = THRIFT_STORED_MESSAGE_PROTOCOL (protocol);
+
+ /* We return the stored values on construction */
+ *name = self->name;
+ *message_type = self->mtype;
+ *seqid = self->seqid;
+
+ return ret;
+}
+
+
+static void
+thrift_stored_message_protocol_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ ThriftStoredMessageProtocol *self = THRIFT_STORED_MESSAGE_PROTOCOL (object);
+
+ switch (property_id)
+ {
+ case PROP_THRIFT_STORED_MESSAGE_PROTOCOL_MESSAGE_NAME:
+ self->name = g_value_dup_string (value);
+ break;
+ case PROP_THRIFT_STORED_MESSAGE_PROTOCOL_MESSAGE_TYPE:
+ self->mtype = g_value_get_int (value);
+ break;
+ case PROP_THRIFT_STORED_MESSAGE_PROTOCOL_SEQUENCE_ID:
+ self->seqid = g_value_get_int (value);
+ break;
+
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+thrift_stored_message_protocol_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ ThriftStoredMessageProtocol *self = THRIFT_STORED_MESSAGE_PROTOCOL (object);
+ ThriftProtocolDecorator *decorator = THRIFT_PROTOCOL_DECORATOR (object);
+ ThriftTransport *transport=NULL;
+ switch (property_id)
+ {
+ case PROP_THRIFT_STORED_MESSAGE_PROTOCOL_MESSAGE_NAME:
+ g_value_set_string (value, self->name);
+ break;
+ case PROP_THRIFT_STORED_MESSAGE_PROTOCOL_TRANSPORT:
+ /* FIXME Since we don't override properties in the decorator as it should
+ we just override the properties that we know are used */
+ g_object_get(decorator->concrete_protocol,pspec->name, &transport, NULL);
+ g_value_set_pointer (value, transport);
+ break;
+
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void
+thrift_stored_message_protocol_init (ThriftStoredMessageProtocol *protocol)
+{
+ protocol->name = NULL;
+}
+
+static void
+thrift_stored_message_protocol_finalize (GObject *gobject)
+{
+ ThriftStoredMessageProtocol *self = THRIFT_STORED_MESSAGE_PROTOCOL (gobject);
+
+ if (self->name) {
+ g_free(self->name);
+ self->name = NULL;
+ }
+
+ /* Always chain up to the parent class; as with dispose(), finalize()
+ * is guaranteed to exist on the parent's class virtual function table
+ */
+ G_OBJECT_CLASS (thrift_stored_message_protocol_parent_class)->finalize(gobject);
+}
+
+
+/* initialize the class */
+static void
+thrift_stored_message_protocol_class_init (ThriftStoredMessageProtocolClass *klass)
+{
+ ThriftProtocolClass *cls = THRIFT_PROTOCOL_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ cls->read_message_begin = thrift_stored_message_protocol_read_message_begin;
+
+ object_class->set_property = thrift_stored_message_protocol_set_property;
+ object_class->get_property = thrift_stored_message_protocol_get_property;
+ object_class->finalize = thrift_stored_message_protocol_finalize;
+
+ thrift_stored_message_protocol_obj_properties[PROP_THRIFT_STORED_MESSAGE_PROTOCOL_MESSAGE_NAME] =
+ g_param_spec_string ("name",
+ "Service name the protocol points to",
+ "Set the service name",
+ NULL,
+ (G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+ thrift_stored_message_protocol_obj_properties[PROP_THRIFT_STORED_MESSAGE_PROTOCOL_MESSAGE_TYPE] =
+ g_param_spec_int ("type",
+ "Message type in the wire",
+ "Set the message type in the wire",
+ T_CALL, T_ONEWAY,
+ T_CALL,
+ (G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+ thrift_stored_message_protocol_obj_properties[PROP_THRIFT_STORED_MESSAGE_PROTOCOL_SEQUENCE_ID] =
+ g_param_spec_int ("seqid",
+ "Sequence id type in the wire",
+ "Set the Sequence id in the wire",
+ 0, G_MAXINT,
+ 0,
+ (G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+
+ /* TODO Ugly hack, in theory we must override all properties from underlaying
+ protocol */
+ thrift_stored_message_protocol_obj_properties[PROP_THRIFT_STORED_MESSAGE_PROTOCOL_TRANSPORT] =
+ g_param_spec_pointer ("transport",
+ "Transport on the underlaying implementation",
+ "Transport of decorated protocol",
+ G_PARAM_READABLE);
+
+
+
+ g_object_class_install_properties (object_class,
+ PROP_THRIFT_STORED_MESSAGE_PROTOCOL_END,
+ thrift_stored_message_protocol_obj_properties);
+}
diff --git a/lib/c_glib/src/thrift/c_glib/protocol/thrift_stored_message_protocol.h b/lib/c_glib/src/thrift/c_glib/protocol/thrift_stored_message_protocol.h
new file mode 100644
index 000000000..88782ac36
--- /dev/null
+++ b/lib/c_glib/src/thrift/c_glib/protocol/thrift_stored_message_protocol.h
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef _THRIFT_STORED_MESSAGE_PROTOCOL_H
+#define _THRIFT_STORED_MESSAGE_PROTOCOL_H
+
+#include <glib-object.h>
+
+#include <thrift/c_glib/protocol/thrift_protocol.h>
+#include <thrift/c_glib/protocol/thrift_protocol_decorator.h>
+#include <thrift/c_glib/transport/thrift_transport.h>
+
+G_BEGIN_DECLS
+
+/*! \file thrift_stored_message_protocol.h
+ * \brief StoredMessage protocol implementation of a pre-stored message header
+ * on Thrift protocol. Implements the ThriftProtocol interface.
+ */
+
+/* type macros */
+#define THRIFT_TYPE_STORED_MESSAGE_PROTOCOL (thrift_stored_message_protocol_get_type ())
+#define THRIFT_STORED_MESSAGE_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_STORED_MESSAGE_PROTOCOL, ThriftStoredMessageProtocol))
+#define THRIFT_IS_STORED_MESSAGE_PROTOCOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_STORED_MESSAGE_PROTOCOL))
+#define THRIFT_STORED_MESSAGE_PROTOCOL_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_STORED_MESSAGE_PROTOCOL, ThriftStoredMessageProtocolClass))
+#define THRIFT_IS_STORED_MESSAGE_PROTOCOL_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_STORED_MESSAGE_PROTOCOL))
+#define THRIFT_STORED_MESSAGE_PROTOCOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_STORED_MESSAGE_PROTOCOL, ThriftStoredMessageProtocolClass))
+
+/* constant */
+#define THRIFT_STORED_MESSAGE_PROTOCOL_DEFAULT_SEPARATOR ":"
+
+typedef struct _ThriftStoredMessageProtocol ThriftStoredMessageProtocol;
+
+
+
+/*!
+ * Thrift StoredMessage Protocol instance.
+ */
+struct _ThriftStoredMessageProtocol
+{
+ ThriftProtocolDecorator parent;
+
+ gchar *name;
+ ThriftMessageType mtype;
+ gint32 seqid;
+};
+
+typedef struct _ThriftStoredMessageProtocolClass ThriftStoredMessageProtocolClass;
+
+/*!
+ * Thrift StoredMessage Protocol class.
+ */
+struct _ThriftStoredMessageProtocolClass
+{
+ ThriftProtocolDecoratorClass parent;
+};
+
+/* used by THRIFT_TYPE_STORED_MESSAGE_PROTOCOL */
+GType thrift_stored_message_protocol_get_type (void);
+
+G_END_DECLS
+
+#endif /* _THRIFT_STORED_MESSAGE_PROTOCOL_H */
diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_platform_socket.h b/lib/c_glib/src/thrift/c_glib/transport/thrift_platform_socket.h
index ef4f00d1e..ede60f172 100644
--- a/lib/c_glib/src/thrift/c_glib/transport/thrift_platform_socket.h
+++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_platform_socket.h
@@ -17,7 +17,7 @@
* under the License.
*/
-// clang-format off
+/* clang-format off */
#ifndef _THRIFT_TRANSPORT_PLATFORM_SOCKET_H_
# define _THRIFT_TRANSPORT_PLATFORM_SOCKET_H_
@@ -63,17 +63,17 @@
# define THRIFT_TIMESPEC thrift_timespec
# define THRIFT_CTIME_R thrift_ctime_r
# define THRIFT_POLL thrift_poll
-# if WINVER <= 0x0502 //XP, Server2003
+# if WINVER <= 0x0502 /* XP, Server2003 */
# define THRIFT_POLLFD thrift_pollfd
# define THRIFT_POLLIN 0x0300
# define THRIFT_POLLOUT 0x0010
-# else //Vista, Win7...
+# else /* Vista, Win7... */
# define THRIFT_POLLFD pollfd
# define THRIFT_POLLIN POLLIN
# define THRIFT_POLLOUT POLLOUT
-# endif //WINVER
+# endif /* WINVER */
# define THRIFT_SHUT_RDWR SD_BOTH
-#else //not _WIN32
+#else /* not _WIN32 */
# include <errno.h>
# define THRIFT_GET_SOCKET_ERROR errno
# define THRIFT_ERRNO errno
@@ -117,4 +117,4 @@
# define THRIFT_SHUT_RDWR SHUT_RDWR
#endif
-#endif // _THRIFT_TRANSPORT_PLATFORM_SOCKET_H_
+#endif /* _THRIFT_TRANSPORT_PLATFORM_SOCKET_H_ */
diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.c b/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.c
index ce6b344e7..6dd0f0d3a 100644
--- a/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.c
+++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.c
@@ -95,6 +95,25 @@ thrift_socket_peek (ThriftTransport *transport, GError **error)
return result;
}
+
+/* implements thrift_transport_close */
+gboolean
+thrift_socket_close (ThriftTransport *transport, GError **error)
+{
+ ThriftSocket *socket = THRIFT_SOCKET (transport);
+
+ if (close (socket->sd) == -1)
+ {
+ g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_CLOSE,
+ "unable to close socket - %s",
+ strerror(errno));
+ return FALSE;
+ }
+
+ socket->sd = THRIFT_INVALID_SOCKET;
+ return TRUE;
+}
+
/* implements thrift_transport_open */
gboolean
thrift_socket_open (ThriftTransport *transport, GError **error)
@@ -128,7 +147,7 @@ thrift_socket_open (ThriftTransport *transport, GError **error)
/* create a socket structure */
memset (&pin, 0, sizeof(pin));
pin.sin_family = AF_INET;
- pin.sin_addr.s_addr = ((struct in_addr *) (hp->h_addr))->s_addr;
+ pin.sin_addr.s_addr = ((struct in_addr *) (hp->h_addr_list[0]))->s_addr;
pin.sin_port = htons (tsocket->port);
/* create the socket */
@@ -144,7 +163,8 @@ thrift_socket_open (ThriftTransport *transport, GError **error)
/* open a connection */
if (connect (tsocket->sd, (struct sockaddr *) &pin, sizeof(pin)) == -1)
{
- g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_CONNECT,
+ thrift_socket_close(tsocket, NULL);
+ g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_CONNECT,
"failed to connect to host %s:%d - %s",
tsocket->hostname, tsocket->port, strerror(errno));
return FALSE;
@@ -153,23 +173,6 @@ thrift_socket_open (ThriftTransport *transport, GError **error)
return TRUE;
}
-/* implements thrift_transport_close */
-gboolean
-thrift_socket_close (ThriftTransport *transport, GError **error)
-{
- ThriftSocket *socket = THRIFT_SOCKET (transport);
-
- if (close (socket->sd) == -1)
- {
- g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_CLOSE,
- "unable to close socket - %s",
- strerror(errno));
- return FALSE;
- }
-
- socket->sd = THRIFT_INVALID_SOCKET;
- return TRUE;
-}
/* implements thrift_transport_read */
gint32
diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.c b/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.c
index 4abeb9341..ee5540685 100644
--- a/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.c
+++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.c
@@ -140,6 +140,84 @@ static void thrift_ssl_socket_dyn_lock_destroy_callback(void* lock, const char*
G_DEFINE_TYPE(ThriftSSLSocket, thrift_ssl_socket, THRIFT_TYPE_SOCKET)
+
+/**
+ * When there's a thread context attached, we pass the SSL socket context so it
+ * can check if the error is outside SSL, on I/O for example
+ * @param socket
+ * @param error_msg
+ * @param thrift_error_no
+ * @param ssl_error
+ * @param error
+ */
+static
+void thrift_ssl_socket_get_ssl_error(ThriftSSLSocket *socket, const guchar *error_msg, guint thrift_error_no, int ssl_error, GError **error)
+{
+ unsigned long error_code;
+ char buffer[1024];
+ int buffer_size=1024;
+ gboolean first_error = TRUE;
+ int ssl_error_type = SSL_get_error(socket->ssl, ssl_error);
+ if(ssl_error_type>0){
+ switch(ssl_error_type){
+ case SSL_ERROR_SSL:
+ buffer_size-=snprintf(buffer, buffer_size, "SSL %s: ", error_msg);
+ while ((error_code = ERR_get_error()) != 0 && buffer_size>1) {
+ const char* reason = ERR_reason_error_string(error_code);
+ if(reason!=NULL){
+ if(!first_error) {
+ buffer_size-=snprintf(buffer+(1024-buffer_size), buffer_size, "\n\t");
+ first_error=FALSE;
+ }
+ buffer_size-=snprintf(buffer+(1024-buffer_size), buffer_size, "%lX(%s) -> %s", error_code, reason, SSL_state_string(socket->ssl));
+ }
+ }
+ break;
+ case SSL_ERROR_SYSCALL:
+ buffer_size-=snprintf(buffer, buffer_size, "%s: ", error_msg);
+ buffer_size-=snprintf(buffer+(1024-buffer_size), buffer_size, "%lX -> %s", errno, strerror(errno));
+ break;
+ case SSL_ERROR_WANT_READ:
+ buffer_size-=snprintf(buffer, buffer_size, "%s: ", error_msg);
+ buffer_size-=snprintf(buffer+(1024-buffer_size), buffer_size, "%lX -> %s", ssl_error_type, "Error while reading from underlaying layer");
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ buffer_size-=snprintf(buffer, buffer_size, "%s: ", error_msg);
+ buffer_size-=snprintf(buffer+(1024-buffer_size), buffer_size, "%lX -> %s", ssl_error_type, "Error while writting to underlaying layer");
+ break;
+
+ }
+ g_set_error (error, THRIFT_TRANSPORT_ERROR,
+ thrift_error_no, "%s", buffer);
+ }
+}
+
+/**
+ * For global SSL errors
+ * @param error_msg
+ * @param thrift_error_no
+ * @param error
+ */
+static
+void thrift_ssl_socket_get_error(const guchar *error_msg, guint thrift_error_no, GError **error)
+{
+ unsigned long error_code;
+ while ((error_code = ERR_get_error()) != 0) {
+ const char* reason = ERR_reason_error_string(error_code);
+ if (reason == NULL) {
+ g_set_error (error, THRIFT_TRANSPORT_ERROR,
+ thrift_error_no,
+ "SSL error %lX: %s", error_code, error_msg);
+ }else{
+ g_set_error (error, THRIFT_TRANSPORT_ERROR,
+ thrift_error_no,
+ "SSL error %lX %s: %s", error_code,reason, error_msg);
+ }
+ }
+}
+
+
+
/* implements thrift_transport_is_open */
gboolean
thrift_ssl_socket_is_open (ThriftTransport *transport)
@@ -159,10 +237,8 @@ thrift_ssl_socket_peek (ThriftTransport *transport, GError **error)
gchar byte;
rc = SSL_peek(ssl_socket->ssl, &byte, 1);
if (rc < 0) {
- g_set_error (error,
- THRIFT_TRANSPORT_ERROR,
- THRIFT_SSL_SOCKET_ERROR_SSL,
- "failed to peek at socket - id?");
+ thrift_ssl_socket_get_ssl_error(ssl_socket, "Check socket data",
+ THRIFT_SSL_SOCKET_ERROR_SSL, rc, error);
}
if (rc == 0) {
ERR_clear_error();
@@ -176,13 +252,14 @@ thrift_ssl_socket_peek (ThriftTransport *transport, GError **error)
gboolean
thrift_ssl_socket_open (ThriftTransport *transport, GError **error)
{
+ ERR_clear_error();
+
if (!thrift_socket_open(transport, error)) {
return FALSE;
}
if (!THRIFT_SSL_SOCKET_GET_CLASS(transport)->handle_handshake(transport, error)) {
- GError *tmperr;
- thrift_socket_close(transport, &tmperr);
+ thrift_ssl_socket_close(transport, NULL);
return FALSE;
}
@@ -194,13 +271,14 @@ gboolean
thrift_ssl_socket_close (ThriftTransport *transport, GError **error)
{
gboolean retval = FALSE;
- if(THRIFT_SSL_SOCKET(transport)->ssl) {
- int rc = SSL_shutdown(THRIFT_SSL_SOCKET(transport)->ssl);
- if (rc < 0) {
+ ThriftSSLSocket *ssl_socket = THRIFT_SSL_SOCKET(transport);
+ if(ssl_socket!=NULL && ssl_socket->ssl) {
+ int rc = SSL_shutdown(ssl_socket->ssl);
+/* if (rc < 0) {
int errno_copy = THRIFT_SSL_SOCKET_ERROR_SSL;
- }
- SSL_free(THRIFT_SSL_SOCKET(transport)->ssl);
- THRIFT_SSL_SOCKET(transport)->ssl = NULL;
+ }*/
+ SSL_free(ssl_socket->ssl);
+ ssl_socket->ssl = NULL;
ERR_remove_state(0);
}
return thrift_socket_close(transport, error);
@@ -216,9 +294,9 @@ thrift_ssl_socket_read (ThriftTransport *transport, gpointer buf,
guint bytes = 0;
guint retries = 0;
ThriftSocket *socket = THRIFT_SOCKET (transport);
- g_return_val_if_fail (socket->sd != THRIFT_INVALID_SOCKET, FALSE);
+ g_return_val_if_fail (socket->sd != THRIFT_INVALID_SOCKET && ssl_socket->ssl!=NULL, FALSE);
- for (retries=0; retries < maxRecvRetries_; retries++) {
+ for (retries=0; retries < maxRecvRetries_; retries++) {
bytes = SSL_read(ssl_socket->ssl, buf, len);
if (bytes >= 0)
break;
@@ -227,10 +305,11 @@ thrift_ssl_socket_read (ThriftTransport *transport, gpointer buf,
if (ERR_get_error() == 0 && errno_copy == THRIFT_EINTR) {
continue;
}
+ }else{
+ thrift_ssl_socket_get_ssl_error(ssl_socket, "Receive error",
+ THRIFT_SSL_SOCKET_ERROR_SSL, bytes, error);
+
}
- g_set_error (error, THRIFT_TRANSPORT_ERROR,
- THRIFT_TRANSPORT_ERROR_RECEIVE,
- "failed to read %d bytes - %s", len, strerror(errno));
return -1;
}
return bytes;
@@ -256,16 +335,15 @@ thrift_ssl_socket_write (ThriftTransport *transport, const gpointer buf,
gint ret = 0;
guint sent = 0;
ThriftSocket *socket = THRIFT_SOCKET (transport);
- g_return_val_if_fail (socket->sd != THRIFT_INVALID_SOCKET, FALSE);
+ g_return_val_if_fail (socket->sd != THRIFT_INVALID_SOCKET && ssl_socket->ssl!=NULL, FALSE);
while (sent < len)
{
ret = SSL_write (ssl_socket->ssl, (guint8 *)buf + sent, len - sent);
if (ret < 0)
{
- g_set_error (error, THRIFT_TRANSPORT_ERROR,
- THRIFT_TRANSPORT_ERROR_SEND,
- "failed to send %d bytes - %s", len, strerror(errno));
+ thrift_ssl_socket_get_ssl_error(ssl_socket, "Send error",
+ THRIFT_SSL_SOCKET_ERROR_SSL, ret, error);
return FALSE;
}
sent += ret;
@@ -295,7 +373,7 @@ thrift_ssl_socket_flush (ThriftTransport *transport, GError **error)
guint sent = 0;
ThriftSocket *socket = THRIFT_SOCKET (transport);
- g_return_val_if_fail (socket->sd != THRIFT_INVALID_SOCKET, FALSE);
+ g_return_val_if_fail (socket->sd != THRIFT_INVALID_SOCKET && ssl_socket->ssl!=NULL, FALSE);
BIO* bio = SSL_get_wbio(ssl_socket->ssl);
if (bio == NULL) {
@@ -331,8 +409,7 @@ thrift_ssl_socket_handle_handshake(ThriftTransport * transport, GError **error)
rc = SSL_connect(ssl_socket->ssl);
}
if (rc <= 0) {
- fprintf(stderr,"The error returned was %d\n", SSL_get_error(ssl_socket->ssl, rc));
- thrift_ssl_socket_get_error(error, "Not possible to connect", THRIFT_SSL_SOCKET_ERROR_CIPHER_NOT_AVAILABLE);
+ thrift_ssl_socket_get_ssl_error(ssl_socket, "Error while connect/bind", THRIFT_SSL_SOCKET_ERROR_CONNECT_BIND, rc, error);
return FALSE;
}
}else
@@ -390,16 +467,16 @@ gboolean thrift_ssl_load_cert_from_buffer(ThriftSSLSocket *ssl_socket, const cha
X509_STORE *cert_store = SSL_CTX_get_cert_store(ssl_socket->ctx);
if(cert_store!=NULL){
- int index = 0;
- while ((cacert = PEM_read_bio_X509(mem, NULL, 0, NULL))!=NULL) {
- if(cacert) {
- X509_STORE_add_cert(cert_store, cacert);
- X509_free(cacert);
- cacert=NULL;
- } /* Free immediately */
- index++;
- }
- retval=TRUE;
+ int index = 0;
+ while ((cacert = PEM_read_bio_X509(mem, NULL, 0, NULL))!=NULL) {
+ if(cacert) {
+ X509_STORE_add_cert(cert_store, cacert);
+ X509_free(cacert);
+ cacert=NULL;
+ } /* Free immediately */
+ index++;
+ }
+ retval=TRUE;
}
BIO_free(mem);
return retval;
@@ -416,46 +493,46 @@ thrift_ssl_socket_authorize(ThriftTransport * transport, GError **error)
if(cls!=NULL && ssl_socket->ssl!=NULL){
int rc = SSL_get_verify_result(ssl_socket->ssl);
if (rc != X509_V_OK) { /* verify authentication result */
- if (rc == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT && ssl_socket->allow_selfsigned) {
- g_debug("The certificate is a self-signed certificate and configuration allows it");
- } else {
- g_set_error (error,
- THRIFT_TRANSPORT_ERROR,
- THRIFT_SSL_SOCKET_ERROR_SSL_CERT_VALIDATION_FAILED,
- "The certificate verification failed: %s (%d)", X509_verify_cert_error_string(rc), rc);
- return FALSE;
- }
+ if (rc == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT && ssl_socket->allow_selfsigned) {
+ g_debug("The certificate is a self-signed certificate and configuration allows it");
+ } else {
+ g_set_error (error,
+ THRIFT_TRANSPORT_ERROR,
+ THRIFT_SSL_SOCKET_ERROR_SSL_CERT_VALIDATION_FAILED,
+ "The certificate verification failed: %s (%d)", X509_verify_cert_error_string(rc), rc);
+ return FALSE;
+ }
}
X509* cert = SSL_get_peer_certificate(ssl_socket->ssl);
if (cert == NULL) {
- if (SSL_get_verify_mode(ssl_socket->ssl) & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
- g_set_error (error,
- THRIFT_TRANSPORT_ERROR,
- THRIFT_SSL_SOCKET_ERROR_SSL_CERT_VALIDATION_FAILED,
- "No certificate present. Are you connecting SSL server?");
- return FALSE;
- }
- g_debug("No certificate required");
- return TRUE;
+ if (SSL_get_verify_mode(ssl_socket->ssl) & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
+ g_set_error (error,
+ THRIFT_TRANSPORT_ERROR,
+ THRIFT_SSL_SOCKET_ERROR_SSL_CERT_VALIDATION_FAILED,
+ "No certificate present. Are you connecting SSL server?");
+ return FALSE;
+ }
+ g_debug("No certificate required");
+ return TRUE;
}
/* certificate is present, since we don't support access manager we are done */
if (cls->authorize_peer == NULL) {
- X509_free(cert);
- g_debug("Certificate presented but we're not checking it");
- return TRUE;
+ X509_free(cert);
+ g_debug("Certificate presented but we're not checking it");
+ return TRUE;
} else {
- /* both certificate and access manager are present */
- struct sockaddr_storage sa;
- socklen_t saLength = sizeof(struct sockaddr_storage);
- if (getpeername(socket->sd, (struct sockaddr*)&sa, &saLength) != 0) {
- sa.ss_family = AF_UNSPEC;
- }
- authorization_result = cls->authorize_peer(transport, cert, &sa, error);
+ /* both certificate and access manager are present */
+ struct sockaddr_storage sa;
+ socklen_t saLength = sizeof(struct sockaddr_storage);
+ if (getpeername(socket->sd, (struct sockaddr*)&sa, &saLength) != 0) {
+ sa.ss_family = AF_UNSPEC;
+ }
+ authorization_result = cls->authorize_peer(transport, cert, &sa, error);
}
if(cert != NULL) {
- X509_free(cert);
+ X509_free(cert);
}
}
@@ -499,8 +576,8 @@ thrift_ssl_socket_finalize (GObject *object)
if(socket->ctx!=NULL){
g_debug("Freeing the context for the instance");
SSL_CTX_free(socket->ctx);
+ socket->ctx=NULL;
}
- socket->ctx=NULL;
}
if (G_OBJECT_CLASS (thrift_ssl_socket_parent_class)->finalize)
@@ -538,7 +615,7 @@ thrift_ssl_socket_set_property (GObject *object, guint property_id,
g_debug("Freeing the context since we are setting a new one");
SSL_CTX_free(socket->ctx);
}
- socket->ctx = g_value_get_pointer(value); // We copy the context
+ socket->ctx = g_value_get_pointer(value); /* We copy the context */
break;
case PROP_THRIFT_SSL_SELF_SIGNED:
@@ -664,7 +741,7 @@ thrift_ssl_socket_new_with_host(ThriftSSLSocketProtocol ssl_protocol, gchar *hos
SSL_CTX *ssl_context = NULL;
/* Create the context */
if((ssl_context=thrift_ssl_socket_context_initialize(ssl_protocol, error))==NULL){
- // FIXME Do error control
+ /* FIXME Do error control */
return thriftSSLSocket;
}
/* FIXME if the protocol is different? */
@@ -712,35 +789,18 @@ thrift_ssl_socket_context_initialize(ThriftSSLSocketProtocol ssl_protocol, GErro
}
if (context == NULL) {
- thrift_ssl_socket_get_error(error, "No cipher overlay", THRIFT_SSL_SOCKET_ERROR_CIPHER_NOT_AVAILABLE);
+ thrift_ssl_socket_get_error("No cipher overlay", THRIFT_SSL_SOCKET_ERROR_CIPHER_NOT_AVAILABLE, error);
return NULL;
}
SSL_CTX_set_mode(context, SSL_MODE_AUTO_RETRY);
- // Disable horribly insecure SSLv2 and SSLv3 protocols but allow a handshake
- // with older clients so they get a graceful denial.
+ /* Disable horribly insecure SSLv2 and SSLv3 protocols but allow a handshake
+ with older clients so they get a graceful denial. */
if (ssl_protocol == SSLTLS) {
SSL_CTX_set_options(context, SSL_OP_NO_SSLv2);
- SSL_CTX_set_options(context, SSL_OP_NO_SSLv3); // THRIFT-3164
+ SSL_CTX_set_options(context, SSL_OP_NO_SSLv3); /* THRIFT-3164 */
}
return context;
}
-void thrift_ssl_socket_get_error(GError **error, const guchar *error_msg, guint thrift_error_no)
-{
- unsigned long error_code;
- while ((error_code = ERR_get_error()) != 0) {
- const char* reason = ERR_reason_error_string(error_code);
- if (reason == NULL) {
- g_set_error (error, THRIFT_TRANSPORT_ERROR,
- thrift_error_no,
- "SSL error %lX: %s", error_code, error_msg);
- }else{
- g_set_error (error, THRIFT_TRANSPORT_ERROR,
- thrift_error_no,
- "SSL error %lX %s: %s", error_code,reason, error_msg);
- }
- }
-}
-
diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.h b/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.h
index 659c88dd9..0ca465a0f 100644
--- a/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.h
+++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.h
@@ -53,6 +53,7 @@ G_BEGIN_DECLS
typedef enum
{
THRIFT_SSL_SOCKET_ERROR_TRANSPORT=7,
+ THRIFT_SSL_SOCKET_ERROR_CONNECT_BIND,
THRIFT_SSL_SOCKET_ERROR_CIPHER_NOT_AVAILABLE,
THRIFT_SSL_SOCKET_ERROR_SSL,
THRIFT_SSL_SOCKET_ERROR_SSL_CERT_VALIDATION_FAILED
@@ -117,21 +118,6 @@ GType thrift_ssl_socket_get_type (void);
/* Public API */
/**
- * @brief Returns a error message for a defined error code.
- *
- * It uses gobject error functionality to get the error code of the last error
- * produced by this API.
- *
- * @param error Pointer to the error message.
- * @param error_msg Adds this message to the error that will be added to the
- * code.
- * @param thrift_error_no number of the error triggered.
- *
- * @see https://developer.gnome.org/glib/stable/glib-Error-Reporting.html#g-set-error
- */
-void thrift_ssl_socket_get_error(GError **error, const guchar *error_msg, guint thrift_error_no);
-
-/**
* @brief Set a pinning manager instead of the default one.
*
* The pinning manager will be used during the SSL handshake to check certificate
diff --git a/lib/c_glib/test/CMakeLists.txt b/lib/c_glib/test/CMakeLists.txt
index 2c87dbcc9..fb3e41cec 100644
--- a/lib/c_glib/test/CMakeLists.txt
+++ b/lib/c_glib/test/CMakeLists.txt
@@ -111,6 +111,8 @@ include_directories("${PROJECT_SOURCE_DIR}/test/c_glib/src" "${CMAKE_CURRENT_BIN
add_executable(testthrifttest testthrifttest.c
${PROJECT_SOURCE_DIR}/test/c_glib/src/thrift_test_handler.c
${PROJECT_SOURCE_DIR}/test/c_glib/src/thrift_test_handler.h
+ ${PROJECT_SOURCE_DIR}/test/c_glib/src/thrift_second_service_handler.c
+ ${PROJECT_SOURCE_DIR}/test/c_glib/src/thrift_second_service_handler.h
gen-c_glib/t_test_thrift_test_types.h)
target_link_libraries(testthrifttest testgenc)
add_test(NAME testthrifttest COMMAND testthrifttest)
diff --git a/lib/c_glib/test/testbufferedtransport.c b/lib/c_glib/test/testbufferedtransport.c
index 1c15ef2ef..c6e6b581d 100755
--- a/lib/c_glib/test/testbufferedtransport.c
+++ b/lib/c_glib/test/testbufferedtransport.c
@@ -31,6 +31,7 @@
#include "../src/thrift/c_glib/transport/thrift_buffered_transport.c"
static void thrift_server (const int port);
+static void thrift_socket_server_open (const int port, int times);
/* test object creation and destruction */
static void
@@ -44,8 +45,8 @@ test_create_and_destroy(void)
object = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT, NULL);
g_assert (object != NULL);
g_object_get (G_OBJECT (object), "transport", &transport,
- "r_buf_size", &r_buf_size,
- "w_buf_size", &w_buf_size, NULL);
+ "r_buf_size", &r_buf_size,
+ "w_buf_size", &w_buf_size, NULL);
g_object_unref (object);
}
@@ -55,35 +56,52 @@ test_open_and_close(void)
ThriftSocket *tsocket = NULL;
ThriftTransport *transport = NULL;
GError *err = NULL;
+ pid_t pid;
+ int port = 51199;
+ int status;
- /* create a ThriftSocket */
- tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
- "port", 51188, NULL);
-
- /* create a BufferedTransport wrapper of the Socket */
- transport = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT,
- "transport", THRIFT_TRANSPORT (tsocket), NULL);
-
- /* this shouldn't work */
- g_assert (thrift_buffered_transport_open (transport, NULL) == FALSE);
- g_assert (thrift_buffered_transport_is_open (transport) == TRUE);
- g_assert (thrift_buffered_transport_close (transport, NULL) == TRUE);
- g_object_unref (transport);
- g_object_unref (tsocket);
-
- /* try and underlying socket failure */
- tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost.broken",
- NULL);
-
- /* create a BufferedTransport wrapper of the Socket */
- transport = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT,
- "transport", THRIFT_TRANSPORT (tsocket), NULL);
+ pid = fork ();
+ g_assert ( pid >= 0 );
- g_assert (thrift_buffered_transport_open (transport, &err) == FALSE);
- g_object_unref (transport);
- g_object_unref (tsocket);
- g_error_free (err);
- err = NULL;
+ if ( pid == 0 )
+ {
+ /* child listens */
+ thrift_socket_server_open (port,1);
+ exit (0);
+ } else {
+ /* parent connects, wait a bit for the socket to be created */
+ sleep (1);
+ /* create a ThriftSocket */
+ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
+ "port", port, NULL);
+
+ /* create a BufferedTransport wrapper of the Socket */
+ transport = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT,
+ "transport", THRIFT_TRANSPORT (tsocket), NULL);
+
+ /* this shouldn't work */
+ g_assert (thrift_buffered_transport_open (transport, NULL) == TRUE);
+ g_assert (thrift_buffered_transport_is_open (transport) == TRUE);
+ g_assert (thrift_buffered_transport_close (transport, NULL) == TRUE);
+ g_object_unref (transport);
+ g_object_unref (tsocket);
+
+ /* try and underlying socket failure */
+ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost.broken",
+ NULL);
+
+ /* create a BufferedTransport wrapper of the Socket */
+ transport = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT,
+ "transport", THRIFT_TRANSPORT (tsocket), NULL);
+
+ g_assert (thrift_buffered_transport_open (transport, &err) == FALSE);
+ g_object_unref (transport);
+ g_object_unref (tsocket);
+ g_error_free (err);
+ err = NULL;
+ g_assert ( wait (&status) == pid );
+ g_assert ( status == 0 );
+ }
}
static void
@@ -100,57 +118,81 @@ test_read_and_write(void)
g_assert ( pid >= 0 );
if ( pid == 0 )
- {
- /* child listens */
- thrift_server (port);
- exit (0);
- } else {
- /* parent connects, wait a bit for the socket to be created */
- sleep (1);
-
- tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
- "port", port, NULL);
- transport = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT,
- "transport", THRIFT_TRANSPORT (tsocket),
- "w_buf_size", 4, NULL);
-
- g_assert (thrift_buffered_transport_open (transport, NULL) == TRUE);
- g_assert (thrift_buffered_transport_is_open (transport));
-
- /* write 10 bytes */
- thrift_buffered_transport_write (transport, buf, 10, NULL);
-
- /* write 1 byte at a time */
- thrift_buffered_transport_write (transport, buf, 1, NULL);
- thrift_buffered_transport_write (transport, buf, 1, NULL);
- thrift_buffered_transport_write (transport, buf, 1, NULL);
-
- /* overflow the buffer */
- thrift_buffered_transport_write (transport, buf, 2, NULL);
- thrift_buffered_transport_write (transport, buf, 1, NULL);
- thrift_buffered_transport_flush (transport, NULL);
-
- /* write 1 byte and flush */
- thrift_buffered_transport_write (transport, buf, 1, NULL);
- thrift_buffered_transport_flush (transport, NULL);
-
- /* write and overflow buffer with 2 system calls */
- thrift_buffered_transport_write (transport, buf, 1, NULL);
- thrift_buffered_transport_write (transport, buf, 3, NULL);
-
- /* write 10 bytes */
- thrift_buffered_transport_write (transport, buf, 10, NULL);
-
- thrift_buffered_transport_write_end (transport, NULL);
- thrift_buffered_transport_flush (transport, NULL);
- thrift_buffered_transport_close (transport, NULL);
-
- g_object_unref (transport);
- g_object_unref (tsocket);
-
- g_assert ( wait (&status) == pid );
- g_assert ( status == 0 );
+ {
+ /* child listens */
+ thrift_server (port);
+ exit (0);
+ } else {
+ /* parent connects, wait a bit for the socket to be created */
+ sleep (1);
+
+ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
+ "port", port, NULL);
+ transport = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT,
+ "transport", THRIFT_TRANSPORT (tsocket),
+ "w_buf_size", 4, NULL);
+
+ g_assert (thrift_buffered_transport_open (transport, NULL) == TRUE);
+ g_assert (thrift_buffered_transport_is_open (transport));
+
+ /* write 10 bytes */
+ thrift_buffered_transport_write (transport, buf, 10, NULL);
+
+ /* write 1 byte at a time */
+ thrift_buffered_transport_write (transport, buf, 1, NULL);
+ thrift_buffered_transport_write (transport, buf, 1, NULL);
+ thrift_buffered_transport_write (transport, buf, 1, NULL);
+
+ /* overflow the buffer */
+ thrift_buffered_transport_write (transport, buf, 2, NULL);
+ thrift_buffered_transport_write (transport, buf, 1, NULL);
+ thrift_buffered_transport_flush (transport, NULL);
+
+ /* write 1 byte and flush */
+ thrift_buffered_transport_write (transport, buf, 1, NULL);
+ thrift_buffered_transport_flush (transport, NULL);
+
+ /* write and overflow buffer with 2 system calls */
+ thrift_buffered_transport_write (transport, buf, 1, NULL);
+ thrift_buffered_transport_write (transport, buf, 3, NULL);
+
+ /* write 10 bytes */
+ thrift_buffered_transport_write (transport, buf, 10, NULL);
+
+ thrift_buffered_transport_write_end (transport, NULL);
+ thrift_buffered_transport_flush (transport, NULL);
+ thrift_buffered_transport_close (transport, NULL);
+
+ g_object_unref (transport);
+ g_object_unref (tsocket);
+
+ g_assert ( wait (&status) == pid );
+ g_assert ( status == 0 );
+ }
+}
+
+
+static void
+thrift_socket_server_open (const int port, int times)
+{
+ int bytes = 0;
+ ThriftServerTransport *transport = NULL;
+ ThriftTransport *client = NULL;
+ guchar buf[10]; /* a buffer */
+ guchar match[10] = TEST_DATA;
+ int i;
+ ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
+ "port", port, NULL);
+
+ transport = THRIFT_SERVER_TRANSPORT (tsocket);
+ thrift_server_transport_listen (transport, NULL);
+ for(i=0;i<times;i++){
+ client = thrift_server_transport_accept (transport, NULL);
+ g_assert (client != NULL);
+ thrift_socket_close (client, NULL);
+ g_object_unref (client);
}
+ g_object_unref (tsocket);
}
static void
@@ -163,15 +205,15 @@ thrift_server (const int port)
guchar match[10] = TEST_DATA;
ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
- "port", port, NULL);
+ "port", port, NULL);
transport = THRIFT_SERVER_TRANSPORT (tsocket);
thrift_server_transport_listen (transport, NULL);
/* wrap the client in a BufferedTransport */
client = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT, "transport",
- thrift_server_transport_accept (transport, NULL),
- "r_buf_size", 5, NULL);
+ thrift_server_transport_accept (transport, NULL),
+ "r_buf_size", 5, NULL);
g_assert (client != NULL);
/* read 10 bytes */
@@ -209,62 +251,62 @@ test_write_fail(void)
g_assert ( pid >= 0 );
if ( pid == 0 )
- {
- /* child listens */
- ThriftServerTransport *transport = NULL;
- ThriftTransport *client = NULL;
-
- ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
- "port", port, NULL);
-
- transport = THRIFT_SERVER_TRANSPORT (tsocket);
- thrift_server_transport_listen (transport, NULL);
-
- /* wrap the client in a BufferedTransport */
- client = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT, "transport",
- thrift_server_transport_accept (transport, NULL),
- "r_buf_size", 5, NULL);
- g_assert (client != NULL);
-
- /* just close socket */
- thrift_buffered_transport_close (client, NULL);
- g_object_unref (client);
- g_object_unref (tsocket);
- exit (0);
- } else {
- /* parent connects, wait a bit for the socket to be created */
- sleep (1);
-
- tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
- "port", port, NULL);
- transport = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT,
- "transport", THRIFT_TRANSPORT (tsocket),
- "w_buf_size", 4, NULL);
-
-
- g_assert (thrift_buffered_transport_open (transport, NULL) == TRUE);
- g_assert (thrift_buffered_transport_is_open (transport));
-
- /* recognize disconnection */
- sleep(1);
- g_assert (thrift_buffered_transport_write (transport, buf, 10, NULL) == TRUE);
- g_assert (thrift_buffered_transport_write (transport, buf, 10, NULL) == FALSE);
-
- /* write and overflow buffer */
- g_assert (thrift_buffered_transport_write (transport, buf, 10, NULL) == FALSE);
-
- /* write 1 and flush */
- g_assert (thrift_buffered_transport_write (transport, buf, 1, NULL) == TRUE);
- g_assert (thrift_buffered_transport_flush (transport, NULL) == FALSE);
-
- thrift_buffered_transport_close (transport, NULL);
-
- g_object_unref (transport);
- g_object_unref (tsocket);
-
- g_assert ( wait (&status) == pid );
- g_assert ( status == 0 );
- }
+ {
+ /* child listens */
+ ThriftServerTransport *transport = NULL;
+ ThriftTransport *client = NULL;
+
+ ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
+ "port", port, NULL);
+
+ transport = THRIFT_SERVER_TRANSPORT (tsocket);
+ thrift_server_transport_listen (transport, NULL);
+
+ /* wrap the client in a BufferedTransport */
+ client = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT, "transport",
+ thrift_server_transport_accept (transport, NULL),
+ "r_buf_size", 5, NULL);
+ g_assert (client != NULL);
+
+ /* just close socket */
+ thrift_buffered_transport_close (client, NULL);
+ g_object_unref (client);
+ g_object_unref (tsocket);
+ exit (0);
+ } else {
+ /* parent connects, wait a bit for the socket to be created */
+ sleep (1);
+
+ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
+ "port", port, NULL);
+ transport = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT,
+ "transport", THRIFT_TRANSPORT (tsocket),
+ "w_buf_size", 4, NULL);
+
+
+ g_assert (thrift_buffered_transport_open (transport, NULL) == TRUE);
+ g_assert (thrift_buffered_transport_is_open (transport));
+
+ /* recognize disconnection */
+ sleep(1);
+ g_assert (thrift_buffered_transport_write (transport, buf, 10, NULL) == TRUE);
+ g_assert (thrift_buffered_transport_write (transport, buf, 10, NULL) == FALSE);
+
+ /* write and overflow buffer */
+ g_assert (thrift_buffered_transport_write (transport, buf, 10, NULL) == FALSE);
+
+ /* write 1 and flush */
+ g_assert (thrift_buffered_transport_write (transport, buf, 1, NULL) == TRUE);
+ g_assert (thrift_buffered_transport_flush (transport, NULL) == FALSE);
+
+ thrift_buffered_transport_close (transport, NULL);
+
+ g_object_unref (transport);
+ g_object_unref (tsocket);
+
+ g_assert ( wait (&status) == pid );
+ g_assert ( status == 0 );
+ }
}
int
diff --git a/lib/c_glib/test/testframedtransport.c b/lib/c_glib/test/testframedtransport.c
index 032873789..45397cef4 100755
--- a/lib/c_glib/test/testframedtransport.c
+++ b/lib/c_glib/test/testframedtransport.c
@@ -30,6 +30,7 @@
#include "../src/thrift/c_glib/transport/thrift_framed_transport.c"
static void thrift_server (const int port);
+static void thrift_socket_server_open (const int port, int times);
/* test object creation and destruction */
static void
@@ -43,8 +44,8 @@ test_create_and_destroy(void)
object = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT, NULL);
g_assert (object != NULL);
g_object_get (G_OBJECT (object), "transport", &transport,
- "r_buf_size", &r_buf_size,
- "w_buf_size", &w_buf_size, NULL);
+ "r_buf_size", &r_buf_size,
+ "w_buf_size", &w_buf_size, NULL);
g_object_unref (object);
}
@@ -54,35 +55,53 @@ test_open_and_close(void)
ThriftSocket *tsocket = NULL;
ThriftTransport *transport = NULL;
GError *err = NULL;
+ pid_t pid;
+ int port = 51199;
+ int status;
- /* create a ThriftSocket */
- tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
- "port", 51188, NULL);
-
- /* create a BufferedTransport wrapper of the Socket */
- transport = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT,
- "transport", THRIFT_TRANSPORT (tsocket), NULL);
-
- /* this shouldn't work */
- g_assert (thrift_framed_transport_open (transport, NULL) == FALSE);
- g_assert (thrift_framed_transport_is_open (transport) == TRUE);
- g_assert (thrift_framed_transport_close (transport, NULL) == TRUE);
- g_object_unref (transport);
- g_object_unref (tsocket);
-
- /* try and underlying socket failure */
- tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost.broken",
- NULL);
-
- /* create a BufferedTransport wrapper of the Socket */
- transport = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT,
- "transport", THRIFT_TRANSPORT (tsocket), NULL);
+ pid = fork ();
+ g_assert ( pid >= 0 );
- g_assert (thrift_framed_transport_open (transport, &err) == FALSE);
- g_object_unref (transport);
- g_object_unref (tsocket);
- g_error_free (err);
- err = NULL;
+ if ( pid == 0 )
+ {
+ /* child listens */
+ thrift_socket_server_open (port,1);
+ exit (0);
+ } else {
+ /* parent connects, wait a bit for the socket to be created */
+ sleep (1);
+ /* create a ThriftSocket */
+ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
+ "port", port, NULL);
+
+ /* create a BufferedTransport wrapper of the Socket */
+ transport = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT,
+ "transport", THRIFT_TRANSPORT (tsocket), NULL);
+
+ /* this shouldn't work */
+ g_assert (thrift_framed_transport_open (transport, NULL) == TRUE);
+ g_assert (thrift_framed_transport_is_open (transport) == TRUE);
+ g_assert (thrift_framed_transport_close (transport, NULL) == TRUE);
+ g_object_unref (transport);
+ g_object_unref (tsocket);
+
+ /* try and underlying socket failure */
+ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost.broken",
+ NULL);
+
+ /* create a BufferedTransport wrapper of the Socket */
+ transport = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT,
+ "transport", THRIFT_TRANSPORT (tsocket), NULL);
+
+ g_assert (thrift_framed_transport_open (transport, &err) == FALSE);
+ g_object_unref (transport);
+ g_object_unref (tsocket);
+ g_error_free (err);
+ err = NULL;
+
+ g_assert ( wait (&status) == pid );
+ g_assert ( status == 0 );
+ }
}
static void
@@ -99,46 +118,46 @@ test_read_and_write(void)
g_assert ( pid >= 0 );
if ( pid == 0 )
- {
- /* child listens */
- thrift_server (port);
- exit (0);
- } else {
- /* parent connects, wait a bit for the socket to be created */
- sleep (1);
-
- tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
- "port", port, NULL);
- transport = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT,
- "transport", THRIFT_TRANSPORT (tsocket),
- "w_buf_size", 4, NULL);
-
- g_assert (thrift_framed_transport_open (transport, NULL) == TRUE);
- g_assert (thrift_framed_transport_is_open (transport));
-
- /* write 10 bytes */
- thrift_framed_transport_write (transport, buf, 10, NULL);
- thrift_framed_transport_flush (transport, NULL);
-
- thrift_framed_transport_write (transport, buf, 1, NULL);
- thrift_framed_transport_flush (transport, NULL);
-
- thrift_framed_transport_write (transport, buf, 10, NULL);
- thrift_framed_transport_flush (transport, NULL);
-
- thrift_framed_transport_write (transport, buf, 10, NULL);
- thrift_framed_transport_flush (transport, NULL);
-
- thrift_framed_transport_write_end (transport, NULL);
- thrift_framed_transport_flush (transport, NULL);
- thrift_framed_transport_close (transport, NULL);
-
- g_object_unref (transport);
- g_object_unref (tsocket);
-
- g_assert ( wait (&status) == pid );
- g_assert ( status == 0 );
- }
+ {
+ /* child listens */
+ thrift_server (port);
+ exit (0);
+ } else {
+ /* parent connects, wait a bit for the socket to be created */
+ sleep (1);
+
+ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
+ "port", port, NULL);
+ transport = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT,
+ "transport", THRIFT_TRANSPORT (tsocket),
+ "w_buf_size", 4, NULL);
+
+ g_assert (thrift_framed_transport_open (transport, NULL) == TRUE);
+ g_assert (thrift_framed_transport_is_open (transport));
+
+ /* write 10 bytes */
+ thrift_framed_transport_write (transport, buf, 10, NULL);
+ thrift_framed_transport_flush (transport, NULL);
+
+ thrift_framed_transport_write (transport, buf, 1, NULL);
+ thrift_framed_transport_flush (transport, NULL);
+
+ thrift_framed_transport_write (transport, buf, 10, NULL);
+ thrift_framed_transport_flush (transport, NULL);
+
+ thrift_framed_transport_write (transport, buf, 10, NULL);
+ thrift_framed_transport_flush (transport, NULL);
+
+ thrift_framed_transport_write_end (transport, NULL);
+ thrift_framed_transport_flush (transport, NULL);
+ thrift_framed_transport_close (transport, NULL);
+
+ g_object_unref (transport);
+ g_object_unref (tsocket);
+
+ g_assert ( wait (&status) == pid );
+ g_assert ( status == 0 );
+ }
}
/* test reading from the transport after the peer has unexpectedly
@@ -155,76 +174,100 @@ test_read_after_peer_close(void)
g_assert (pid >= 0);
if (pid == 0)
- {
- ThriftServerTransport *server_transport = NULL;
- ThriftTransport *client_transport = NULL;
-
- /* child listens */
- server_transport = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
- "port", port,
- NULL);
- g_assert (server_transport != NULL);
-
- thrift_server_transport_listen (server_transport, &err);
- g_assert (err == NULL);
-
- /* wrap the client transport in a ThriftFramedTransport */
- client_transport = g_object_new
- (THRIFT_TYPE_FRAMED_TRANSPORT,
- "transport", thrift_server_transport_accept (server_transport, &err),
- "r_buf_size", 0,
- NULL);
- g_assert (err == NULL);
- g_assert (client_transport != NULL);
-
- /* close the connection immediately after the client connects */
- thrift_transport_close (client_transport, NULL);
-
- g_object_unref (client_transport);
- g_object_unref (server_transport);
-
- exit (0);
- } else {
- ThriftSocket *tsocket = NULL;
- ThriftTransport *transport = NULL;
- guchar buf[10]; /* a buffer */
-
- /* parent connects, wait a bit for the socket to be created */
- sleep (1);
-
- tsocket = g_object_new (THRIFT_TYPE_SOCKET,
- "hostname", "localhost",
- "port", port,
- NULL);
- transport = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT,
- "transport", THRIFT_TRANSPORT (tsocket),
- "w_buf_size", 0,
- NULL);
-
- g_assert (thrift_transport_open (transport, NULL) == TRUE);
- g_assert (thrift_transport_is_open (transport));
-
- /* attempting to read from the transport after the peer has closed
+ {
+ ThriftServerTransport *server_transport = NULL;
+ ThriftTransport *client_transport = NULL;
+
+ /* child listens */
+ server_transport = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
+ "port", port,
+ NULL);
+ g_assert (server_transport != NULL);
+
+ thrift_server_transport_listen (server_transport, &err);
+ g_assert (err == NULL);
+
+ /* wrap the client transport in a ThriftFramedTransport */
+ client_transport = g_object_new
+ (THRIFT_TYPE_FRAMED_TRANSPORT,
+ "transport", thrift_server_transport_accept (server_transport, &err),
+ "r_buf_size", 0,
+ NULL);
+ g_assert (err == NULL);
+ g_assert (client_transport != NULL);
+
+ /* close the connection immediately after the client connects */
+ thrift_transport_close (client_transport, NULL);
+
+ g_object_unref (client_transport);
+ g_object_unref (server_transport);
+
+ exit (0);
+ } else {
+ ThriftSocket *tsocket = NULL;
+ ThriftTransport *transport = NULL;
+ guchar buf[10]; /* a buffer */
+
+ /* parent connects, wait a bit for the socket to be created */
+ sleep (1);
+
+ tsocket = g_object_new (THRIFT_TYPE_SOCKET,
+ "hostname", "localhost",
+ "port", port,
+ NULL);
+ transport = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT,
+ "transport", THRIFT_TRANSPORT (tsocket),
+ "w_buf_size", 0,
+ NULL);
+
+ g_assert (thrift_transport_open (transport, NULL) == TRUE);
+ g_assert (thrift_transport_is_open (transport));
+
+ /* attempting to read from the transport after the peer has closed
the connection fails gracefully without generating a critical
warning or segmentation fault */
- thrift_transport_read (transport, buf, 10, &err);
- g_assert (err != NULL);
+ thrift_transport_read (transport, buf, 10, &err);
+ g_assert (err != NULL);
+
+ g_error_free (err);
+ err = NULL;
- g_error_free (err);
- err = NULL;
+ thrift_transport_read_end (transport, &err);
+ g_assert (err == NULL);
- thrift_transport_read_end (transport, &err);
- g_assert (err == NULL);
+ thrift_transport_close (transport, &err);
+ g_assert (err == NULL);
- thrift_transport_close (transport, &err);
- g_assert (err == NULL);
+ g_object_unref (transport);
+ g_object_unref (tsocket);
+
+ g_assert (wait (&status) == pid);
+ g_assert (status == 0);
+ }
+}
+
+static void
+thrift_socket_server_open (const int port, int times)
+{
+ int bytes = 0;
+ ThriftServerTransport *transport = NULL;
+ ThriftTransport *client = NULL;
+ guchar buf[10]; /* a buffer */
+ guchar match[10] = TEST_DATA;
+ int i;
- g_object_unref (transport);
- g_object_unref (tsocket);
+ ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
+ "port", port, NULL);
- g_assert (wait (&status) == pid);
- g_assert (status == 0);
+ transport = THRIFT_SERVER_TRANSPORT (tsocket);
+ thrift_server_transport_listen (transport, NULL);
+ for(i=0;i<times;i++){
+ client = thrift_server_transport_accept (transport, NULL);
+ g_assert (client != NULL);
+ thrift_socket_close (client, NULL);
+ g_object_unref (client);
}
+ g_object_unref (tsocket);
}
static void
@@ -237,15 +280,15 @@ thrift_server (const int port)
guchar match[10] = TEST_DATA;
ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
- "port", port, NULL);
+ "port", port, NULL);
transport = THRIFT_SERVER_TRANSPORT (tsocket);
thrift_server_transport_listen (transport, NULL);
/* wrap the client in a BufferedTransport */
client = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT, "transport",
- thrift_server_transport_accept (transport, NULL),
- "r_buf_size", 5, NULL);
+ thrift_server_transport_accept (transport, NULL),
+ "r_buf_size", 5, NULL);
g_assert (client != NULL);
/* read 10 bytes */
diff --git a/lib/c_glib/test/testtransportsocket.c b/lib/c_glib/test/testtransportsocket.c
index 8e963754e..fedbad6b6 100755
--- a/lib/c_glib/test/testtransportsocket.c
+++ b/lib/c_glib/test/testtransportsocket.c
@@ -33,9 +33,9 @@ int
my_socket(int domain, int type, int protocol)
{
if (socket_error == 0)
- {
- return socket (domain, type, protocol);
- }
+ {
+ return socket (domain, type, protocol);
+ }
return -1;
}
@@ -44,9 +44,9 @@ ssize_t
my_recv(int socket, void *buffer, size_t length, int flags)
{
if (recv_error == 0)
- {
- return recv (socket, buffer, length, flags);
- }
+ {
+ return recv (socket, buffer, length, flags);
+ }
return -1;
}
@@ -55,9 +55,9 @@ ssize_t
my_send(int socket, const void *buffer, size_t length, int flags)
{
if (send_error == 0)
- {
- return send (socket, buffer, length, flags);
- }
+ {
+ return send (socket, buffer, length, flags);
+ }
return -1;
}
@@ -70,7 +70,7 @@ my_send(int socket, const void *buffer, size_t length, int flags)
#undef send
static void thrift_socket_server (const int port);
-
+static void thrift_socket_server_open (const int port, int times);
/* test object creation and destruction */
static void
test_create_and_destroy(void)
@@ -93,82 +93,100 @@ test_open_and_close(void)
ThriftSocket *tsocket = NULL;
ThriftTransport *transport = NULL;
GError *err = NULL;
+ int port = 51199;
+ pid_t pid;
+ int status;
- /* open a connection and close it */
- tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
- "port", 51188, NULL);
- transport = THRIFT_TRANSPORT (tsocket);
- thrift_socket_open (transport, NULL);
- g_assert (thrift_socket_is_open (transport) == TRUE);
- thrift_socket_close (transport, NULL);
- g_assert (thrift_socket_is_open (transport) == FALSE);
-
- /* test close failure */
- tsocket->sd = -1;
- thrift_socket_close (transport, NULL);
- g_object_unref (tsocket);
+ pid = fork ();
+ g_assert ( pid >= 0 );
- /* try a hostname lookup failure */
- tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost.broken",
- NULL);
- transport = THRIFT_TRANSPORT (tsocket);
- g_assert (thrift_socket_open (transport, &err) == FALSE);
- g_object_unref (tsocket);
- g_error_free (err);
- err = NULL;
-
- /* try an error call to socket() */
- tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", NULL);
- transport = THRIFT_TRANSPORT (tsocket);
- socket_error = 1;
- g_assert (thrift_socket_open (transport, &err) == FALSE);
- socket_error = 0;
- g_object_unref (tsocket);
- g_error_free (err);
+ if ( pid == 0 )
+ {
+ /* child listens */
+ thrift_socket_server_open (port, 1);
+ exit (0);
+ } else {
+ /* parent connects, wait a bit for the socket to be created */
+ sleep (1);
+
+ /* open a connection and close it */
+ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
+ "port", port, NULL);
+ transport = THRIFT_TRANSPORT (tsocket);
+ thrift_socket_open (transport, NULL);
+ g_assert (thrift_socket_is_open (transport) == TRUE);
+ thrift_socket_close (transport, NULL);
+ g_assert (thrift_socket_is_open (transport) == FALSE);
+
+ /* test close failure */
+ tsocket->sd = -1;
+ thrift_socket_close (transport, NULL);
+ g_object_unref (tsocket);
+
+ /* try a hostname lookup failure */
+ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost.broken",
+ NULL);
+ transport = THRIFT_TRANSPORT (tsocket);
+ g_assert (thrift_socket_open (transport, &err) == FALSE);
+ g_object_unref (tsocket);
+ g_error_free (err);
+ err = NULL;
+
+ /* try an error call to socket() */
+ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", NULL);
+ transport = THRIFT_TRANSPORT (tsocket);
+ socket_error = 1;
+ g_assert (thrift_socket_open (transport, &err) == FALSE);
+ socket_error = 0;
+ g_object_unref (tsocket);
+ g_error_free (err);
+ g_assert ( wait (&status) == pid );
+ g_assert ( status == 0 );
+ }
}
static void
test_read_and_write(void)
{
- int status;
- pid_t pid;
ThriftSocket *tsocket = NULL;
ThriftTransport *transport = NULL;
+ pid_t pid;
int port = 51199;
+ int status;
guchar buf[10] = TEST_DATA; /* a buffer */
pid = fork ();
g_assert ( pid >= 0 );
if ( pid == 0 )
- {
- /* child listens */
- thrift_socket_server (port);
- exit (0);
- } else {
- /* parent connects, wait a bit for the socket to be created */
- sleep (1);
-
- tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
- "port", port, NULL);
- transport = THRIFT_TRANSPORT (tsocket);
- g_assert (thrift_socket_open (transport, NULL) == TRUE);
- g_assert (thrift_socket_is_open (transport));
- thrift_socket_write (transport, buf, 10, NULL);
-
- /* write fail */
- send_error = 1;
- thrift_socket_write (transport, buf, 1, NULL);
- send_error = 0;
-
- thrift_socket_write_end (transport, NULL);
- thrift_socket_flush (transport, NULL);
- thrift_socket_close (transport, NULL);
- g_object_unref (tsocket);
-
- g_assert ( wait (&status) == pid );
- g_assert ( status == 0 );
- }
+ {
+ /* child listens */
+ thrift_socket_server (port);
+ exit (0);
+ } else {
+ /* parent connects, wait a bit for the socket to be created */
+ sleep (1);
+
+ tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
+ "port", port, NULL);
+ transport = THRIFT_TRANSPORT (tsocket);
+ g_assert (thrift_socket_open (transport, NULL) == TRUE);
+ g_assert (thrift_socket_is_open (transport));
+ thrift_socket_write (transport, buf, 10, NULL);
+
+ /* write fail */
+ send_error = 1;
+ thrift_socket_write (transport, buf, 1, NULL);
+ send_error = 0;
+
+ thrift_socket_write_end (transport, NULL);
+ thrift_socket_flush (transport, NULL);
+ thrift_socket_close (transport, NULL);
+ g_object_unref (tsocket);
+
+ g_assert ( wait (&status) == pid );
+ g_assert ( status == 0 );
+ }
}
/* test ThriftSocket's peek() implementation */
@@ -183,9 +201,9 @@ test_peek(void)
GError *error = NULL;
client_transport = g_object_new (THRIFT_TYPE_SOCKET,
- "hostname", "localhost",
- "port", port,
- NULL);
+ "hostname", "localhost",
+ "port", port,
+ NULL);
/* thrift_transport_peek returns FALSE when the socket is closed */
g_assert (thrift_transport_is_open (client_transport) == FALSE);
@@ -196,81 +214,105 @@ test_peek(void)
g_assert (pid >= 0);
if (pid == 0)
- {
- ThriftServerTransport *server_transport = NULL;
-
- g_object_unref (client_transport);
-
- /* child listens */
- server_transport = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
- "port", port,
- NULL);
- g_assert (server_transport != NULL);
-
- thrift_server_transport_listen (server_transport, &error);
- g_assert (error == NULL);
-
- client_transport = g_object_new
- (THRIFT_TYPE_BUFFERED_TRANSPORT,
- "transport", thrift_server_transport_accept (server_transport, &error),
- "r_buf_size", 0,
- "w_buf_size", sizeof data,
- NULL);
- g_assert (error == NULL);
- g_assert (client_transport != NULL);
-
- /* write exactly one character to the client */
- g_assert (thrift_transport_write (client_transport,
- &data,
- sizeof data,
- &error) == TRUE);
-
- thrift_transport_flush (client_transport, &error);
- thrift_transport_write_end (client_transport, &error);
- thrift_transport_close (client_transport, &error);
-
- g_object_unref (client_transport);
- g_object_unref (server_transport);
-
- exit (0);
- }
+ {
+ ThriftServerTransport *server_transport = NULL;
+
+ g_object_unref (client_transport);
+
+ /* child listens */
+ server_transport = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
+ "port", port,
+ NULL);
+ g_assert (server_transport != NULL);
+
+ thrift_server_transport_listen (server_transport, &error);
+ g_assert (error == NULL);
+
+ client_transport = g_object_new
+ (THRIFT_TYPE_BUFFERED_TRANSPORT,
+ "transport", thrift_server_transport_accept (server_transport, &error),
+ "r_buf_size", 0,
+ "w_buf_size", sizeof data,
+ NULL);
+ g_assert (error == NULL);
+ g_assert (client_transport != NULL);
+
+ /* write exactly one character to the client */
+ g_assert (thrift_transport_write (client_transport,
+ &data,
+ sizeof data,
+ &error) == TRUE);
+
+ thrift_transport_flush (client_transport, &error);
+ thrift_transport_write_end (client_transport, &error);
+ thrift_transport_close (client_transport, &error);
+
+ g_object_unref (client_transport);
+ g_object_unref (server_transport);
+
+ exit (0);
+ }
else {
- /* parent connects, wait a bit for the socket to be created */
- sleep (1);
+ /* parent connects, wait a bit for the socket to be created */
+ sleep (1);
- /* connect to the child */
- thrift_transport_open (client_transport, &error);
- g_assert (error == NULL);
- g_assert (thrift_transport_is_open (client_transport) == TRUE);
+ /* connect to the child */
+ thrift_transport_open (client_transport, &error);
+ g_assert (error == NULL);
+ g_assert (thrift_transport_is_open (client_transport) == TRUE);
- /* thrift_transport_peek returns TRUE when the socket is open and there is
+ /* thrift_transport_peek returns TRUE when the socket is open and there is
data available to be read */
- g_assert (thrift_transport_peek (client_transport, &error) == TRUE);
- g_assert (error == NULL);
+ g_assert (thrift_transport_peek (client_transport, &error) == TRUE);
+ g_assert (error == NULL);
- /* read exactly one character from the server */
- g_assert_cmpint (thrift_transport_read (client_transport,
- &data,
- sizeof data,
- &error), ==, sizeof data);
+ /* read exactly one character from the server */
+ g_assert_cmpint (thrift_transport_read (client_transport,
+ &data,
+ sizeof data,
+ &error), ==, sizeof data);
- /* thrift_transport_peek returns FALSE when the socket is open but there is
+ /* thrift_transport_peek returns FALSE when the socket is open but there is
no (more) data available to be read */
- g_assert (thrift_transport_is_open (client_transport) == TRUE);
- g_assert (thrift_transport_peek (client_transport, &error) == FALSE);
- g_assert (error == NULL);
+ g_assert (thrift_transport_is_open (client_transport) == TRUE);
+ g_assert (thrift_transport_peek (client_transport, &error) == FALSE);
+ g_assert (error == NULL);
- thrift_transport_read_end (client_transport, &error);
- thrift_transport_close (client_transport, &error);
+ thrift_transport_read_end (client_transport, &error);
+ thrift_transport_close (client_transport, &error);
- g_object_unref (client_transport);
+ g_object_unref (client_transport);
- g_assert (wait (&status) == pid);
- g_assert (status == 0);
+ g_assert (wait (&status) == pid);
+ g_assert (status == 0);
}
}
static void
+thrift_socket_server_open (const int port, int times)
+{
+ int bytes = 0;
+ ThriftServerTransport *transport = NULL;
+ ThriftTransport *client = NULL;
+ guchar buf[10]; /* a buffer */
+ guchar match[10] = TEST_DATA;
+ int i;
+ ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
+ "port", port, NULL);
+
+ transport = THRIFT_SERVER_TRANSPORT (tsocket);
+ thrift_server_transport_listen (transport, NULL);
+ for(i=0;i<times;i++){
+ client = thrift_server_transport_accept (transport, NULL);
+ g_assert (client != NULL);
+ thrift_socket_close (client, NULL);
+ g_object_unref (client);
+ }
+ g_object_unref (tsocket);
+}
+
+
+static void
thrift_socket_server (const int port)
{
int bytes = 0;
@@ -280,7 +322,7 @@ thrift_socket_server (const int port)
guchar match[10] = TEST_DATA;
ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
- "port", port, NULL);
+ "port", port, NULL);
transport = THRIFT_SERVER_TRANSPORT (tsocket);
thrift_server_transport_listen (transport, NULL);
diff --git a/lib/c_glib/test/testtransportsslsocket.c b/lib/c_glib/test/testtransportsslsocket.c
index f2f56f835..3c2644d8d 100644
--- a/lib/c_glib/test/testtransportsslsocket.c
+++ b/lib/c_glib/test/testtransportsslsocket.c
@@ -16,13 +16,14 @@
* specific language governing permissions and limitations
* under the License.
*/
+#define _POSIX_C_SOURCE 200112L /* https://stackoverflow.com/questions/37541985/storage-size-of-addrinfo-isnt-known */
+
-#include <netdb.h>
#include <sys/wait.h>
+#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
-#include <arpa/inet.h>
#include <thrift/c_glib/transport/thrift_transport.h>
#include <thrift/c_glib/transport/thrift_buffered_transport.h>
@@ -30,7 +31,7 @@
#include <thrift/c_glib/transport/thrift_server_socket.h>
#include <thrift/c_glib/transport/thrift_ssl_socket.h>
-//#define TEST_DATA { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' }
+/* #define TEST_DATA { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' } */
#define TEST_DATA { "GET / HTTP/1.1\n\n" }
@@ -40,9 +41,9 @@ int
my_socket(int domain, int type, int protocol)
{
if (socket_error == 0)
- {
- return socket (domain, type, protocol);
- }
+ {
+ return socket (domain, type, protocol);
+ }
return -1;
}
@@ -51,9 +52,9 @@ ssize_t
my_recv(int socket, void *buffer, size_t length, int flags)
{
if (recv_error == 0)
- {
- return recv (socket, buffer, length, flags);
- }
+ {
+ return recv (socket, buffer, length, flags);
+ }
return -1;
}
@@ -62,9 +63,9 @@ ssize_t
my_send(int socket, const void *buffer, size_t length, int flags)
{
if (send_error == 0)
- {
- return send (socket, buffer, length, flags);
- }
+ {
+ return send (socket, buffer, length, flags);
+ }
return -1;
}
@@ -76,7 +77,7 @@ my_send(int socket, const void *buffer, size_t length, int flags)
#undef recv
#undef send
-static void thrift_ssl_socket_server (const int port);
+static void thrift_socket_server (const int port);
/* test object creation and destruction */
static void
@@ -111,18 +112,90 @@ test_ssl_create_and_set_properties(void)
}
static void
-test_ssl_open_and_close(void)
+test_ssl_open_and_close_non_ssl_server(void)
{
ThriftSSLSocket *tSSLSocket = NULL;
ThriftTransport *transport = NULL;
GError *error=NULL;
+ pid_t pid;
+ int non_ssl_port = 51198;
+ char errormsg[255];
+
+
+ pid = fork ();
+ g_assert ( pid >= 0 );
+
+ if ( pid == 0 )
+ {
+ /* child listens */
+ /* This is a non SSL server */
+ thrift_socket_server (non_ssl_port);
+ exit (0);
+ } else {
+ /* parent connects, wait a bit for the socket to be created */
+ sleep (1);
+
+ /* open a connection and close it */
+ tSSLSocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost", non_ssl_port, &error);
+
+ transport = THRIFT_TRANSPORT (tSSLSocket);
+ g_assert (thrift_ssl_socket_open (transport, &error) == FALSE);
+ g_assert_cmpstr(error->message, == ,"Error while connect/bind: 68 -> Connection reset by peer");
+ g_clear_error (&error);
+ g_assert (thrift_ssl_socket_is_open (transport) == FALSE);
+ thrift_ssl_socket_close (transport, NULL);
+ g_assert (thrift_ssl_socket_is_open (transport) == FALSE);
+
+ /* test close failure */
+ THRIFT_SOCKET(tSSLSocket)->sd = -1;
+ thrift_ssl_socket_close (transport, NULL);
+ g_object_unref (tSSLSocket);
+
+ /* try a hostname lookup failure */
+ tSSLSocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost.broken", non_ssl_port, &error);
+ transport = THRIFT_TRANSPORT (tSSLSocket);
+ g_assert (thrift_ssl_socket_open (transport, &error) == FALSE);
+ snprintf(errormsg, 255, "host lookup failed for localhost.broken:%d - Unknown host", non_ssl_port);
+ g_assert_cmpstr(error->message, ==, errormsg);
+ g_clear_error (&error);
+ g_object_unref (tSSLSocket);
+ error = NULL;
+
+ /* try an error call to socket() */
+ /*
+ tSSLSocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost", port, &error);
+ transport = THRIFT_TRANSPORT (tSSLSocket);
+ socket_error = 1;
+ assert (thrift_ssl_socket_open (transport, &error) == FALSE);
+ socket_error = 0;
+ g_object_unref (tSSLSocket);
+ g_error_free (error);
+ */
+ }
+}
+
+static void
+test_ssl_write_invalid_socket(void)
+{
+ ThriftSSLSocket *tSSLSocket = NULL;
+ ThriftTransport *transport = NULL;
+ GError *error=NULL;
+ char buffer[] = "this must not break";
/* open a connection and close it */
- tSSLSocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost", 51188, &error);
+ tSSLSocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost", 51188+1, &error);
transport = THRIFT_TRANSPORT (tSSLSocket);
- thrift_ssl_socket_open (transport, NULL);
- g_assert (thrift_ssl_socket_is_open (transport) == TRUE);
+ g_assert (thrift_ssl_socket_open (transport, NULL) == FALSE);
+ g_assert (thrift_ssl_socket_is_open (transport) == FALSE);
+
+ /* FIXME This must be tested but since the assertion inside thrift_ssl_socket_write breaks the test unit
+ it's disabled. They idea is to disable trap/coredump during this test
+ g_assert (thrift_ssl_socket_write(transport, buffer, sizeof(buffer), &error) == FALSE);
+ g_message ("write_failed_with_error: %s",
+ error != NULL ? error->message : "No");
+ g_clear_error (&error);
+ */
thrift_ssl_socket_close (transport, NULL);
g_assert (thrift_ssl_socket_is_open (transport) == FALSE);
@@ -130,23 +203,6 @@ test_ssl_open_and_close(void)
THRIFT_SOCKET(tSSLSocket)->sd = -1;
thrift_ssl_socket_close (transport, NULL);
g_object_unref (tSSLSocket);
-
- /* try a hostname lookup failure */
- tSSLSocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost.broken", 51188, &error);
- transport = THRIFT_TRANSPORT (tSSLSocket);
- g_assert (thrift_ssl_socket_open (transport, &error) == FALSE);
- g_object_unref (tSSLSocket);
- g_error_free (error);
- error = NULL;
-
- /* try an error call to socket() */
- tSSLSocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost", 51188, &error);
- transport = THRIFT_TRANSPORT (tSSLSocket);
- socket_error = 1;
- g_assert (thrift_ssl_socket_open (transport, &error) == FALSE);
- socket_error = 0;
- g_object_unref (tSSLSocket);
- g_error_free (error);
}
@@ -160,22 +216,22 @@ unsigned char * get_cn_name(X509_NAME* const name)
unsigned char *utf8 = NULL;
do
- {
- if(!name) break; /* failed */
+ {
+ if(!name) break; /* failed */
- idx = X509_NAME_get_index_by_NID(name, NID_commonName, -1);
- if(!(idx > -1)) break; /* failed */
+ idx = X509_NAME_get_index_by_NID(name, NID_commonName, -1);
+ if(!(idx > -1)) break; /* failed */
- X509_NAME_ENTRY* entry = X509_NAME_get_entry(name, idx);
- if(!entry) break; /* failed */
+ X509_NAME_ENTRY* entry = X509_NAME_get_entry(name, idx);
+ if(!entry) break; /* failed */
- ASN1_STRING* data = X509_NAME_ENTRY_get_data(entry);
- if(!data) break; /* failed */
+ ASN1_STRING* data = X509_NAME_ENTRY_get_data(entry);
+ if(!data) break; /* failed */
- int length = ASN1_STRING_to_UTF8(&utf8, data);
- if(!utf8 || !(length > 0)) break; /* failed */
+ int length = ASN1_STRING_to_UTF8(&utf8, data);
+ if(!utf8 || !(length > 0)) break; /* failed */
- } while (0);
+ } while (0);
return utf8;
}
@@ -197,34 +253,34 @@ int verify_ip(char * hostname, struct sockaddr_storage *addr)
int retval = 0;
- memset(&hints, 0, sizeof hints);
- hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6
+ memset(&hints, 0, sizeof (struct addrinfo));
+ hints.ai_family = AF_UNSPEC; /* use AF_INET6 to force IPv6 */
hints.ai_socktype = SOCK_STREAM;
if ( (res = getaddrinfo(hostname, NULL, &hints, &addr_info) ) != 0)
- {
- // get the host info
- g_error("Cannot get the host address");
- return retval;
- }
- // loop through all the results and connect to the first we can
- char dnshost[INET6_ADDRSTRLEN]; // bigger addr supported IPV6
+ {
+ /* get the host info */
+ g_error("Cannot get the host address");
+ return retval;
+ }
+ /* loop through all the results and connect to the first we can */
+ char dnshost[INET6_ADDRSTRLEN]; /* bigger addr supported IPV6 */
char socket_ip[INET6_ADDRSTRLEN];
if(inet_ntop(addr->ss_family, get_in_addr(addr), socket_ip, INET6_ADDRSTRLEN)==socket_ip){
- g_debug("We are connected to host %s checking against certificate...", socket_ip);
- int sizeip = socket_ip!=NULL ? strlen(socket_ip) : 0;
- for(p = addr_info; p != NULL; p = p->ai_next) {
- if(inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), dnshost, INET6_ADDRSTRLEN)==dnshost){
- if(dnshost!=NULL){
- g_info("DNS address [%i -> %s]", p->ai_addr, dnshost);
- if(!strncmp(dnshost, socket_ip, sizeip)){
- retval=1;
- break; // if we get here, we must have connected successfully
- }
- }
+ g_debug("We are connected to host %s checking against certificate...", socket_ip);
+ int sizeip = socket_ip!=NULL ? strlen(socket_ip) : 0;
+ for(p = addr_info; p != NULL; p = p->ai_next) {
+ if(inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), dnshost, INET6_ADDRSTRLEN)==dnshost){
+ if(dnshost!=NULL){
+ g_info("DNS address [%i -> %s]", p->ai_addr, dnshost);
+ if(!strncmp(dnshost, socket_ip, sizeip)){
+ retval=1;
+ break; /* if we get here, we must have connected successfully */
+ }
+ }
+ }
}
- }
}
if(addr_info)
@@ -236,25 +292,25 @@ int verify_ip(char * hostname, struct sockaddr_storage *addr)
static void
read_from_file(char *buffer, long size, const char *file_name)
{
- char ch;
- long index=0;
- FILE *fp;
+ char ch;
+ long index=0;
+ FILE *fp;
- fp = fopen(file_name,"r"); // read mode
+ fp = fopen(file_name,"r"); /* read mode */
- if( fp == NULL )
- {
- perror("Error while opening the file.\n");
- exit(EXIT_FAILURE);
- }
+ if( fp == NULL )
+ {
+ perror("Error while opening the file.\n");
+ exit(EXIT_FAILURE);
+ }
- printf("The contents of %s file are :\n", file_name);
+ printf("The contents of %s file are :\n", file_name);
- while(index<size && ( ch = fgetc(fp) ) != EOF ){
- buffer[index++] = ch;
- }
+ while(index<size && ( ch = fgetc(fp) ) != EOF ){
+ buffer[index++] = ch;
+ }
- fclose(fp);
+ fclose(fp);
}
#define ISSUER_CN_PINNING "The Apache Software Foundation"
@@ -269,25 +325,27 @@ gboolean verify_certificate_sn(X509 *cert, const unsigned char *serial_number)
BIGNUM *bn = ASN1_INTEGER_to_BN(serial, NULL);
if (!bn) {
- fprintf(stderr, "unable to convert ASN1INTEGER to BN\n");
- return EXIT_FAILURE;
+ fprintf(stderr, "unable to convert ASN1INTEGER to BN\n");
+ return EXIT_FAILURE;
}
char *tmp = BN_bn2dec(bn);
if (!tmp) {
- g_warning(stderr, "unable to convert BN to decimal string.\n");
- BN_free(bn);
- return EXIT_FAILURE;
+ g_warning(stderr, "unable to convert BN to decimal string.\n");
+ BN_free(bn);
+ return EXIT_FAILURE;
}
-// if (strlen(tmp) >= len) {
-// g_warn(stderr, "buffer length shorter than serial number\n");
-// BN_free(bn);
-// OPENSSL_free(tmp);
-// return EXIT_FAILURE;
-// }
+ /*
+ if (strlen(tmp) >= len) {
+ g_warn(stderr, "buffer length shorter than serial number\n");
+ BN_free(bn);
+ OPENSSL_free(tmp);
+ return EXIT_FAILURE;
+ }
+ */
if(!strncmp(serial_number, tmp, strlen(serial_number))){
- retval=TRUE;
+ retval=TRUE;
}else{
- g_warning("Serial number is not valid");
+ g_warning("Serial number is not valid");
}
BN_free(bn);
@@ -306,52 +364,52 @@ gboolean my_access_manager(ThriftTransport * transport, X509 *cert, struct socka
/* Issuer is the authority we trust that warrants nothing useful */
const unsigned char * issuer = get_cn_name(iname);
if(issuer){
- gboolean valid = TRUE;
- g_info("Issuer (cn) %s", issuer);
+ gboolean valid = TRUE;
+ g_info("Issuer (cn) %s", issuer);
- // Issuer pinning
- if(strncmp(ISSUER_CN_PINNING, issuer, strlen(ISSUER_CN_PINNING))){
- g_warning("The Issuer of the certificate is not valid");
- valid=FALSE;
- }
- OPENSSL_free(issuer);
- if(!valid)
- return valid;
+ /* Issuer pinning */
+ if(strncmp(ISSUER_CN_PINNING, issuer, strlen(ISSUER_CN_PINNING))){
+ g_warning("The Issuer of the certificate is not valid");
+ valid=FALSE;
+ }
+ OPENSSL_free(issuer);
+ if(!valid)
+ return valid;
}
/* Subject is who the certificate is issued to by the authority */
const unsigned char * subject = get_cn_name(sname);
if(subject){
- g_info("Subject (cn) %s", subject);
- gboolean valid = TRUE;
+ g_info("Subject (cn) %s", subject);
+ gboolean valid = TRUE;
- // Subject pinning
- if(strncmp(SUBJECT_CN_PINNING, subject, strlen(SUBJECT_CN_PINNING))){
- g_warning("The subject of the certificate is not valid");
- valid=FALSE;
- }
+ /* Subject pinning */
+ if(strncmp(SUBJECT_CN_PINNING, subject, strlen(SUBJECT_CN_PINNING))){
+ g_warning("The subject of the certificate is not valid");
+ valid=FALSE;
+ }
- if(!valid)
- return valid;
+ if(!valid)
+ return valid;
- // Host pinning
- if(verify_ip(subject, addr)){
- g_info("Verified subject");
- }else{
- g_info("Cannot verify subject");
- valid=FALSE;
- }
- OPENSSL_free(subject);
+ /* Host pinning */
+ if(verify_ip(subject, addr)){
+ g_info("Verified subject");
+ }else{
+ g_info("Cannot verify subject");
+ valid=FALSE;
+ }
+ OPENSSL_free(subject);
- if(!valid)
- return valid;
+ if(!valid)
+ return valid;
}
if(!verify_certificate_sn(cert, CERT_SERIAL_NUMBER)){
- return FALSE;
+ return FALSE;
}else{
- g_info("Verified serial number");
+ g_info("Verified serial number");
}
return TRUE;
@@ -369,32 +427,33 @@ test_ssl_authorization_manager(void)
pid_t pid;
ThriftSSLSocket *tSSLsocket = NULL;
ThriftTransport *transport = NULL;
- // int port = 51199;
+ /* int port = 51199; */
int port = 443;
GError *error=NULL;
guchar buf[17] = TEST_DATA; /* a buffer */
- // pid = fork ();
- // g_assert ( pid >= 0 );
- //
- // if ( pid == 0 )
- // {
- // /* child listens */
- // thrift_ssl_socket_server (port);
- // exit (0);
- // } else {
+/*
+ pid = fork ();
+ g_assert ( pid >= 0 );
+
+ if ( pid == 0 )
+ {
+ thrift_ssl_socket_server (port);
+ exit (0);
+ } else {
+ */
/* parent connects, wait a bit for the socket to be created */
sleep (1);
- // Test against level2 owncloud certificate
+ /* Test against level2 owncloud certificate */
tSSLsocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost", port, &error);
- thrift_ssl_socket_set_manager(tSSLsocket, my_access_manager); // Install pinning manager
- //thrift_ssl_load_cert_from_file(tSSLsocket, "./owncloud.level2crm.pem");
+ thrift_ssl_socket_set_manager(tSSLsocket, my_access_manager); /* Install pinning manager */
+ /* thrift_ssl_load_cert_from_file(tSSLsocket, "./owncloud.level2crm.pem"); */
unsigned char cert_buffer[65534];
read_from_file(cert_buffer, 65534, "../../keys/client.pem");
if(!thrift_ssl_load_cert_from_buffer(tSSLsocket, cert_buffer)){
- g_warning("Certificates cannot be loaded!");
+ g_warning("Certificates cannot be loaded!");
}
transport = THRIFT_TRANSPORT (tSSLsocket);
@@ -405,122 +464,24 @@ test_ssl_authorization_manager(void)
/* write fail */
send_error = 1;
- // thrift_ssl_socket_write (transport, buf, 1, NULL);
- // send_error = 0;
-
- // thrift_ssl_socket_write_end (transport, NULL);
- // thrift_ssl_socket_flush (transport, NULL);
+ /*
+ thrift_ssl_socket_write (transport, buf, 1, NULL);
+ send_error = 0;
+ thrift_ssl_socket_write_end (transport, NULL);
+ thrift_ssl_socket_flush (transport, NULL);
+ */
thrift_ssl_socket_close (transport, NULL);
g_object_unref (tSSLsocket);
- // g_assert ( wait (&status) == pid );
+ /* g_assert ( wait (&status) == pid ); */
g_assert ( status == 0 );
- // }
+ /* } */
}
#endif
-/* test ThriftSocket's peek() implementation */
-//static void
-//test_ssl_peek(void)
-//{
-// gint status;
-// pid_t pid;
-// guint port = 51199;
-// gchar data = 'A';
-// ThriftTransport *client_transport;
-// GError *error = NULL;
-//
-// client_transport = g_object_new (THRIFT_TYPE_SSL_SOCKET,
-// "hostname", "localhost",
-// "port", port,
-// NULL);
-//
-// /* thrift_transport_peek returns FALSE when the socket is closed */
-// g_assert (thrift_transport_is_open (client_transport) == FALSE);
-// g_assert (thrift_transport_peek (client_transport, &error) == FALSE);
-// g_assert (error == NULL);
-//
-// pid = fork ();
-// g_assert (pid >= 0);
-//
-// if (pid == 0)
-// {
-// ThriftServerTransport *server_transport = NULL;
-//
-// g_object_unref (client_transport);
-//
-// /* child listens */
-// server_transport = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
-// "port", port,
-// NULL);
-// g_assert (server_transport != NULL);
-//
-// thrift_server_transport_listen (server_transport, &error);
-// g_assert (error == NULL);
-//
-// client_transport = g_object_new
-// (THRIFT_TYPE_BUFFERED_TRANSPORT,
-// "transport", thrift_server_transport_accept (server_transport, &error),
-// "r_buf_size", 0,
-// "w_buf_size", sizeof data,
-// NULL);
-// g_assert (error == NULL);
-// g_assert (client_transport != NULL);
-//
-// /* write exactly one character to the client */
-// g_assert (thrift_transport_write (client_transport,
-// &data,
-// sizeof data,
-// &error) == TRUE);
-//
-// thrift_transport_flush (client_transport, &error);
-// thrift_transport_write_end (client_transport, &error);
-// thrift_transport_close (client_transport, &error);
-//
-// g_object_unref (client_transport);
-// g_object_unref (server_transport);
-//
-// exit (0);
-// }
-// else {
-// /* parent connects, wait a bit for the socket to be created */
-// sleep (1);
-//
-// /* connect to the child */
-// thrift_transport_open (client_transport, &error);
-// g_assert (error == NULL);
-// g_assert (thrift_transport_is_open (client_transport) == TRUE);
-//
-// /* thrift_transport_peek returns TRUE when the socket is open and there is
-// data available to be read */
-// g_assert (thrift_transport_peek (client_transport, &error) == TRUE);
-// g_assert (error == NULL);
-//
-// /* read exactly one character from the server */
-// g_assert_cmpint (thrift_transport_read (client_transport,
-// &data,
-// sizeof data,
-// &error), ==, sizeof data);
-//
-// /* thrift_transport_peek returns FALSE when the socket is open but there is
-// no (more) data available to be read */
-// g_assert (thrift_transport_is_open (client_transport) == TRUE);
-// g_assert (thrift_transport_peek (client_transport, &error) == FALSE);
-// g_assert (error == NULL);
-//
-// thrift_transport_read_end (client_transport, &error);
-// thrift_transport_close (client_transport, &error);
-//
-// g_object_unref (client_transport);
-//
-// g_assert (wait (&status) == pid);
-// g_assert (status == 0);
-// }
-//}
-
static void
-thrift_ssl_socket_server (const int port)
+thrift_socket_server (const int port)
{
int bytes = 0;
ThriftServerTransport *transport = NULL;
@@ -529,7 +490,7 @@ thrift_ssl_socket_server (const int port)
guchar match[10] = TEST_DATA;
ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
- "port", port, NULL);
+ "port", port, NULL);
transport = THRIFT_SERVER_TRANSPORT (tsocket);
thrift_server_transport_listen (transport, NULL);
@@ -566,10 +527,11 @@ main(int argc, char *argv[])
g_test_add_func ("/testtransportsslsocket/CreateAndDestroy", test_ssl_create_and_destroy);
g_test_add_func ("/testtransportsslsocket/CreateAndSetProperties", test_ssl_create_and_set_properties);
- g_test_add_func ("/testtransportsslsocket/OpenAndClose", test_ssl_open_and_close);
- // This test is disabled because server is not ready
- // g_test_add_func ("/testtransportsslsocket/AuthorizationManagerPinning", test_ssl_authorization_manager);
- // g_test_add_func ("/testtransportsslsocket/Peek", test_ssl_peek);
+ g_test_add_func ("/testtransportsslsocket/OpenAndCloseNonSSLServer", test_ssl_open_and_close_non_ssl_server);
+ g_test_add_func ("/testtransportsslsocket/OpenAndWriteInvalidSocket", test_ssl_write_invalid_socket);
+
+
+
retval = g_test_run ();