~cyphermox/ubuntu/utopic/libsoup2.4/autopkgtest

« back to all changes in this revision

Viewing changes to libsoup/soup-connection.c

  • Committer: Package Import Robot
  • Author(s): Sebastien Bacher
  • Date: 2014-05-12 12:28:40 UTC
  • mfrom: (10.3.28 utopic-proposed)
  • Revision ID: package-import@ubuntu.com-20140512122840-48y5krquj9i3ru79
Tags: 2.46.0-2ubuntu1
* Resynchronize on Debian, remaining change
  - Use dh-autoreconf to update libtool.m4 for new ports.

Show diffs side-by-side

added added

removed removed

Lines of Context:
442
442
                soup_connection_event (conn, event, connection);
443
443
}
444
444
 
445
 
typedef struct {
446
 
        SoupConnection *conn;
447
 
        SoupConnectionCallback callback;
448
 
        gpointer callback_data;
449
 
        GCancellable *cancellable;
450
 
        guint event_id;
451
 
} SoupConnectionAsyncConnectData;
452
 
 
453
445
static void
454
 
socket_connect_finished (SoupSocket *socket, guint status, gpointer user_data)
 
446
socket_connect_finished (GTask *task, SoupSocket *sock, GError *error)
455
447
{
456
 
        SoupConnectionAsyncConnectData *data = user_data;
457
 
        SoupConnectionPrivate *priv = SOUP_CONNECTION_GET_PRIVATE (data->conn);
458
 
 
459
 
        g_signal_handler_disconnect (socket, data->event_id);
460
 
 
461
 
        if (SOUP_STATUS_IS_SUCCESSFUL (status)) {
 
448
        SoupConnection *conn = g_task_get_source_object (task);
 
449
        SoupConnectionPrivate *priv = SOUP_CONNECTION_GET_PRIVATE (conn);
 
450
 
 
451
        if (priv->async_context && !priv->use_thread_context)
 
452
                g_main_context_pop_thread_default (priv->async_context);
 
453
 
 
454
        g_signal_handlers_disconnect_by_func (sock, G_CALLBACK (re_emit_socket_event), conn);
 
455
 
 
456
        if (!error) {
462
457
                if (priv->ssl && !priv->proxy_uri) {
463
 
                        soup_connection_event (data->conn,
 
458
                        soup_connection_event (conn,
464
459
                                               G_SOCKET_CLIENT_TLS_HANDSHAKED,
465
460
                                               NULL);
466
461
                }
467
462
                if (!priv->ssl || !priv->proxy_uri) {
468
 
                        soup_connection_event (data->conn,
 
463
                        soup_connection_event (conn,
469
464
                                               G_SOCKET_CLIENT_COMPLETE,
470
465
                                               NULL);
471
466
                }
472
467
 
473
 
                soup_connection_set_state (data->conn, SOUP_CONNECTION_IN_USE);
 
468
                soup_connection_set_state (conn, SOUP_CONNECTION_IN_USE);
474
469
                priv->unused_timeout = time (NULL) + SOUP_CONNECTION_UNUSED_TIMEOUT;
475
 
                start_idle_timer (data->conn);
476
 
        } else if (status == SOUP_STATUS_TLS_FAILED) {
477
 
                priv->ssl_fallback = TRUE;
478
 
                status = SOUP_STATUS_TRY_AGAIN;
479
 
        }
480
 
 
481
 
        if (data->callback) {
482
 
                if (priv->proxy_uri != NULL)
483
 
                        status = soup_status_proxify (status);
484
 
                data->callback (data->conn, status, data->callback_data);
485
 
        }
486
 
        g_object_unref (data->conn);
487
 
        if (data->cancellable)
488
 
                g_object_unref (data->cancellable);
489
 
        g_slice_free (SoupConnectionAsyncConnectData, data);
490
 
}
491
 
 
492
 
static void
493
 
socket_connect_result (SoupSocket *sock, guint status, gpointer user_data)
494
 
{
495
 
        SoupConnectionAsyncConnectData *data = user_data;
496
 
        SoupConnectionPrivate *priv = SOUP_CONNECTION_GET_PRIVATE (data->conn);
497
 
 
498
 
        if (!SOUP_STATUS_IS_SUCCESSFUL (status)) {
499
 
                socket_connect_finished (sock, status, data);
 
470
                start_idle_timer (conn);
 
471
 
 
472
                g_task_return_boolean (task, TRUE);
 
473
        } else
 
474
                g_task_return_error (task, error);
 
475
        g_object_unref (task);
 
476
}
 
477
 
 
478
static void
 
479
socket_handshake_complete (GObject *object, GAsyncResult *result, gpointer user_data)
 
480
{
 
481
        SoupSocket *sock = SOUP_SOCKET (object);
 
482
        GTask *task = user_data;
 
483
        GError *error = NULL;
 
484
 
 
485
        soup_socket_handshake_finish (sock, result, &error);
 
486
        socket_connect_finished (task, sock, error);
 
487
}
 
488
 
 
489
static void
 
490
socket_connect_complete (GObject *object, GAsyncResult *result, gpointer user_data)
 
491
{
 
492
        SoupSocket *sock = SOUP_SOCKET (object);
 
493
        GTask *task = user_data;
 
494
        SoupConnection *conn = g_task_get_source_object (task);
 
495
        SoupConnectionPrivate *priv = SOUP_CONNECTION_GET_PRIVATE (conn);
 
496
        GError *error = NULL;
 
497
 
 
498
        if (!soup_socket_connect_finish_internal (sock, result, &error)) {
 
499
                socket_connect_finished (task, sock, error);
500
500
                return;
501
501
        }
502
502
 
503
 
        priv->proxy_uri = soup_socket_get_http_proxy_uri (priv->socket);
 
503
        priv->proxy_uri = soup_socket_get_http_proxy_uri (sock);
504
504
 
505
505
        if (priv->ssl && !priv->proxy_uri) {
506
 
                if (soup_socket_start_ssl (sock, data->cancellable)) {
507
 
                        soup_connection_event (data->conn,
508
 
                                               G_SOCKET_CLIENT_TLS_HANDSHAKING,
509
 
                                               NULL);
510
 
                        soup_socket_handshake_async (sock, data->cancellable,
511
 
                                                     socket_connect_finished, data);
512
 
                        return;
513
 
                }
 
506
                soup_connection_event (conn,
 
507
                                       G_SOCKET_CLIENT_TLS_HANDSHAKING,
 
508
                                       NULL);
514
509
 
515
 
                status = SOUP_STATUS_SSL_FAILED;
 
510
                soup_socket_handshake_async (sock, priv->remote_uri->host,
 
511
                                             g_task_get_cancellable (task),
 
512
                                             socket_handshake_complete, task);
 
513
                return;
516
514
        }
517
515
 
518
 
        socket_connect_finished (sock, status, data);
 
516
        socket_connect_finished (task, sock, NULL);
519
517
}
520
518
 
521
519
void
522
 
soup_connection_connect_async (SoupConnection *conn,
523
 
                               GCancellable *cancellable,
524
 
                               SoupConnectionCallback callback,
525
 
                               gpointer user_data)
 
520
soup_connection_connect_async (SoupConnection      *conn,
 
521
                               GCancellable        *cancellable,
 
522
                               GAsyncReadyCallback  callback,
 
523
                               gpointer             user_data)
526
524
{
527
 
        SoupConnectionAsyncConnectData *data;
528
525
        SoupConnectionPrivate *priv;
529
526
        SoupAddress *remote_addr;
 
527
        GTask *task;
530
528
 
531
529
        g_return_if_fail (SOUP_IS_CONNECTION (conn));
532
530
        priv = SOUP_CONNECTION_GET_PRIVATE (conn);
534
532
 
535
533
        soup_connection_set_state (conn, SOUP_CONNECTION_CONNECTING);
536
534
 
537
 
        data = g_slice_new (SoupConnectionAsyncConnectData);
538
 
        data->conn = g_object_ref (conn);
539
 
        data->callback = callback;
540
 
        data->callback_data = user_data;
541
 
        data->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
 
535
        /* Set the protocol to ensure correct proxy resolution. */
 
536
        remote_addr =
 
537
                g_object_new (SOUP_TYPE_ADDRESS,
 
538
                              SOUP_ADDRESS_NAME, priv->remote_uri->host,
 
539
                              SOUP_ADDRESS_PORT, priv->remote_uri->port,
 
540
                              SOUP_ADDRESS_PROTOCOL, priv->remote_uri->scheme,
 
541
                              NULL);
542
542
 
543
 
        remote_addr = soup_address_new (priv->remote_uri->host,
544
 
                                        priv->remote_uri->port);
545
543
        priv->socket =
546
544
                soup_socket_new (SOUP_SOCKET_REMOTE_ADDRESS, remote_addr,
547
545
                                 SOUP_SOCKET_SSL_CREDENTIALS, priv->tlsdb,
556
554
                                 NULL);
557
555
        g_object_unref (remote_addr);
558
556
 
559
 
        data->event_id = g_signal_connect (priv->socket, "event",
560
 
                                           G_CALLBACK (re_emit_socket_event),
561
 
                                           data->conn);
562
 
 
563
 
        soup_socket_connect_async (priv->socket, data->cancellable,
564
 
                                   socket_connect_result, data);
565
 
}
566
 
 
567
 
guint
568
 
soup_connection_connect_sync (SoupConnection *conn, GCancellable *cancellable)
 
557
        g_signal_connect (priv->socket, "event",
 
558
                          G_CALLBACK (re_emit_socket_event), conn);
 
559
 
 
560
        if (priv->async_context && !priv->use_thread_context)
 
561
                g_main_context_push_thread_default (priv->async_context);
 
562
        task = g_task_new (conn, cancellable, callback, user_data);
 
563
 
 
564
        soup_socket_connect_async_internal (priv->socket, cancellable,
 
565
                                            socket_connect_complete, task);
 
566
}
 
567
 
 
568
gboolean
 
569
soup_connection_connect_finish (SoupConnection  *conn,
 
570
                                GAsyncResult    *result,
 
571
                                GError         **error)
 
572
{
 
573
        return g_task_propagate_boolean (G_TASK (result), error);
 
574
}
 
575
 
 
576
gboolean
 
577
soup_connection_connect_sync (SoupConnection  *conn,
 
578
                              GCancellable    *cancellable,
 
579
                              GError         **error)
569
580
{
570
581
        SoupConnectionPrivate *priv;
571
 
        guint status, event_id = 0;
 
582
        guint event_id = 0;
572
583
        SoupAddress *remote_addr;
 
584
        gboolean success = TRUE;
573
585
 
574
 
        g_return_val_if_fail (SOUP_IS_CONNECTION (conn), SOUP_STATUS_MALFORMED);
 
586
        g_return_val_if_fail (SOUP_IS_CONNECTION (conn), FALSE);
575
587
        priv = SOUP_CONNECTION_GET_PRIVATE (conn);
576
 
        g_return_val_if_fail (priv->socket == NULL, SOUP_STATUS_MALFORMED);
 
588
        g_return_val_if_fail (priv->socket == NULL, FALSE);
577
589
 
578
590
        soup_connection_set_state (conn, SOUP_CONNECTION_CONNECTING);
579
591
 
580
 
        remote_addr = soup_address_new (priv->remote_uri->host, priv->remote_uri->port);
 
592
        /* Set the protocol to ensure correct proxy resolution. */
 
593
        remote_addr =
 
594
                g_object_new (SOUP_TYPE_ADDRESS,
 
595
                              SOUP_ADDRESS_NAME, priv->remote_uri->host,
 
596
                              SOUP_ADDRESS_PORT, priv->remote_uri->port,
 
597
                              SOUP_ADDRESS_PROTOCOL, priv->remote_uri->scheme,
 
598
                              NULL);
 
599
 
581
600
        priv->socket =
582
601
                soup_socket_new (SOUP_SOCKET_REMOTE_ADDRESS, remote_addr,
583
602
                                 SOUP_SOCKET_PROXY_RESOLVER, priv->proxy_resolver,
593
612
 
594
613
        event_id = g_signal_connect (priv->socket, "event",
595
614
                                     G_CALLBACK (re_emit_socket_event), conn);
596
 
        status = soup_socket_connect_sync (priv->socket, cancellable);
597
 
 
598
 
        if (!SOUP_STATUS_IS_SUCCESSFUL (status))
599
 
                goto fail;
 
615
        if (!soup_socket_connect_sync_internal (priv->socket, cancellable, error)) {
 
616
                success = FALSE;
 
617
                goto done;
 
618
        }
600
619
 
601
620
        priv->proxy_uri = soup_socket_get_http_proxy_uri (priv->socket);
602
621
 
603
622
        if (priv->ssl && !priv->proxy_uri) {
604
 
                if (!soup_socket_start_ssl (priv->socket, cancellable))
605
 
                        status = SOUP_STATUS_SSL_FAILED;
606
 
                else {
607
 
                        soup_connection_event (conn,
608
 
                                               G_SOCKET_CLIENT_TLS_HANDSHAKING,
609
 
                                               NULL);
610
 
                        status = soup_socket_handshake_sync (priv->socket, cancellable);
611
 
                        if (status == SOUP_STATUS_OK) {
612
 
                                soup_connection_event (conn,
613
 
                                                       G_SOCKET_CLIENT_TLS_HANDSHAKED,
614
 
                                                       NULL);
615
 
                        } else if (status == SOUP_STATUS_TLS_FAILED) {
616
 
                                priv->ssl_fallback = TRUE;
617
 
                                status = SOUP_STATUS_TRY_AGAIN;
618
 
                        }
619
 
                }
620
 
        }
621
 
 
622
 
        if (SOUP_STATUS_IS_SUCCESSFUL (status)) {
623
 
                if (!priv->ssl || !priv->proxy_uri) {
624
 
                        soup_connection_event (conn,
625
 
                                               G_SOCKET_CLIENT_COMPLETE,
626
 
                                               NULL);
627
 
                }
628
 
                soup_connection_set_state (conn, SOUP_CONNECTION_IN_USE);
629
 
                priv->unused_timeout = time (NULL) + SOUP_CONNECTION_UNUSED_TIMEOUT;
630
 
                start_idle_timer (conn);
631
 
        }
632
 
 
633
 
 fail:
 
623
                soup_connection_event (conn,
 
624
                                       G_SOCKET_CLIENT_TLS_HANDSHAKING,
 
625
                                       NULL);
 
626
                if (!soup_socket_handshake_sync (priv->socket,
 
627
                                                 priv->remote_uri->host,
 
628
                                                 cancellable, error)) {
 
629
                        success = FALSE;
 
630
                        goto done;
 
631
                }
 
632
                soup_connection_event (conn,
 
633
                                       G_SOCKET_CLIENT_TLS_HANDSHAKED,
 
634
                                       NULL);
 
635
        }
 
636
 
 
637
        if (!priv->ssl || !priv->proxy_uri) {
 
638
                soup_connection_event (conn,
 
639
                                       G_SOCKET_CLIENT_COMPLETE,
 
640
                                       NULL);
 
641
        }
 
642
        soup_connection_set_state (conn, SOUP_CONNECTION_IN_USE);
 
643
        priv->unused_timeout = time (NULL) + SOUP_CONNECTION_UNUSED_TIMEOUT;
 
644
        start_idle_timer (conn);
 
645
 
 
646
 done:
634
647
        if (priv->socket && event_id)
635
648
                g_signal_handler_disconnect (priv->socket, event_id);
636
649
 
637
 
        if (priv->proxy_uri != NULL)
638
 
                status = soup_status_proxify (status);
639
 
        return status;
 
650
        return success;
640
651
}
641
652
 
642
653
gboolean
650
661
        return priv->ssl && priv->proxy_uri != NULL;
651
662
}
652
663
 
653
 
guint
654
 
soup_connection_start_ssl_sync (SoupConnection *conn,
655
 
                                GCancellable   *cancellable)
 
664
gboolean
 
665
soup_connection_start_ssl_sync (SoupConnection  *conn,
 
666
                                GCancellable    *cancellable,
 
667
                                GError         **error)
656
668
{
657
669
        SoupConnectionPrivate *priv;
658
 
        guint status;
659
670
 
660
671
        g_return_val_if_fail (SOUP_IS_CONNECTION (conn), FALSE);
661
672
        priv = SOUP_CONNECTION_GET_PRIVATE (conn);
662
673
 
663
 
        if (!soup_socket_start_proxy_ssl (priv->socket,
664
 
                                          priv->remote_uri->host,
665
 
                                          cancellable))
666
 
                return SOUP_STATUS_SSL_FAILED;
667
 
 
668
674
        soup_connection_event (conn, G_SOCKET_CLIENT_TLS_HANDSHAKING, NULL);
669
 
        status = soup_socket_handshake_sync (priv->socket, cancellable);
670
 
        if (status == SOUP_STATUS_OK) {
 
675
        if (soup_socket_handshake_sync (priv->socket, priv->remote_uri->host,
 
676
                                        cancellable, error)) {
671
677
                soup_connection_event (conn, G_SOCKET_CLIENT_TLS_HANDSHAKED, NULL);
672
678
                soup_connection_event (conn, G_SOCKET_CLIENT_COMPLETE, NULL);
673
 
        } else if (status == SOUP_STATUS_TLS_FAILED) {
674
 
                priv->ssl_fallback = TRUE;
675
 
                status = SOUP_STATUS_TRY_AGAIN;
676
 
        }
677
 
 
678
 
        return status;
 
679
                return TRUE;
 
680
        } else
 
681
                return FALSE;
679
682
}
680
683
 
681
684
static void
682
 
start_ssl_completed (SoupSocket *socket, guint status, gpointer user_data)
683
 
{
684
 
        SoupConnectionAsyncConnectData *data = user_data;
685
 
        SoupConnectionPrivate *priv = SOUP_CONNECTION_GET_PRIVATE (data->conn);
686
 
 
687
 
        if (status == SOUP_STATUS_OK) {
688
 
                soup_connection_event (data->conn, G_SOCKET_CLIENT_TLS_HANDSHAKED, NULL);
689
 
                soup_connection_event (data->conn, G_SOCKET_CLIENT_COMPLETE, NULL);
690
 
        } else if (status == SOUP_STATUS_TLS_FAILED) {
691
 
                priv->ssl_fallback = TRUE;
692
 
                status = SOUP_STATUS_TRY_AGAIN;
693
 
        }
694
 
 
695
 
        data->callback (data->conn, status, data->callback_data);
696
 
        g_object_unref (data->conn);
697
 
        g_slice_free (SoupConnectionAsyncConnectData, data);
698
 
}
699
 
 
700
 
static gboolean
701
 
idle_start_ssl_completed (gpointer user_data)
702
 
{
703
 
        SoupConnectionAsyncConnectData *data = user_data;
704
 
 
705
 
        start_ssl_completed (NULL, SOUP_STATUS_SSL_FAILED, data);
706
 
        return FALSE;
 
685
start_ssl_completed (GObject *object, GAsyncResult *result, gpointer user_data)
 
686
{
 
687
        GTask *task = user_data;
 
688
        SoupConnection *conn = g_task_get_source_object (task);
 
689
        SoupConnectionPrivate *priv = SOUP_CONNECTION_GET_PRIVATE (conn);
 
690
        GError *error = NULL;
 
691
 
 
692
        if (priv->async_context && !priv->use_thread_context)
 
693
                g_main_context_pop_thread_default (priv->async_context);
 
694
 
 
695
        if (soup_socket_handshake_finish (priv->socket, result, &error)) {
 
696
                soup_connection_event (conn, G_SOCKET_CLIENT_TLS_HANDSHAKED, NULL);
 
697
                soup_connection_event (conn, G_SOCKET_CLIENT_COMPLETE, NULL);
 
698
                g_task_return_boolean (task, TRUE);
 
699
        } else
 
700
                g_task_return_error (task, error);
 
701
        g_object_unref (task);
707
702
}
708
703
 
709
704
void
710
 
soup_connection_start_ssl_async (SoupConnection   *conn,
711
 
                                 GCancellable     *cancellable,
712
 
                                 SoupConnectionCallback callback,
713
 
                                 gpointer          user_data)
 
705
soup_connection_start_ssl_async (SoupConnection      *conn,
 
706
                                 GCancellable        *cancellable,
 
707
                                 GAsyncReadyCallback  callback,
 
708
                                 gpointer             user_data)
714
709
{
715
710
        SoupConnectionPrivate *priv;
716
 
        SoupConnectionAsyncConnectData *data;
717
 
        GMainContext *async_context;
 
711
        GTask *task;
718
712
 
719
713
        g_return_if_fail (SOUP_IS_CONNECTION (conn));
720
714
        priv = SOUP_CONNECTION_GET_PRIVATE (conn);
721
715
 
722
 
        data = g_slice_new (SoupConnectionAsyncConnectData);
723
 
        data->conn = g_object_ref (conn);
724
 
        data->callback = callback;
725
 
        data->callback_data = user_data;
726
 
 
727
 
        if (priv->use_thread_context)
728
 
                async_context = g_main_context_get_thread_default ();
729
 
        else
730
 
                async_context = priv->async_context;
731
 
 
732
 
        if (!soup_socket_start_proxy_ssl (priv->socket,
733
 
                                          priv->remote_uri->host,
734
 
                                          cancellable)) {
735
 
                soup_add_completion (async_context,
736
 
                                     idle_start_ssl_completed, data);
737
 
                return;
738
 
        }
739
 
 
740
716
        soup_connection_event (conn, G_SOCKET_CLIENT_TLS_HANDSHAKING, NULL);
741
 
        soup_socket_handshake_async (priv->socket, cancellable,
742
 
                                     start_ssl_completed, data);
 
717
 
 
718
        if (priv->async_context && !priv->use_thread_context)
 
719
                g_main_context_push_thread_default (priv->async_context);
 
720
        task = g_task_new (conn, cancellable, callback, user_data);
 
721
 
 
722
        soup_socket_handshake_async (priv->socket, priv->remote_uri->host,
 
723
                                     cancellable, start_ssl_completed, task);
 
724
}
 
725
 
 
726
gboolean
 
727
soup_connection_start_ssl_finish (SoupConnection  *conn,
 
728
                                  GAsyncResult    *result,
 
729
                                  GError         **error)
 
730
{
 
731
        return g_task_propagate_boolean (G_TASK (result), error);
743
732
}
744
733
 
745
734
/**