/** Close connection to the server.
 *
 * @param cb 3E calendar backend.
 */
void e_cal_backend_3e_close_connection(ECalBackend3e *cb)
{
    g_return_if_fail(cb != NULL);

    if (cb->priv->is_open)
    {
        xr_client_close(cb->priv->conn);
        cb->priv->is_open = FALSE;

        g_static_rec_mutex_unlock(&cb->priv->conn_mutex);
    }
}
Example #2
0
void xr_client_free(xr_client_conn* conn)
{
  xr_trace(XR_DEBUG_CLIENT_TRACE, "(conn=%p)", conn);

  if (conn == NULL)
    return;

  xr_client_close(conn);
  g_free(conn->host);
  g_free(conn->resource);
  g_free(conn->session_id);
  g_hash_table_destroy(conn->headers);
  g_free(conn);
}
/** Open connection to the 3E server and authenticate user.
 *
 * This function will do nothing and return TRUE if connection is already
 * opened.
 *
 * @param cb 3E calendar backend.
 * @param err Error pointer.
 *
 * @return TRUE if connection was already open, FALSE on error.
 */
gboolean e_cal_backend_3e_open_connection(ECalBackend3e *cb, GError * *err)
{
    GError *local_err = NULL;

    g_return_val_if_fail(cb != NULL, FALSE);
    g_return_val_if_fail(err == NULL || *err == NULL, FALSE);

    cb->priv->last_conn_failed = FALSE;

    /* if user tried to open connection in offline mode, close current connection
       if any and return error. this shouldn't happen, but let's check it anyway */
    if (!e_cal_backend_3e_calendar_is_online(cb))
    {
        g_set_error(err, 0, -1, "Can't open 3e server connection in offline mode.");
        e_cal_backend_3e_close_connection(cb);
        return FALSE;
    }

    g_static_rec_mutex_lock(&cb->priv->conn_mutex);

    /* resolve server URI from DNS TXT if necessary */
    if (cb->priv->server_uri == NULL)
    {
        char *server_hostname = get_eee_server_hostname(cb->priv->username);
        if (server_hostname == NULL)
        {
            g_set_error(err, 0, -1, "Can't resolve server URI for username '%s'", cb->priv->username);
            goto err;
        }
        cb->priv->server_uri = g_strdup_printf("https://%s/RPC2", server_hostname);
        g_free(server_hostname);
    }

    /* check that we have all info that is necessary to create conn */
    if (cb->priv->username == NULL || cb->priv->password == NULL || cb->priv->server_uri == NULL)
    {
        g_set_error(err, 0, -1, "Connection was not setup correctly, can't open.");
        goto err;
    }

    /* create conn object */
    if (cb->priv->conn == NULL)
    {
        cb->priv->conn = xr_client_new(err);
        if (cb->priv->conn == NULL)
        {
            goto err;
        }
        cb->priv->is_open = FALSE;
    }

    if (cb->priv->is_open)
    {
        /* was already locked in this thread */
        g_static_rec_mutex_unlock(&cb->priv->conn_mutex);
        return TRUE;
    }

    if (!xr_client_open(cb->priv->conn, cb->priv->server_uri, err))
    {
        goto err;
    }

    ESClient_authenticate(cb->priv->conn, cb->priv->username, cb->priv->password, &local_err);
    if (local_err)
    {
        g_propagate_error(err, local_err);
        xr_client_close(cb->priv->conn);
        goto err;
    }

    cb->priv->is_open = TRUE;

    return TRUE;

err:
    cb->priv->last_conn_failed = TRUE;
    g_static_rec_mutex_unlock(&cb->priv->conn_mutex);
    return FALSE;
}
Example #4
0
gboolean xr_client_call(xr_client_conn* conn, xr_call* call, GError** err)
{
  char* buffer;
  int length;
  gboolean rs;
  gboolean write_success;
  GString* response;

  xr_trace(XR_DEBUG_CLIENT_TRACE, "(conn=%p, call=%p)", conn, call);

  g_return_val_if_fail(conn != NULL, FALSE);
  g_return_val_if_fail(call != NULL, FALSE);
  g_return_val_if_fail(err == NULL || *err == NULL, FALSE);

  if (!conn->is_open)
  {
    g_set_error(err, XR_CLIENT_ERROR, XR_CLIENT_ERROR_CLOSED, "Can't perform RPC on closed connection.");
    return FALSE;
  }

  /* serialize nad send XML-RPC request */
  xr_call_set_transport(call, conn->transport);
  xr_call_serialize_request(call, &buffer, &length);
  xr_http_setup_request(conn->http, "POST", conn->resource, conn->host);
  g_hash_table_foreach(conn->headers, (GHFunc)_add_http_header, conn->http);
  if (conn->transport == XR_CALL_XML_RPC)
    xr_http_set_header(conn->http, "Content-Type", "text/xml");
#ifdef XR_JSON_ENABLED
  else if (conn->transport == XR_CALL_JSON_RPC)
    xr_http_set_header(conn->http, "Content-Type", "text/json");
#endif
  xr_http_set_message_length(conn->http, length);
  write_success = xr_http_write_all(conn->http, buffer, length, err);
  xr_call_free_buffer(call, buffer);
  if (!write_success)
  {
    xr_client_close(conn);
    return FALSE;
  }

  /* receive HTTP response header */
  if (!xr_http_read_header(conn->http, err))
    return FALSE;

  /* check if some dumb bunny sent us wrong message type */
  if (xr_http_get_message_type(conn->http) != XR_HTTP_RESPONSE)
    return FALSE;

  response = xr_http_read_all(conn->http, err);
  if (response == NULL)
  {
    xr_client_close(conn);
    return FALSE;
  }

  rs = xr_call_unserialize_response(call, response->str, response->len);
  g_string_free(response, TRUE);
  if (!rs)
  {
    g_set_error(err, 0, xr_call_get_error_code(call), "%s", xr_call_get_error_message(call));

    if (xr_debug_enabled & XR_DEBUG_CALL)
      xr_call_dump(call, 0);

    return FALSE;
  }

  if (xr_debug_enabled & XR_DEBUG_CALL)
    xr_call_dump(call, 0);

  return TRUE;
}