static void socket_connect_result (SoupSocket *sock, guint status, gpointer user_data) { SoupConnectionAsyncConnectData *data = user_data; SoupConnectionPrivate *priv = SOUP_CONNECTION_GET_PRIVATE (data->conn); if (!SOUP_STATUS_IS_SUCCESSFUL (status)) goto done; if (priv->ssl_creds && !priv->tunnel_addr) { if (!soup_socket_start_ssl (sock, NULL)) { status = SOUP_STATUS_SSL_FAILED; goto done; } } g_signal_connect (priv->socket, "disconnected", G_CALLBACK (socket_disconnected), data->conn); soup_connection_set_state (data->conn, SOUP_CONNECTION_IDLE); priv->unused_timeout = time (NULL) + SOUP_CONNECTION_UNUSED_TIMEOUT; start_idle_timer (data->conn); done: if (data->callback) { if (priv->proxy_uri != NULL) status = soup_status_proxify (status); data->callback (data->conn, status, data->callback_data); } g_slice_free (SoupConnectionAsyncConnectData, data); }
/** * soup_connection_connect_sync: * @conn: the connection * * Synchronously connects @conn. * * Return value: the soup status **/ guint soup_connection_connect_sync (SoupConnection *conn) { SoupConnectionPrivate *priv; guint status; g_return_val_if_fail (SOUP_IS_CONNECTION (conn), SOUP_STATUS_MALFORMED); priv = SOUP_CONNECTION_GET_PRIVATE (conn); g_return_val_if_fail (priv->socket == NULL, SOUP_STATUS_MALFORMED); soup_connection_set_state (conn, SOUP_CONNECTION_CONNECTING); priv->socket = soup_socket_new (SOUP_SOCKET_REMOTE_ADDRESS, priv->remote_addr, SOUP_SOCKET_SSL_CREDENTIALS, priv->ssl_creds, SOUP_SOCKET_FLAG_NONBLOCKING, FALSE, SOUP_SOCKET_TIMEOUT, priv->io_timeout, NULL); status = soup_socket_connect_sync (priv->socket, NULL); if (!SOUP_STATUS_IS_SUCCESSFUL (status)) goto fail; g_signal_connect (priv->socket, "disconnected", G_CALLBACK (socket_disconnected), conn); if (priv->ssl_creds && !priv->tunnel_addr) { if (!soup_socket_start_ssl (priv->socket, NULL)) { status = SOUP_STATUS_SSL_FAILED; goto fail; } } if (SOUP_STATUS_IS_SUCCESSFUL (status)) { soup_connection_set_state (conn, SOUP_CONNECTION_IDLE); priv->unused_timeout = time (NULL) + SOUP_CONNECTION_UNUSED_TIMEOUT; start_idle_timer (conn); } else { fail: if (priv->socket) { g_object_unref (priv->socket); priv->socket = NULL; } } if (priv->proxy_uri != NULL) status = soup_status_proxify (status); return status; }
int main (int argc, char **argv) { int opt, debug = 0, listener, sin_len, port, i; struct sockaddr_in sin; GThread *server; char writebuf[BUFSIZE], readbuf[BUFSIZE]; SoupAddress *addr; SoupSSLCredentials *creds; SoupSocket *sock; gsize n, total; SoupSocketIOStatus status; int connect_status; GError *error = NULL; g_thread_init (NULL); g_type_init (); /* On Windows, this will call WSAStartup() */ soup_socket_get_type (); while ((opt = getopt (argc, argv, "c:d:k:")) != -1) { switch (opt) { case 'c': ssl_cert_file = optarg; break; case 'd': debug = atoi (optarg); break; case 'k': ssl_key_file = optarg; break; case '?': fprintf (stderr, "Usage: %s [-d debuglevel] [-c ssl-cert-file] [-k ssl-key-file]\n", argv[0]); break; } } if (debug) { gnutls_global_set_log_function (debug_log); gnutls_global_set_log_level (debug); } /* Create server socket */ listener = socket (AF_INET, SOCK_STREAM, 0); if (listener == -1) { SOCKET_PRINT_ERROR ("creating listening socket"); exit (1); } memset (&sin, 0, sizeof (sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = ntohl (INADDR_LOOPBACK); if (bind (listener, (struct sockaddr *) &sin, sizeof (sin)) == -1) { SOCKET_PRINT_ERROR ("binding listening socket"); exit (1); } if (listen (listener, 1) == -1) { SOCKET_PRINT_ERROR ("listening on socket"); exit (1); } sin_len = sizeof (sin); getsockname (listener, (struct sockaddr *)&sin, (void *)&sin_len); port = ntohs (sin.sin_port); /* Create the client */ addr = soup_address_new ("127.0.0.1", port); creds = soup_ssl_get_client_credentials (NULL); sock = soup_socket_new (SOUP_SOCKET_REMOTE_ADDRESS, addr, SOUP_SOCKET_FLAG_NONBLOCKING, FALSE, SOUP_SOCKET_SSL_CREDENTIALS, creds, NULL); g_object_unref (addr); connect_status = soup_socket_connect_sync (sock, NULL); if (connect_status != SOUP_STATUS_OK) { g_error ("Could not create client socket: %s", soup_status_get_phrase (connect_status)); } soup_socket_start_ssl (sock, NULL); /* Now spawn server thread */ server = g_thread_create (server_thread, GINT_TO_POINTER (listener), TRUE, NULL); /* Synchronous client test */ for (i = 0; i < BUFSIZE; i++) writebuf[i] = i & 0xFF; total = 0; while (total < BUFSIZE) { status = soup_socket_write (sock, writebuf + total, BUFSIZE - total, &n, NULL, &error); if (status != SOUP_SOCKET_OK) g_error ("Sync write got status %d: %s", status, error ? error->message : "(unknown)"); total += n; } total = 0; while (total < BUFSIZE) { status = soup_socket_read (sock, readbuf + total, BUFSIZE - total, &n, NULL, &error); if (status != SOUP_SOCKET_OK) g_error ("Sync read got status %d: %s", status, error ? error->message : "(unknown)"); total += n; } if (memcmp (writebuf, readbuf, BUFSIZE) != 0) g_error ("Sync read didn't match write"); printf ("SYNCHRONOUS SSL TEST PASSED\n"); /* Switch socket to async and do it again */ g_object_set (sock, SOUP_SOCKET_FLAG_NONBLOCKING, TRUE, NULL); g_idle_add (start_writing, sock); loop = g_main_loop_new (NULL, TRUE); g_main_loop_run (loop); g_main_loop_unref (loop); g_main_context_unref (g_main_context_default ()); printf ("ASYNCHRONOUS SSL TEST PASSED\n"); g_object_unref (sock); soup_ssl_free_client_credentials (creds); g_thread_join (server); /* Success */ return 0; }