source: trunk/third/libsoup/tests/revserver.c @ 21108

Revision 21108, 3.3 KB checked in by ghudson, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r21107, which included commits to RCS files with non-trunk default branches.
Line 
1#ifdef HAVE_CONFIG_H
2#include "config.h"
3#endif
4
5#include <ctype.h>
6#include <pthread.h>
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10#include <unistd.h>
11
12#include <libsoup/soup-address.h>
13#include <libsoup/soup-socket.h>
14
15static void rev_read (SoupSocket *sock, GString *buf);
16static void rev_write (SoupSocket *sock, GString *buf);
17
18static void
19reverse (GString *buf)
20{
21        char tmp, *a, *b;
22
23        a = buf->str;
24        b = buf->str + buf->len - 1;
25
26        while (isspace ((unsigned char)*b) && b > a)
27                b--;
28
29        while (a < b) {
30                tmp = *a;
31                *a++ = *b;
32                *b-- = tmp;
33        }
34}
35
36static void
37rev_done (SoupSocket *sock, GString *buf)
38{
39        g_object_unref (sock);
40        g_string_free (buf, TRUE);
41}
42
43static void
44rev_write (SoupSocket *sock, GString *buf)
45{
46        SoupSocketIOStatus status;
47        gsize nwrote;
48
49        do {
50                status = soup_socket_write (sock, buf->str, buf->len, &nwrote);
51                memmove (buf->str, buf->str + nwrote, buf->len - nwrote);
52                buf->len -= nwrote;
53        } while (status == SOUP_SOCKET_OK && buf->len);
54
55        switch (status) {
56        case SOUP_SOCKET_OK:
57                rev_read (sock, buf);
58                break;
59
60        case SOUP_SOCKET_WOULD_BLOCK:
61                g_error ("Can't happen");
62                break;
63
64        default:
65                g_warning ("Socket error");
66                /* fall through */
67
68        case SOUP_SOCKET_EOF:
69                rev_done (sock, buf);
70                break;
71        }
72}
73
74static void
75rev_read (SoupSocket *sock, GString *buf)
76{
77        SoupSocketIOStatus status;
78        char tmp[10];
79        gsize nread;
80        gboolean eol;
81
82        do {
83                status = soup_socket_read_until (sock, tmp, sizeof (tmp),
84                                                 "\n", 1, &nread, &eol);
85                if (status == SOUP_SOCKET_OK)
86                        g_string_append_len (buf, tmp, nread);
87        } while (status == SOUP_SOCKET_OK && !eol);
88
89        switch (status) {
90        case SOUP_SOCKET_OK:
91                reverse (buf);
92                rev_write (sock, buf);
93                break;
94
95        case SOUP_SOCKET_WOULD_BLOCK:
96                g_error ("Can't happen");
97                break;
98
99        default:
100                g_warning ("Socket error");
101                /* fall through */
102
103        case SOUP_SOCKET_EOF:
104                rev_done (sock, buf);
105                break;
106        }
107}
108
109static void *
110start_thread (void *client)
111{
112        rev_read (client, g_string_new (NULL));
113
114        return NULL;
115}
116
117static void
118new_connection (SoupSocket *listener, SoupSocket *client, gpointer user_data)
119{
120        pthread_t pth;
121
122        g_object_ref (client);
123        g_object_set (G_OBJECT (client),
124                      SOUP_SOCKET_FLAG_NONBLOCKING, FALSE,
125                      NULL);
126
127        if (pthread_create (&pth, NULL, start_thread, client) != 0) {
128                g_warning ("Could not start thread");
129                g_object_unref (client);
130        }
131}
132
133int
134main (int argc, char **argv)
135{
136        SoupSocket *listener;
137        SoupAddressFamily family = SOUP_ADDRESS_FAMILY_IPV4;
138        guint port = SOUP_ADDRESS_ANY_PORT;
139        SoupAddress *addr;
140        GMainLoop *loop;
141        int opt;
142
143        g_type_init ();
144
145        while ((opt = getopt (argc, argv, "6p:")) != -1) {
146                switch (opt) {
147                case '6':
148                        family = SOUP_ADDRESS_FAMILY_IPV6;
149                        break;
150                case 'p':
151                        port = atoi (optarg);
152                        break;
153                default:
154                        fprintf (stderr, "Usage: %s [-6] [-p port]\n",
155                                 argv[0]);
156                        exit (1);
157                }
158        }
159
160        addr = soup_address_new_any (family, port);
161        if (!addr) {
162                fprintf (stderr, "Could not create listener address\n");
163                exit (1);
164        }
165
166        listener = soup_socket_server_new (addr, NULL,
167                                           new_connection, NULL);
168        g_object_unref (addr);
169        if (!listener) {
170                fprintf (stderr, "Could not create listening socket\n");
171                exit (1);
172        }
173        printf ("Listening on port %d\n",
174                soup_address_get_port (
175                        soup_socket_get_local_address (listener)));
176
177        loop = g_main_loop_new (NULL, TRUE);
178        g_main_loop_run (loop);
179
180        g_object_unref (listener);
181        return 0;
182}
Note: See TracBrowser for help on using the repository browser.