Mercurial > dovecot > core-2.2
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 |
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 } |