/* reads a frame and puts it into the buffer */
gboolean
thrift_framed_transport_read_frame (ThriftTransport *transport,
                                    GError **error)
{
  ThriftFramedTransport *t = THRIFT_FRAMED_TRANSPORT (transport);
  guint32 sz;
  gint32 bytes;
  gboolean result = FALSE;

  /* read the size */
  if (thrift_transport_read (t->transport,
                             &sz,
                             sizeof (sz),
                             error) == sizeof (sz))
  {
    guchar *tmpdata;

    sz = ntohl (sz);

    /* create a buffer to hold the data and read that much data */
    tmpdata = g_alloca (sz);
    bytes = thrift_transport_read (t->transport, tmpdata, sz, error);

    if (bytes > 0 && (error == NULL || *error == NULL))
    {
      /* add the data to the buffer */
      g_byte_array_append (t->r_buf, tmpdata, bytes);

      result = TRUE;
    }
  }

  return result;
}
Beispiel #2
0
gint32
my_thrift_transport_read (ThriftTransport *transport, gpointer buf,
                          guint32 len, GError **error)
{
  if (transport_read_count != transport_read_error_at
      && transport_read_error == 0)
  {
    transport_read_count++;
    return thrift_transport_read (transport, buf, len, error);
  }
  return -1;
}
int32_t
thrift_binary_protocol_read_u64 (ThriftProtocol *protocol, uint64_t *value,
                                 int *error)
{
  int32_t ret;
  void * b[8];

  if ((ret =
       thrift_transport_read (protocol->transport,
                              b, 8, error)) < 0)
  {
    return -1;
  }
  *value = os_get_value64((uint8_t *)b);
  return ret;
}
int32_t
thrift_binary_protocol_read_byte (ThriftProtocol *protocol, int8_t *value,
                                  int *error)
{
  int32_t ret;
  void * b[1];

  if ((ret =
       thrift_transport_read (protocol->transport,
                              b, 1, error)) < 0)
  {
    return -1;
  }
  *value = *(int8_t *) b;
  return ret;
}
gint32
thrift_binary_protocol_read_byte (ThriftProtocol *protocol, gint8 *value,
                                  GError **error)
{
  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
  gint32 ret;
  gpointer b[1];

  if ((ret =
       thrift_transport_read (protocol->transport,
                              b, 1, error)) < 0)
  {
    return -1;
  }
  *value = *(gint8 *) b;
  return ret;
}
gint32
thrift_binary_protocol_read_i64 (ThriftProtocol *protocol, gint64 *value,
                                 GError **error)
{
  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
  gint32 ret;
  gpointer b[8];

  if ((ret =
       thrift_transport_read (protocol->transport,
                              b, 8, error)) < 0)
  {
    return -1;
  }
  *value = *(gint64 *) b;
  *value = GUINT64_FROM_BE (*value);
  return ret;
}
gint32
thrift_binary_protocol_read_i32 (ThriftProtocol *protocol, gint32 *value,
                                 GError **error)
{
  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
  gint32 ret;
  gpointer b[4];

  if ((ret =
       thrift_transport_read (protocol->transport,
                              b, 4, error)) < 0)
  {
    return -1;
  }
  *value = *(gint32 *) b;
  *value = g_ntohl (*value);
  return ret;
}
gint32
thrift_binary_protocol_read_double (ThriftProtocol *protocol,
                                    gdouble *value, GError **error)
{
  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
  gint32 ret;
  gpointer b[8];

  if ((ret =
       thrift_transport_read (protocol->transport,
                              b, 8, error)) < 0)
  {
    return -1;
  }
  guint64 bits = *(guint64 *) b;
  bits = GUINT64_FROM_BE (bits);
  *value = thrift_bitwise_cast_gdouble (bits);
  return ret;
}
int32_t
thrift_binary_protocol_read_u32 (ThriftProtocol *protocol, u_int32_t *value,
                                 int *error)
{
  int32_t ret;
  union {
      void * b[4];
      u_int32_t all;
  } bytes;

  if ((ret =
       thrift_transport_read (protocol->transport,
                              bytes.b, 4, error)) < 0)
  {
    return -1;
  }
  *value = ntohl (bytes.all);
  return ret;
}
int32_t
thrift_binary_protocol_read_i16 (ThriftProtocol *protocol, int16_t *value,
                                 int *error)
{
  int32_t ret;
  union bytes {
    void * b[2];
    int16_t all;
  } bytes;

  if ((ret =
       thrift_transport_read (protocol->transport,
                              bytes.b, 2, error)) < 0)
  {
    return -1;
  }
  *value = ntohs (bytes.all);
  return ret;
}
gint32
thrift_binary_protocol_read_binary (ThriftProtocol *protocol,
                                    gpointer *buf, guint32 *len,
                                    GError **error)
{
  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
  gint32 ret;
  gint32 xfer = 0;
  gint32 read_len = 0;
 
  /* read the length into read_len */
  if ((ret =
       thrift_protocol_read_i32 (protocol, &read_len, error)) < 0)
  {
    return -1;
  }
  xfer += ret;

  if (read_len > 0)
  {
    /* allocate the memory as an array of unsigned char for binary data */
    *len = (guint32) read_len;
    *buf = g_new (guchar, *len);
    if ((ret =
         thrift_transport_read (protocol->transport,
                                *buf, *len, error)) < 0)
    {
      g_free (*buf);
      *buf = NULL;
      *len = 0;
      return -1;
    }
    xfer += ret;
  } else {
    *buf = NULL;
  }

  return xfer;
}
gint32
thrift_binary_protocol_read_string (ThriftProtocol *protocol,
                                    gchar **str, GError **error)
{
  g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1);
  guint32 len;
  gint32 ret;
  gint32 xfer = 0;
  gint32 read_len = 0;

  /* read the length into read_len */
  if ((ret =
       thrift_protocol_read_i32 (protocol, &read_len, error)) < 0)
  {
    return -1;
  }
  xfer += ret;

  if (read_len > 0)
  {
    /* allocate the memory for the string */
    len = (guint32) read_len + 1; // space for null terminator
    *str = g_new0 (gchar, len);
    if ((ret =
         thrift_transport_read (protocol->transport,
                                *str, read_len, error)) < 0)
    {
      g_free (*str);
      *str = NULL;
      len = 0;
      return -1;
    }
    xfer += ret;
  } else {
    *str = NULL;
  }

  return xfer;
}
int32_t
thrift_binary_protocol_read_binary (ThriftProtocol *protocol,
                                    void **buf, u_int32_t *len,
                                    int *error)
{
  int32_t ret;
  int32_t xfer = 0;
  int32_t read_len = 0;
 
  /* read the length into read_len */
  if ((ret =
       thrift_protocol_read_i32 (protocol, &read_len, error)) < 0)
  {
    return -1;
  }
  xfer += ret;

  if (read_len > 0)
  {
    /* allocate the memory as an array of unsigned char for binary data */
    *len = (u_int32_t) read_len;
    *buf = os_malloc (*len);
    memset (*buf, 0, *len);
    if ((ret =
         thrift_transport_read (protocol->transport,
                                *buf, *len, error)) < 0)
    {
      os_free (*buf);
      *buf = NULL;
      *len = 0;
      return -1;
    }
    xfer += ret;
  } else {
    *buf = NULL;
  }

  return xfer;
}
int32_t
thrift_binary_protocol_read_string (ThriftProtocol *protocol,
                                    char **str, int *error)
{
  u_int32_t len;
  int32_t ret;
  int32_t xfer = 0;
  int32_t read_len = 0;

  /* read the length into read_len */
  if ((ret =
       thrift_protocol_read_i32 (protocol, &read_len, error)) < 0)
  {
    return -1;
  }
  xfer += ret;

  if (read_len > 0)
  {
    /* allocate the memory for the string */
    len = (u_int32_t) read_len + 1; // space for null terminator
    *str = os_malloc (len);
    memset (*str, 0, len);
    if ((ret =
         thrift_transport_read (protocol->transport,
                                *str, read_len, error)) < 0)
    {
      os_free (*str);
      *str = NULL;
      len = 0;
      return -1;
    }
    xfer += ret;
  } else {
    *str = NULL;
  }

  return xfer;
}
int32_t
thrift_binary_protocol_read_double (ThriftProtocol *protocol,
                                    double *value, int *error)
{
#ifndef __KERNEL__
  int32_t ret;
  union {
    void * b[8];
    u_int64_t all;
  } bytes;

  if ((ret =
       thrift_transport_read (protocol->transport,
                              bytes.b, 8, error)) < 0)
  {
    return -1;
  }
  *value = thrift_bitwise_cast_double (bytes.all);
  return ret;
#else
  return -1;
#endif
}
Beispiel #16
0
/* test reading from the transport after the peer has unexpectedly
   closed the connection */
static void
test_read_after_peer_close(void)
{
  int status;
  pid_t pid;
  int port = 51199;
  GError *err = NULL;

  pid = fork ();
  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
       the connection fails gracefully without generating a critical
       warning or segmentation fault */
	thrift_transport_read (transport, buf, 10, &err);
	g_assert (err != NULL);

	g_error_free (err);
	err = NULL;

	thrift_transport_read_end (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);
    }
}