annotate src/lib-http/http-client-connection.c @ 15394:107c8b2c9594

lib-http: Added initial HTTP client implementation.
author Stephan Bosch <stephan@rename-it.nl>
date Sat, 24 Nov 2012 00:30:14 +0200
parents
children 9cab24687819
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
15394
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
1 /* Copyright (c) 2012 Dovecot authors, see the included COPYING file */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
2
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
3 #include "lib.h"
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
4 #include "net.h"
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
5 #include "str.h"
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
6 #include "hash.h"
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
7 #include "array.h"
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
8 #include "ioloop.h"
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
9 #include "istream.h"
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
10 #include "ostream.h"
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
11 #include "iostream-rawlog.h"
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
12 #include "iostream-ssl.h"
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
13 #include "http-response-parser.h"
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
14
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
15 #include "http-client-private.h"
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
16
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
17 /*
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
18 * Logging
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
19 */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
20
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
21 static inline void
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
22 http_client_connection_debug(struct http_client_connection *conn,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
23 const char *format, ...) ATTR_FORMAT(2, 3);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
24 static inline void
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
25 http_client_connection_error(struct http_client_connection *conn,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
26 const char *format, ...) ATTR_FORMAT(2, 3);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
27
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
28 static inline void
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
29 http_client_connection_debug(struct http_client_connection *conn,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
30 const char *format, ...)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
31 {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
32 va_list args;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
33
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
34 if (conn->client->set.debug) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
35
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
36 va_start(args, format);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
37 i_debug("http-client: conn %s: %s",
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
38 http_client_connection_label(conn), t_strdup_vprintf(format, args));
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
39 va_end(args);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
40 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
41 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
42
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
43 static inline void
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
44 http_client_connection_error(struct http_client_connection *conn,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
45 const char *format, ...)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
46 {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
47 va_list args;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
48
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
49 va_start(args, format);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
50 i_error("http-client: conn %s: %s",
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
51 http_client_connection_label(conn), t_strdup_vprintf(format, args));
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
52 va_end(args);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
53 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
54
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
55
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
56 /*
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
57 * Connection
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
58 */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
59
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
60 static void http_client_connection_input(struct connection *_conn);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
61
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
62 bool http_client_connection_is_ready(struct http_client_connection *conn)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
63 {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
64 return (conn->connected && !conn->output_locked &&
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
65 array_count(&conn->request_wait_list) <
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
66 conn->client->set.max_pipelined_requests);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
67 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
68
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
69 static void
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
70 http_client_connection_retry_requests(struct http_client_connection *conn,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
71 unsigned int status, const char *error)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
72 {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
73 struct http_client_request **req;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
74
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
75 array_foreach_modifiable(&conn->request_wait_list, req) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
76 http_client_request_retry(*req, status, error);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
77 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
78 array_clear(&conn->request_wait_list);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
79 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
80
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
81 static void
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
82 http_client_connection_server_close(struct http_client_connection **_conn)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
83 {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
84 struct http_client_connection *conn = *_conn;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
85 struct http_client_request **req;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
86
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
87 conn->connected = FALSE;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
88 conn->closing = TRUE;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
89
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
90 http_client_connection_debug(conn,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
91 "Server explicitly closed connection");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
92
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
93 array_foreach_modifiable(&conn->request_wait_list, req) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
94 http_client_request_resubmit(*req);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
95 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
96 array_clear(&conn->request_wait_list);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
97
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
98 if (conn->client->ioloop != NULL)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
99 io_loop_stop(conn->client->ioloop);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
100
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
101 http_client_connection_free(_conn);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
102 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
103
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
104 static void
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
105 http_client_connection_abort_temp_error(struct http_client_connection **_conn,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
106 unsigned int status, const char *error)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
107 {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
108 struct http_client_connection *conn = *_conn;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
109
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
110 conn->connected = FALSE;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
111 conn->closing = TRUE;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
112
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
113 http_client_connection_retry_requests(conn, status, error);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
114 http_client_connection_free(_conn);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
115 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
116
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
117 static void
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
118 http_client_connection_abort_error(struct http_client_connection **_conn,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
119 unsigned int status, const char *error)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
120 {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
121 struct http_client_connection *conn = *_conn;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
122 struct http_client_request **req;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
123
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
124 conn->connected = FALSE;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
125 conn->closing = TRUE;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
126
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
127 array_foreach_modifiable(&conn->request_wait_list, req) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
128 http_client_request_error(*req, status, error);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
129 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
130 array_clear(&conn->request_wait_list);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
131 http_client_connection_free(_conn);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
132 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
133
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
134 static void
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
135 http_client_connection_idle_timeout(struct http_client_connection *conn)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
136 {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
137 http_client_connection_debug(conn, "Idle connection timed out");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
138
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
139 http_client_connection_free(&conn);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
140 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
141
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
142 static void
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
143 http_client_connection_check_idle(struct http_client_connection *conn)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
144 {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
145 unsigned int timeout, count;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
146
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
147 if (array_count(&conn->request_wait_list) == 0 &&
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
148 conn->incoming_payload == NULL &&
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
149 conn->client->set.max_idle_time_msecs > 0) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
150
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
151 if (conn->to_idle != NULL) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
152 /* timeout already set */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
153 return;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
154 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
155
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
156 http_client_connection_debug(conn,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
157 "No more requests queued; going idle");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
158
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
159 if (conn->client->ioloop != NULL)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
160 io_loop_stop(conn->client->ioloop);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
161
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
162 count = array_count(&conn->peer->conns);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
163 i_assert(count > 0);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
164
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
165 /* set timeout for this connection */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
166 if (count > conn->client->set.max_parallel_connections) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
167 /* instant death for (urgent) connections above limit */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
168 timeout = 0;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
169 } else {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
170 /* kill duplicate connections quicker;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
171 linearly based on the number of connections */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
172 timeout = (conn->client->set.max_parallel_connections - count) *
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
173 (conn->client->set.max_idle_time_msecs /
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
174 conn->client->set.max_parallel_connections);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
175 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
176
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
177 conn->to_idle =
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
178 timeout_add(timeout, http_client_connection_idle_timeout, conn);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
179
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
180 } else {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
181 /* there should be no idle timeout */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
182 i_assert(conn->to_idle == NULL);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
183 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
184 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
185
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
186 static void
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
187 http_client_connection_continue_timeout(struct http_client_connection *conn)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
188 {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
189 struct http_client_request *const *req_idx;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
190 struct http_client_request *req;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
191
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
192 if (conn->to_response != NULL)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
193 timeout_remove(&conn->to_response);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
194 conn->peer->no_payload_sync = TRUE;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
195
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
196 http_client_connection_debug(conn,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
197 "Expected 100-continue response timed out; sending payload anyway");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
198
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
199 req_idx = array_idx(&conn->request_wait_list, 0);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
200 req = req_idx[0];
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
201
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
202 // FIXME: we should mark this in the peer object for next requests
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
203 conn->payload_continue = TRUE;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
204 if (http_client_request_send_more(req) < 0) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
205 http_client_connection_abort_temp_error(&conn,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
206 HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, "Failed to send request");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
207 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
208 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
209
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
210 bool http_client_connection_next_request(struct http_client_connection *conn)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
211 {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
212 struct http_client_request *req = NULL;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
213
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
214 if (!http_client_connection_is_ready(conn)) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
215
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
216 http_client_connection_debug(conn, "Not ready for next request");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
217 return FALSE;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
218 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
219
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
220 /* claim request, but no urgent request can be second in line */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
221 req = http_client_peer_claim_request(conn->peer,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
222 array_count(&conn->request_wait_list) > 0);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
223 if (req == NULL) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
224 http_client_connection_check_idle(conn);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
225 return FALSE;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
226 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
227
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
228 if (conn->to_idle != NULL)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
229 timeout_remove(&conn->to_idle);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
230
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
231 req->conn = conn;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
232 conn->payload_continue = FALSE;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
233 if (conn->peer->no_payload_sync)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
234 req->payload_sync = FALSE;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
235 array_append(&conn->request_wait_list, &req, 1);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
236 http_client_request_ref(req);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
237
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
238 if (http_client_request_send(req) < 0) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
239 http_client_connection_abort_temp_error(&conn,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
240 HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
241 "Failed to send request");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
242 return FALSE;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
243 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
244
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
245 /* https://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-21;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
246 Section 6.1.2.1:
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
247
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
248 Because of the presence of older implementations, the protocol allows
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
249 ambiguous situations in which a client might send "Expect: 100-continue"
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
250 without receiving either a 417 (Expectation Failed) or a 100 (Continue)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
251 status code. Therefore, when a client sends this header field to an
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
252 origin server (possibly via a proxy) from which it has never seen a 100
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
253 (Continue) status code, the client SHOULD NOT wait for an indefinite
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
254 period before sending the payload body.
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
255 */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
256 if (req->payload_sync) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
257 i_assert(req->input_size > 0);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
258 i_assert(conn->to_response == NULL);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
259 conn->to_response = timeout_add(HTTP_CLIENT_CONTINUE_TIMEOUT_MSECS,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
260 http_client_connection_continue_timeout, conn);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
261 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
262
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
263 return TRUE;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
264 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
265
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
266 static void http_client_connection_destroy(struct connection *_conn)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
267 {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
268 struct http_client_connection *conn =
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
269 (struct http_client_connection *)_conn;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
270
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
271 conn->closing = TRUE;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
272 conn->connected = FALSE;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
273
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
274 switch (_conn->disconnect_reason) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
275 case CONNECTION_DISCONNECT_CONNECT_TIMEOUT:
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
276 http_client_peer_connection_failure(conn->peer);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
277 break;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
278 case CONNECTION_DISCONNECT_CONN_CLOSED:
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
279 /* retry pending requests if possible */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
280 http_client_connection_retry_requests(conn,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
281 HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, "Connection lost");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
282 default:
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
283 break;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
284 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
285
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
286 http_client_connection_free(&conn);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
287 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
288
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
289 static void http_client_payload_finished(struct http_client_connection *conn)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
290 {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
291 timeout_remove(&conn->to_input);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
292 conn->conn.io = io_add(conn->conn.fd_in, IO_READ,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
293 http_client_connection_input, &conn->conn);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
294 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
295
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
296 static void http_client_payload_destroyed(struct http_client_connection *conn)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
297 {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
298 i_assert(conn->incoming_payload != NULL);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
299 i_assert(conn->pending_request != NULL);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
300 i_assert(conn->conn.io == NULL);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
301
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
302 http_client_connection_debug(conn, "Response payload stream destroyed");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
303
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
304 /* caller is allowed to change the socket fd to blocking while reading
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
305 the payload. make sure here that it's switched back. */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
306 net_set_nonblock(conn->conn.fd_in, TRUE);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
307
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
308 conn->incoming_payload = NULL;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
309
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
310 http_client_request_finish(&conn->pending_request);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
311 conn->pending_request = NULL;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
312
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
313 if (conn->close_indicated) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
314 http_client_connection_server_close(&conn);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
315 return;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
316 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
317
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
318 /* input stream may have pending input. make sure input handler
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
319 gets called (but don't do it directly, since we get get here
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
320 somewhere from the API user's code, which we can't really know what
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
321 state it is in). this call also triggers sending a new request if
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
322 necessary. */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
323 conn->to_input =
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
324 timeout_add_short(0, http_client_connection_input, &conn->conn);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
325 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
326
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
327 static bool
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
328 http_client_connection_return_response(struct http_client_connection *conn,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
329 struct http_client_request *req, struct http_response *response)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
330 {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
331 struct istream *payload;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
332
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
333 i_assert(conn->incoming_payload == NULL);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
334 i_assert(conn->pending_request == NULL);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
335
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
336 req->state = HTTP_REQUEST_STATE_GOT_RESPONSE;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
337
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
338 if (response->payload != NULL) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
339 /* wrap the stream to capture the destroy event without destroying the
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
340 actual payload stream. */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
341 conn->incoming_payload = response->payload =
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
342 i_stream_create_limit(response->payload, (uoff_t)-1);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
343 i_stream_set_destroy_callback(response->payload,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
344 http_client_payload_destroyed,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
345 conn);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
346 /* the callback may add its own I/O, so we need to remove
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
347 our one before calling it */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
348 io_remove(&conn->conn.io);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
349 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
350
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
351 http_client_request_callback(req, response);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
352
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
353 // FIXME: conn may be freed at this point..
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
354
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
355 if (response->payload != NULL) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
356 req->state = HTTP_REQUEST_STATE_PAYLOAD_IN;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
357 payload = response->payload;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
358 response->payload = NULL;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
359 conn->pending_request = req;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
360 i_stream_unref(&payload);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
361 if (conn->to_input != NULL) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
362 /* already finished reading the payload */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
363 http_client_payload_finished(conn);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
364 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
365 } else {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
366 http_client_request_finish(&req);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
367 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
368
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
369 if (conn->incoming_payload == NULL) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
370 i_assert(conn->conn.io != NULL);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
371 return TRUE;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
372 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
373
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
374 return FALSE;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
375 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
376
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
377 static void http_client_connection_input(struct connection *_conn)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
378 {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
379 struct http_client_connection *conn =
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
380 (struct http_client_connection *)_conn;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
381 struct http_response *response;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
382 struct http_client_request *const *req_idx;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
383 struct http_client_request *req = NULL;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
384 int finished = 0, ret;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
385 const char *error;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
386 bool no_payload = FALSE;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
387
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
388 i_assert(conn->incoming_payload == NULL);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
389
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
390 if (conn->to_input != NULL) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
391 /* We came here from a timeout added by
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
392 http_client_payload_destroyed(). The IO couldn't be added
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
393 back immediately in there, because the HTTP API user may
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
394 still have had its own IO pointed to the same fd. It should
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
395 be removed by now, so we can add it back. */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
396 http_client_payload_finished(conn);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
397 finished++;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
398 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
399
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
400 /* get first waiting request */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
401 if (array_count(&conn->request_wait_list) > 0) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
402 req_idx = array_idx(&conn->request_wait_list, 0);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
403 req = req_idx[0];
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
404
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
405 /* https://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-21
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
406 Section 3.3.2:
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
407
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
408 A server MAY send a Content-Length header field in a response to a
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
409 HEAD request [...]
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
410 */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
411 no_payload = (strcmp(req->method, "HEAD") == 0);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
412 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
413
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
414 // FIXME: handle somehow if server replies before request->input is at EOF
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
415 while ((ret=http_response_parse_next
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
416 (conn->http_parser, no_payload, &response, &error)) > 0) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
417 bool aborted;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
418
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
419 if (req == NULL) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
420 /* server sent response without any requests in the wait list */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
421 http_client_connection_error(conn, "Got unexpected input from server");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
422 http_client_connection_free(&conn);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
423 return;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
424 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
425
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
426 /* https://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-21
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
427 Section 7.2:
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
428
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
429 A client MUST be prepared to accept one or more 1xx status responses
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
430 prior to a regular response, even if the client does not expect a 100
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
431 (Continue) status message. Unexpected 1xx status responses MAY be
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
432 ignored by a user agent.
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
433 */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
434 if (req->payload_sync && response->status == 100) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
435 conn->payload_continue = TRUE;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
436 if (conn->to_response != NULL)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
437 timeout_remove(&conn->to_response);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
438 http_client_connection_debug(conn,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
439 "Got expected 100-continue response");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
440 if (http_client_request_send_more(req) < 0) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
441 http_client_connection_abort_temp_error(&conn,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
442 HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
443 "Failed to send request");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
444 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
445 return;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
446 } else if (response->status / 100 == 1) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
447 /* ignore them for now */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
448 http_client_connection_debug(conn,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
449 "Got unexpected %u response; ignoring", response->status);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
450 continue;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
451 } // FIXME: handle 417 Expectation Failed
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
452
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
453 http_client_connection_debug(conn,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
454 "Got %u response for request %s",
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
455 response->status, http_client_request_label(req));
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
456
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
457 /* remove request from queue */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
458 array_delete(&conn->request_wait_list, 0, 1);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
459 aborted = (req->state == HTTP_REQUEST_STATE_ABORTED);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
460 http_client_request_unref(&req);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
461
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
462 conn->close_indicated = response->connection_close;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
463
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
464 if (!aborted) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
465 if (response->status / 100 == 3) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
466 /* redirect */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
467 http_client_request_redirect(req, response->location);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
468 } else {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
469 /* response for application */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
470 if (!http_client_connection_return_response(conn, req, response))
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
471 return;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
472 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
473
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
474 finished++;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
475 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
476
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
477 /* server closing connection? */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
478 if (conn->close_indicated) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
479 http_client_connection_server_close(&conn);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
480 return;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
481 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
482
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
483 /* get next waiting request */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
484 if (array_count(&conn->request_wait_list) > 0) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
485 req_idx = array_idx(&conn->request_wait_list, 0);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
486 req = req_idx[0];
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
487 no_payload = (strcmp(req->method, "HEAD") == 0);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
488 } else {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
489 req = NULL;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
490 no_payload = FALSE;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
491 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
492 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
493
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
494 if (ret <= 0 &&
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
495 (conn->conn.input->eof || conn->conn.input->stream_errno != 0)) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
496 int stream_errno = conn->conn.input->stream_errno;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
497 http_client_connection_debug(conn,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
498 "Lost connection to server (error=%s)",
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
499 stream_errno != 0 ? strerror(stream_errno) : "EOF");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
500 http_client_connection_abort_temp_error(&conn,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
501 HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, "Connection lost");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
502 return;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
503 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
504
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
505 if (ret < 0) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
506 http_client_connection_abort_error(&conn,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
507 HTTP_CLIENT_REQUEST_ERROR_BAD_RESPONSE, error);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
508 return;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
509 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
510
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
511 if (finished > 0) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
512 /* room for new requests */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
513 http_client_peer_handle_requests(conn->peer);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
514 http_client_connection_check_idle(conn);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
515 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
516 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
517
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
518 static int http_client_connection_output(struct http_client_connection *conn)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
519 {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
520 struct http_client_request *const *req_idx, *req;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
521 struct ostream *output = conn->conn.output;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
522 int ret;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
523
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
524 if ((ret = o_stream_flush(output)) <= 0) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
525 if (ret < 0) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
526 http_client_connection_abort_temp_error(&conn,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
527 HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, "Connection lost");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
528 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
529 return ret;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
530 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
531
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
532 if (array_count(&conn->request_wait_list) > 0 && conn->output_locked) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
533 req_idx = array_idx(&conn->request_wait_list, 0);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
534 req = req_idx[0];
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
535
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
536 if (!req->payload_sync || conn->payload_continue) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
537 if (http_client_request_send_more(req) < 0) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
538 http_client_connection_abort_temp_error(&conn,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
539 HTTP_CLIENT_REQUEST_ERROR_CONNECTION_LOST, "Connection lost");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
540 return -1;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
541 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
542 if (!conn->output_locked) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
543 /* room for new requests */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
544 http_client_peer_handle_requests(conn->peer);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
545 http_client_connection_check_idle(conn);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
546 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
547 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
548 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
549 return 1;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
550 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
551
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
552 static void
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
553 http_client_connection_ready(struct http_client_connection *conn)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
554 {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
555 struct stat st;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
556
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
557 conn->connected = TRUE;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
558
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
559 if (*conn->client->set.rawlog_dir != '\0' &&
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
560 stat(conn->client->set.rawlog_dir, &st) == 0) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
561 iostream_rawlog_create(conn->client->set.rawlog_dir,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
562 &conn->conn.input, &conn->conn.output);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
563 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
564
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
565 conn->http_parser = http_response_parser_init(conn->conn.input);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
566 o_stream_set_flush_callback(conn->conn.output,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
567 http_client_connection_output, conn);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
568
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
569 /* we never pipeline before the first response */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
570 (void)http_client_connection_next_request(conn);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
571 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
572
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
573 #ifdef HTTP_BUILD_SSL
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
574 static int http_client_connection_ssl_handshaked(void *context)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
575 {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
576 struct http_client_connection *conn = context;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
577
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
578 if (!conn->client->set.ssl_verify) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
579 /* skip certificate checks */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
580 http_client_connection_debug(conn, "SSL handshake successful");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
581 return 0;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
582 } else if (!ssl_iostream_has_valid_client_cert(conn->ssl_iostream)) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
583 if (!ssl_iostream_has_broken_client_cert(conn->ssl_iostream)) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
584 http_client_connection_error(conn, "SSL certificate not received");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
585 } else {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
586 http_client_connection_error(conn, "Received invalid SSL certificate");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
587 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
588 } else {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
589 const char *host = http_client_peer_get_hostname(conn->peer);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
590
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
591 i_assert(host != NULL);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
592
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
593 if (ssl_iostream_cert_match_name(conn->ssl_iostream, host) < 0) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
594 http_client_connection_error(conn,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
595 "SSL certificate doesn't match host name");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
596 } else {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
597 http_client_connection_debug(conn, "SSL handshake successful");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
598 return 0;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
599 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
600 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
601 i_stream_close(conn->conn.input);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
602 return -1;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
603 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
604
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
605 static int
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
606 http_client_connection_ssl_init(struct http_client_connection *conn)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
607 {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
608 struct ssl_iostream_settings ssl_set;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
609 const char *source;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
610
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
611 if (conn->peer->ssl_ctx == NULL) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
612 http_client_connection_error(conn, "No SSL context");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
613 return -1;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
614 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
615
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
616 memset(&ssl_set, 0, sizeof(ssl_set));
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
617 if (conn->client->set.ssl_verify) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
618 ssl_set.verbose_invalid_cert = TRUE;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
619 ssl_set.verify_remote_cert = TRUE;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
620 ssl_set.require_valid_cert = TRUE;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
621 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
622
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
623 if (conn->client->set.debug)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
624 http_client_connection_debug(conn, "Starting SSL handshake");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
625
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
626 source = t_strdup_printf
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
627 ("connection %s: ", http_client_connection_label(conn));
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
628 if (io_stream_create_ssl(conn->peer->ssl_ctx, source, &ssl_set,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
629 &conn->conn.input, &conn->conn.output, &conn->ssl_iostream) < 0) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
630 http_client_connection_error(conn, "Couldn't initialize SSL client");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
631 return -1;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
632 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
633 ssl_iostream_set_handshake_callback(conn->ssl_iostream,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
634 http_client_connection_ssl_handshaked, conn);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
635 if (ssl_iostream_handshake(conn->ssl_iostream) < 0) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
636 http_client_connection_error(conn, "SSL handshake failed: %s",
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
637 ssl_iostream_get_last_error(conn->ssl_iostream));
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
638 return -1;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
639 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
640
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
641 http_client_connection_ready(conn);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
642 return 0;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
643 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
644 #endif
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
645
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
646 static void
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
647 http_client_connection_connected(struct connection *_conn, bool success)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
648 {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
649 struct http_client_connection *conn =
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
650 (struct http_client_connection *)_conn;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
651
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
652 if (!success) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
653 http_client_connection_error(conn, "Connect failed: %m");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
654 http_client_peer_connection_failure(conn->peer);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
655
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
656 } else {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
657 http_client_connection_debug(conn, "Connected");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
658 #ifdef HTTP_BUILD_SSL
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
659 if (conn->peer->addr.ssl) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
660 if (http_client_connection_ssl_init(conn) < 0)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
661 http_client_peer_connection_failure(conn->peer);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
662 return;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
663 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
664 #endif
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
665 http_client_connection_ready(conn);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
666 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
667 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
668
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
669 static const struct connection_settings http_client_connection_set = {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
670 .input_max_size = (size_t)-1,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
671 .output_max_size = (size_t)-1,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
672 .client = TRUE
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
673 };
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
674
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
675 static const struct connection_vfuncs http_client_connection_vfuncs = {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
676 .destroy = http_client_connection_destroy,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
677 .input = http_client_connection_input,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
678 .client_connected = http_client_connection_connected
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
679 };
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
680
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
681 struct connection_list *
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
682 http_client_connection_list_init(void)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
683 {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
684 return connection_list_init
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
685 (&http_client_connection_set, &http_client_connection_vfuncs);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
686 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
687
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
688 static int http_client_connection_connect(struct http_client_connection *conn)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
689 {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
690 if (conn->conn.fd_in == -1) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
691 if (connection_client_connect(&conn->conn) < 0) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
692 http_client_connection_error(conn, "Could not connect");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
693 return -1;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
694 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
695 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
696
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
697 return 0;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
698 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
699
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
700 struct http_client_connection *
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
701 http_client_connection_create(struct http_client_peer *peer)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
702 {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
703 struct http_client_connection *conn;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
704 static unsigned int id = 0;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
705
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
706 conn = i_new(struct http_client_connection, 1);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
707 conn->client = peer->client;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
708 conn->peer = peer;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
709 i_array_init(&conn->request_wait_list, 16);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
710
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
711 connection_init_client_ip
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
712 (peer->client->conn_list, &conn->conn, &peer->addr.ip, peer->addr.port);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
713
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
714 if (http_client_connection_connect(conn) < 0) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
715 http_client_connection_free(&conn);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
716 return NULL;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
717 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
718
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
719 conn->id = id++;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
720 array_append(&peer->conns, &conn, 1);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
721
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
722 http_client_connection_debug(conn,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
723 "Connection created (%d parallel connections exist)",
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
724 array_count(&peer->conns));
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
725 return conn;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
726 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
727
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
728 void http_client_connection_free(struct http_client_connection **_conn)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
729 {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
730 struct http_client_connection *conn = *_conn;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
731 struct http_client_connection *const *conn_idx;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
732 struct http_client_peer *peer = conn->peer;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
733 struct http_client_request **req;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
734
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
735 http_client_connection_debug(conn, "Connection destroy");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
736
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
737 conn->connected = FALSE;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
738
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
739 #ifdef HTTP_BUILD_SSL
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
740 if (conn->ssl_iostream != NULL)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
741 ssl_iostream_unref(&conn->ssl_iostream);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
742 #endif
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
743
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
744 connection_deinit(&conn->conn);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
745
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
746 /* abort all pending requests */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
747 array_foreach_modifiable(&conn->request_wait_list, req) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
748 http_client_request_error(*req, HTTP_CLIENT_REQUEST_ERROR_ABORTED,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
749 "Aborting");
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
750 http_client_request_unref(req);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
751 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
752 array_free(&conn->request_wait_list);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
753
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
754 if (conn->to_input != NULL)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
755 timeout_remove(&conn->to_input);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
756 if (conn->to_idle != NULL)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
757 timeout_remove(&conn->to_idle);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
758 if (conn->to_response != NULL)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
759 timeout_remove(&conn->to_response);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
760
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
761 /* remove this connection from the list */
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
762 array_foreach(&conn->peer->conns, conn_idx) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
763 if (*conn_idx == conn) {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
764 array_delete(&conn->peer->conns,
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
765 array_foreach_idx(&conn->peer->conns, conn_idx), 1);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
766 break;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
767 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
768 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
769
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
770 if (conn->http_parser != NULL)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
771 http_response_parser_deinit(&conn->http_parser);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
772
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
773 i_free(conn);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
774 *_conn = NULL;
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
775
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
776 http_client_peer_connection_lost(peer);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
777 }
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
778
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
779 void http_client_connection_switch_ioloop(struct http_client_connection *conn)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
780 {
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
781 if (conn->to_input != NULL)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
782 conn->to_input = io_loop_move_timeout(&conn->to_input);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
783 if (conn->to_idle != NULL)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
784 conn->to_idle = io_loop_move_timeout(&conn->to_idle);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
785 if (conn->to_response != NULL)
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
786 conn->to_response = io_loop_move_timeout(&conn->to_response);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
787 connection_switch_ioloop(&conn->conn);
107c8b2c9594 lib-http: Added initial HTTP client implementation.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
788 }