Fix FSF address (Tobias Mueller, #470445)
[platform/upstream/evolution-data-server.git] / servers / exchange / lib / davcat.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
3 /* Copyright (C) 2003, 2004 Novell, Inc.
4  *
5  * This  program is free  software; you  can redistribute  it and/or
6  * modify it under the terms of version 2  of the GNU General Public
7  * License as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public
15  * License along with this program; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 /* Generic WebDAV test program */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <ctype.h>
27 #include <errno.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <unistd.h>
31
32 #include "e2k-context.h"
33 #include "e2k-uri.h"
34 #include "e2k-utils.h"
35 #include "e2k-xml-utils.h"
36
37 #include "test-utils.h"
38
39 static void
40 print_header (gpointer name, gpointer value, gpointer data)
41 {
42         gboolean *isxml = data;
43
44         printf ("%s: %s\n", (char *)name, (char *)value);
45         if (!g_ascii_strcasecmp (name, "Content-Type") &&
46             strstr (value, "/xml"))
47                 *isxml = TRUE;
48 }
49
50 const char *test_program_name = "davcat";
51
52 void
53 test_main (int argc, char **argv)
54 {
55         E2kContext *ctx;
56         SoupMessage *msg;
57         GByteArray *input;
58         char buf[1024], *base_uri, *root_uri, *eol, *vers, *p;
59         char *method, *path, *uri;
60         char *name, *value;
61         int nread;
62         gboolean isxml = FALSE;
63
64         if (argc != 2) {
65                 fprintf (stderr, "usage: %s URI\n", argv[0]);
66                 exit (1);
67         }
68         base_uri = argv[1];
69         ctx = test_get_context (base_uri);
70
71         input = g_byte_array_new ();
72         do {
73                 nread = read (STDIN_FILENO, buf, sizeof (buf));
74                 if (nread > 0)
75                         g_byte_array_append (input, buf, nread);
76         } while (nread > 0 || (nread == -1 && errno == EINTR));
77         g_byte_array_append (input, "", 1);
78
79         method = input->data;
80         eol = strchr (method, '\n');
81         p = strchr (method, ' ');
82         if (!eol || !p || p > eol) {
83                 fprintf (stderr, "Could not parse request method\n");
84                 exit (1);
85         }
86         *p = '\0';
87
88         path = p + 1;
89         if (*path == '/')
90                 path++;
91         p = strchr (path, ' ');
92         if (!p || p > eol)
93                 p = eol;
94         *p = '\0';
95         if (p < eol)
96                 vers = p + 1;
97         else
98                 vers = NULL;
99
100         root_uri = g_strdup (base_uri);
101         p = strstr (root_uri, "://");
102         if (p) {
103                 p = strchr (p + 3, '/');
104                 if (p)
105                         *p = '\0';
106         }
107         uri = e2k_uri_concat (root_uri, path);
108         g_free (root_uri);
109         msg = e2k_soup_message_new (ctx, uri, method);
110         if (!msg) {
111                 fprintf (stderr, "Could not create message to %s\n", uri);
112                 exit (1);
113         }
114         g_free (uri);
115
116         if (vers) {
117                 if (strncmp (vers, "HTTP/1.", 7) != 0 ||
118                     (vers[7] != '0' && vers[7] != '1')) {
119                         fprintf (stderr, "Could not parse HTTP version\n");
120                         exit (1);
121                 }
122                 if (vers[7] == '0')
123                         soup_message_set_http_version (msg, SOUP_HTTP_1_0);
124         }
125
126         while (1) {
127                 name = eol + 1;
128                 eol = strchr (name, '\n');
129                 p = strchr (name, ':');
130                 if (!eol || eol == name || !p || p > eol || p[1] != ' ')
131                         break;
132                 *p = '\0';
133                 value = p + 2;
134                 *eol = '\0';
135                 if (eol[-1] == '\r')
136                         eol[-1] = '\0';
137                 soup_message_add_header (msg->request_headers, name, value);
138         }
139
140         p = name;
141         if (*p == '\r')
142                 p++;
143         if (*p == '\n')
144                 p++;
145
146         if (*p) {
147                 msg->request.body = e2k_lf_to_crlf (p);
148                 msg->request.length = strlen (msg->request.body);
149                 msg->request.owner = SOUP_BUFFER_SYSTEM_OWNED;
150
151                 if (!soup_message_get_header (msg->request_headers, "Content-Type")) {
152                         soup_message_add_header (msg->request_headers,
153                                                  "Content-Type", "text/xml");
154                 }
155         }
156
157         e2k_context_send_message (ctx, NULL, msg);
158
159         printf ("%d %s\n", msg->status_code, msg->reason_phrase);
160         if (SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code))
161                 exit (1);
162
163         soup_message_foreach_header (msg->response_headers,
164                                      print_header, &isxml);
165         printf ("\n");
166
167         if (isxml) {
168                 xmlDoc *doc;
169
170                 doc = e2k_parse_xml (msg->response.body, msg->response.length);
171                 if (doc) {
172                         xmlDocFormatDump (stdout, doc, 1);
173                         xmlFreeDoc (doc);
174                 } else
175                         fwrite (msg->response.body, 1, msg->response.length, stdout);
176         } else
177                 fwrite (msg->response.body, 1, msg->response.length, stdout);
178         printf ("\n");
179
180         g_object_unref (msg);
181         g_byte_array_free (input, TRUE);
182         g_object_unref (ctx);
183         test_quit ();
184 }