annotate src/lib-http/http-server-response.c @ 22633:9284bdc3c5c5

director: Don't recreate timeout on every user lookup Recreate it only when the timeout should change.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Sat, 04 Nov 2017 01:34:02 +0200
parents 1d5160a7b0fd
children cb108f786fb4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
21390
2e2563132d5f Updated copyright notices to include the year 2017.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21389
diff changeset
1 /* Copyright (c) 2013-2017 Dovecot authors, see the included COPYING file */
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
2
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
3 #include "lib.h"
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
4 #include "str.h"
17772
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
5 #include "array.h"
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
6 #include "istream.h"
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
7 #include "ostream-private.h"
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
8 #include "http-date.h"
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
9 #include "http-transfer.h"
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
10 #include "http-server-private.h"
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
11
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
12 struct http_server_response_payload {
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
13 struct http_server_response *resp;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
14 struct const_iovec *iov;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
15 unsigned int iov_count, iov_idx;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
16 size_t iov_pos;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
17 };
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
18
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
19 /*
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
20 * Logging
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
21 */
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
22
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
23 static inline void
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
24 http_server_response_debug(struct http_server_response *resp,
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
25 const char *format, ...) ATTR_FORMAT(2, 3);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
26
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
27 static inline void
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
28 http_server_response_debug(struct http_server_response *resp,
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
29 const char *format, ...)
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
30 {
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
31 va_list args;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
32
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
33 if (resp->request->server->set.debug) {
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
34 va_start(args, format);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
35 i_debug("http-server: request %s; %u response: %s",
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
36 http_server_request_label(resp->request), resp->status,
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
37 t_strdup_vprintf(format, args));
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
38 va_end(args);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
39 }
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
40 }
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
41
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
42 /*
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
43 * Response
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
44 */
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
45
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
46 struct http_server_response *
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
47 http_server_response_create(struct http_server_request *req,
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
48 unsigned int status, const char *reason)
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
49 {
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
50 struct http_server_response *resp;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
51
19782
9d8d3589d2fb lib-http: server: Implicitly free a request response structure when a new (failure) response is started.
Stephan Bosch <stephan@rename-it.nl>
parents: 19761
diff changeset
52 if (req->response == NULL) {
9d8d3589d2fb lib-http: server: Implicitly free a request response structure when a new (failure) response is started.
Stephan Bosch <stephan@rename-it.nl>
parents: 19761
diff changeset
53 resp = req->response = p_new
9d8d3589d2fb lib-http: server: Implicitly free a request response structure when a new (failure) response is started.
Stephan Bosch <stephan@rename-it.nl>
parents: 19761
diff changeset
54 (req->pool, struct http_server_response, 1);
9d8d3589d2fb lib-http: server: Implicitly free a request response structure when a new (failure) response is started.
Stephan Bosch <stephan@rename-it.nl>
parents: 19761
diff changeset
55 } else {
9d8d3589d2fb lib-http: server: Implicitly free a request response structure when a new (failure) response is started.
Stephan Bosch <stephan@rename-it.nl>
parents: 19761
diff changeset
56 /* was already composing a response, but decided to
9d8d3589d2fb lib-http: server: Implicitly free a request response structure when a new (failure) response is started.
Stephan Bosch <stephan@rename-it.nl>
parents: 19761
diff changeset
57 start a new one (would usually be a failure response)
9d8d3589d2fb lib-http: server: Implicitly free a request response structure when a new (failure) response is started.
Stephan Bosch <stephan@rename-it.nl>
parents: 19761
diff changeset
58 */
9d8d3589d2fb lib-http: server: Implicitly free a request response structure when a new (failure) response is started.
Stephan Bosch <stephan@rename-it.nl>
parents: 19761
diff changeset
59 resp = req->response;
9d8d3589d2fb lib-http: server: Implicitly free a request response structure when a new (failure) response is started.
Stephan Bosch <stephan@rename-it.nl>
parents: 19761
diff changeset
60 i_assert(!resp->submitted);
9d8d3589d2fb lib-http: server: Implicitly free a request response structure when a new (failure) response is started.
Stephan Bosch <stephan@rename-it.nl>
parents: 19761
diff changeset
61 http_server_response_free(resp);
21389
59437f8764c6 global: Replaced all instances of memset(p, 0, sizeof(*p)) with the new i_zero() macro.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 20264
diff changeset
62 i_zero(resp);
19782
9d8d3589d2fb lib-http: server: Implicitly free a request response structure when a new (failure) response is started.
Stephan Bosch <stephan@rename-it.nl>
parents: 19761
diff changeset
63 }
17678
c9151da3a9b3 lib-http server: Added http_server_request_get_response()
Timo Sirainen <tss@iki.fi>
parents: 17676
diff changeset
64
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
65 resp->request = req;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
66 resp->status = status;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
67 resp->reason = p_strdup(req->pool, reason);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
68 resp->headers = str_new(default_pool, 256);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
69 resp->date = (time_t)-1;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
70
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
71 return resp;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
72 }
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
73
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
74 void http_server_response_free(struct http_server_response *resp)
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
75 {
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
76 http_server_response_debug(resp, "Destroy");
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
77
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
78 i_assert(!resp->payload_blocking);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
79
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
80 if (resp->payload_input != NULL)
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
81 i_stream_unref(&resp->payload_input);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
82 if (resp->payload_output != NULL)
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
83 o_stream_unref(&resp->payload_output);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
84 str_free(&resp->headers);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
85 }
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
86
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
87 void http_server_response_add_header(struct http_server_response *resp,
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
88 const char *key, const char *value)
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
89 {
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
90 i_assert(!resp->submitted);
17722
8e6d2afb14c5 lib-http: Added asserts to make sure CR or LF can't be added accidentally to HTTP headers.
Timo Sirainen <tss@iki.fi>
parents: 17678
diff changeset
91 i_assert(strchr(key, '\r') == NULL && strchr(key, '\n') == NULL);
8e6d2afb14c5 lib-http: Added asserts to make sure CR or LF can't be added accidentally to HTTP headers.
Timo Sirainen <tss@iki.fi>
parents: 17678
diff changeset
92 i_assert(strchr(value, '\r') == NULL && strchr(value, '\n') == NULL);
8e6d2afb14c5 lib-http: Added asserts to make sure CR or LF can't be added accidentally to HTTP headers.
Timo Sirainen <tss@iki.fi>
parents: 17678
diff changeset
93
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
94 /* mark presence of special headers */
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
95 switch (key[0]) {
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
96 case 'c': case 'C':
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
97 if (strcasecmp(key, "Connection") == 0)
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
98 resp->have_hdr_connection = TRUE;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
99 else if (strcasecmp(key, "Content-Length") == 0)
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
100 resp->have_hdr_body_spec = TRUE;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
101 break;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
102 case 'd': case 'D':
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
103 if (strcasecmp(key, "Date") == 0)
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
104 resp->have_hdr_date = TRUE;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
105 break;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
106 case 't': case 'T':
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
107 if (strcasecmp(key, "Transfer-Encoding") == 0)
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
108 resp->have_hdr_body_spec = TRUE;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
109 break;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
110 }
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
111 str_printfa(resp->headers, "%s: %s\r\n", key, value);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
112 }
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
113
19685
71627df01608 lib-http: Add function to update HTTP response status
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 19552
diff changeset
114 void http_server_response_update_status(struct http_server_response *resp,
71627df01608 lib-http: Add function to update HTTP response status
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 19552
diff changeset
115 unsigned int status,
71627df01608 lib-http: Add function to update HTTP response status
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 19552
diff changeset
116 const char *reason)
71627df01608 lib-http: Add function to update HTTP response status
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 19552
diff changeset
117 {
71627df01608 lib-http: Add function to update HTTP response status
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 19552
diff changeset
118 i_assert(!resp->submitted);
71627df01608 lib-http: Add function to update HTTP response status
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 19552
diff changeset
119 resp->status = status;
71627df01608 lib-http: Add function to update HTTP response status
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 19552
diff changeset
120 /* free not called because pool is alloconly */
71627df01608 lib-http: Add function to update HTTP response status
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 19552
diff changeset
121 resp->reason = p_strdup(resp->request->pool, reason);
71627df01608 lib-http: Add function to update HTTP response status
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 19552
diff changeset
122 }
71627df01608 lib-http: Add function to update HTTP response status
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 19552
diff changeset
123
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
124 void http_server_response_set_date(struct http_server_response *resp,
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
125 time_t date)
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
126 {
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
127 i_assert(!resp->submitted);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
128
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
129 resp->date = date;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
130 }
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
131
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
132 void http_server_response_set_payload(struct http_server_response *resp,
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
133 struct istream *input)
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
134 {
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
135 int ret;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
136
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
137 i_assert(!resp->submitted);
19747
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
138 i_assert(resp->blocking_output == NULL);
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
139 i_assert(resp->payload_input == NULL);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
140
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
141 i_stream_ref(input);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
142 resp->payload_input = input;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
143 if ((ret = i_stream_get_size(input, TRUE, &resp->payload_size)) <= 0) {
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
144 if (ret < 0) {
20264
0fd0fb05e2b3 global: Use [io]_stream_get_error() insted of %m
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 20186
diff changeset
145 i_error("i_stream_get_size(%s) failed: %s",
0fd0fb05e2b3 global: Use [io]_stream_get_error() insted of %m
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 20186
diff changeset
146 i_stream_get_name(input), i_stream_get_error(input));
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
147 }
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
148 resp->payload_size = 0;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
149 resp->payload_chunked = TRUE;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
150 }
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
151 resp->payload_offset = input->v_offset;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
152 }
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
153
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
154 void http_server_response_set_payload_data(struct http_server_response *resp,
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
155 const unsigned char *data, size_t size)
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
156 {
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
157 struct istream *input;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
158 unsigned char *payload_data;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
159
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
160 if (size == 0)
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
161 return;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
162
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
163 payload_data = p_malloc(resp->request->pool, size);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
164 memcpy(payload_data, data, size);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
165 input = i_stream_create_from_data(payload_data, size);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
166
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
167 http_server_response_set_payload(resp, input);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
168 i_stream_unref(&input);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
169 }
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
170
17772
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
171 void http_server_response_add_auth(
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
172 struct http_server_response *resp,
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
173 const struct http_auth_challenge *chlng)
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
174 {
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
175 struct http_auth_challenge *new;
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
176 pool_t pool = resp->request->pool;
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
177
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
178 if (!array_is_created(&resp->auth_challenges))
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
179 p_array_init(&resp->auth_challenges, pool, 4);
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
180
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
181 new = array_append_space(&resp->auth_challenges);
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
182 http_auth_challenge_copy(pool, new, chlng);
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
183 }
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
184
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
185 void http_server_response_add_auth_basic(
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
186 struct http_server_response *resp, const char *realm)
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
187 {
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
188 struct http_auth_challenge chlng;
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
189
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
190 http_auth_basic_challenge_init(&chlng, realm);
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
191 http_server_response_add_auth(resp, &chlng);
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
192 }
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
193
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
194 static void http_server_response_do_submit(struct http_server_response *resp,
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
195 bool close)
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
196 {
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
197 if (resp->date == (time_t)-1)
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
198 resp->date = ioloop_time;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
199 resp->close = close;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
200 resp->submitted = TRUE;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
201 http_server_request_submit_response(resp->request);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
202 }
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
203
17676
898d4cce2aa9 lib-http server: Removed "bool close" parameters in favor of _close() functions.
Timo Sirainen <tss@iki.fi>
parents: 17629
diff changeset
204 void http_server_response_submit(struct http_server_response *resp)
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
205 {
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
206 i_assert(!resp->submitted);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
207 http_server_response_debug(resp, "Submitted");
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
208
17676
898d4cce2aa9 lib-http server: Removed "bool close" parameters in favor of _close() functions.
Timo Sirainen <tss@iki.fi>
parents: 17629
diff changeset
209 http_server_response_do_submit(resp, FALSE);
898d4cce2aa9 lib-http server: Removed "bool close" parameters in favor of _close() functions.
Timo Sirainen <tss@iki.fi>
parents: 17629
diff changeset
210 }
898d4cce2aa9 lib-http server: Removed "bool close" parameters in favor of _close() functions.
Timo Sirainen <tss@iki.fi>
parents: 17629
diff changeset
211
898d4cce2aa9 lib-http server: Removed "bool close" parameters in favor of _close() functions.
Timo Sirainen <tss@iki.fi>
parents: 17629
diff changeset
212 void http_server_response_submit_close(struct http_server_response *resp)
898d4cce2aa9 lib-http server: Removed "bool close" parameters in favor of _close() functions.
Timo Sirainen <tss@iki.fi>
parents: 17629
diff changeset
213 {
898d4cce2aa9 lib-http server: Removed "bool close" parameters in favor of _close() functions.
Timo Sirainen <tss@iki.fi>
parents: 17629
diff changeset
214 i_assert(!resp->submitted);
898d4cce2aa9 lib-http server: Removed "bool close" parameters in favor of _close() functions.
Timo Sirainen <tss@iki.fi>
parents: 17629
diff changeset
215 http_server_response_debug(resp, "Submitted");
898d4cce2aa9 lib-http server: Removed "bool close" parameters in favor of _close() functions.
Timo Sirainen <tss@iki.fi>
parents: 17629
diff changeset
216
898d4cce2aa9 lib-http server: Removed "bool close" parameters in favor of _close() functions.
Timo Sirainen <tss@iki.fi>
parents: 17629
diff changeset
217 http_server_response_do_submit(resp, TRUE);
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
218 }
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
219
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
220 void http_server_response_submit_tunnel(struct http_server_response *resp,
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
221 http_server_tunnel_callback_t callback, void *context)
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
222 {
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
223 i_assert(!resp->submitted);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
224 http_server_response_debug(resp, "Started tunnelling");
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
225
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
226 resp->tunnel_callback = callback;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
227 resp->tunnel_context = context;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
228 http_server_response_do_submit(resp, TRUE);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
229 }
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
230
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
231 static void
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
232 http_server_response_finish_payload_out(struct http_server_response *resp)
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
233 {
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
234 struct http_server_connection *conn = resp->request->conn;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
235
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
236 if (resp->payload_output != NULL) {
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
237 o_stream_unref(&resp->payload_output);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
238 resp->payload_output = NULL;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
239 }
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
240
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
241 http_server_response_debug(resp, "Finished sending payload");
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
242
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
243 conn->output_locked = FALSE;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
244 if (resp->payload_corked)
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
245 o_stream_uncork(conn->conn.output);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
246 o_stream_set_flush_callback(conn->conn.output,
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
247 http_server_connection_output, conn);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
248
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
249 http_server_request_finished(resp->request);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
250 }
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
251
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
252 static int
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
253 http_server_response_output_direct(struct http_server_response_payload *rpay)
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
254 {
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
255 struct http_server_response *resp = rpay->resp;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
256 struct http_server_connection *conn = resp->request->conn;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
257 struct http_server *server = resp->request->server;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
258 struct ostream *output = resp->payload_output;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
259 struct const_iovec *iov;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
260 unsigned int iov_count, i;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
261 size_t bytes_left, block_len;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
262 ssize_t ret;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
263
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
264 if (http_server_connection_flush(conn) < 0)
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
265 return -1;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
266
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
267 iov = &rpay->iov[rpay->iov_idx];
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
268 iov_count = rpay->iov_count - rpay->iov_idx;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
269
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
270 if ((ret=o_stream_sendv(output, iov, iov_count)) < 0) {
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
271 const char *error = NULL;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
272
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
273 if (output->stream_errno != EPIPE &&
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
274 output->stream_errno != ECONNRESET) {
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
275 error = t_strdup_printf("write(%s) failed: %s",
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
276 o_stream_get_name(output),
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
277 o_stream_get_error(output));
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
278 }
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
279 http_server_connection_write_failed(conn, error);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
280 return -1;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
281 }
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
282 if (ret > 0) {
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
283 bytes_left = ret;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
284 for (i = 0; i < iov_count && bytes_left > 0; i++) {
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
285 block_len = iov[i].iov_len <= bytes_left ?
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
286 iov[i].iov_len : bytes_left;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
287 bytes_left -= block_len;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
288 }
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
289 rpay->iov_idx += i;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
290 if (i < iov_count) {
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
291 i_assert(iov[i].iov_len > bytes_left);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
292 iov[i].iov_base = PTR_OFFSET
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
293 (iov[i].iov_base, iov[i].iov_len - bytes_left);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
294 iov[i].iov_len = bytes_left;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
295 } else {
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
296 i_assert(rpay->iov_idx == rpay->iov_count);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
297 i_assert(server->ioloop != NULL);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
298 io_loop_stop(server->ioloop);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
299 }
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
300 }
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
301 return 1;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
302 }
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
303
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
304 static int
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
305 http_server_response_output_payload(
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
306 struct http_server_response **_resp,
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
307 const struct const_iovec *iov, unsigned int iov_count)
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
308 {
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
309 struct ioloop *prev_ioloop = current_ioloop;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
310 struct http_server_response *resp = *_resp;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
311 struct http_server_request *req = resp->request;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
312 struct http_server *server = req->server;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
313 struct http_server_connection *conn = req->conn;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
314 struct http_server_response_payload rpay;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
315 int ret;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
316
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
317 i_assert(req->state < HTTP_SERVER_REQUEST_STATE_SUBMITTED_RESPONSE ||
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
318 req->state == HTTP_SERVER_REQUEST_STATE_PAYLOAD_OUT);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
319 i_assert(resp->payload_input == NULL);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
320
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
321 /* Discard any remaining incoming payload */
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
322 if (http_server_connection_discard_payload(conn) < 0)
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
323 return -1;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
324 req->req.payload = NULL;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
325
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
326 http_server_connection_ref(conn);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
327 http_server_request_ref(req);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
328 resp->payload_blocking = TRUE;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
329
21389
59437f8764c6 global: Replaced all instances of memset(p, 0, sizeof(*p)) with the new i_zero() macro.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 20264
diff changeset
330 i_zero(&rpay);
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
331 rpay.resp = resp;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
332
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
333 if (iov == NULL) {
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
334 resp->payload_direct = FALSE;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
335 if (req->state == HTTP_SERVER_REQUEST_STATE_PAYLOAD_OUT)
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
336 http_server_response_finish_payload_out(resp);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
337 } else {
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
338 resp->payload_direct = TRUE;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
339 rpay.iov = i_new(struct const_iovec, iov_count);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
340 memcpy(rpay.iov, iov, sizeof(*iov)*iov_count);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
341 rpay.iov_count = iov_count;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
342 }
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
343
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
344 resp->payload_size = 0;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
345 resp->payload_chunked = TRUE;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
346
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
347 if (req->state < HTTP_SERVER_REQUEST_STATE_SUBMITTED_RESPONSE)
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
348 http_server_response_submit(resp);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
349
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
350 if (req->state < HTTP_SERVER_REQUEST_STATE_FINISHED) {
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
351 /* Wait for payload data to be written */
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
352
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
353 i_assert(server->ioloop == NULL);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
354 server->ioloop = io_loop_create();
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
355 http_server_connection_switch_ioloop(conn);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
356
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
357 do {
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
358 if (req->state < HTTP_SERVER_REQUEST_STATE_PAYLOAD_OUT) {
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
359 http_server_response_debug(resp,
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
360 "Preparing to send blocking payload");
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
361 http_server_connection_trigger_responses(conn);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
362
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
363 } else if (resp->payload_output != NULL) {
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
364 http_server_response_debug(resp,
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
365 "Sending blocking payload");
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
366 o_stream_unset_flush_callback(conn->conn.output);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
367 o_stream_set_flush_callback(resp->payload_output,
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
368 http_server_response_output_direct, &rpay);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
369 o_stream_set_flush_pending(resp->payload_output, TRUE);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
370
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
371 } else {
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
372 http_server_response_finish_payload_out(resp);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
373 i_assert(req->state >= HTTP_SERVER_REQUEST_STATE_FINISHED);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
374 break;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
375 }
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
376
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
377 io_loop_run(server->ioloop);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
378
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
379 if (rpay.iov_count > 0 && rpay.iov_idx >= rpay.iov_count)
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
380 break;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
381 } while (req->state < HTTP_SERVER_REQUEST_STATE_FINISHED);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
382
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
383 io_loop_set_current(prev_ioloop);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
384 http_server_connection_switch_ioloop(conn);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
385 io_loop_set_current(server->ioloop);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
386 io_loop_destroy(&server->ioloop);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
387 }
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
388
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
389 switch (req->state) {
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
390 case HTTP_SERVER_REQUEST_STATE_FINISHED:
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
391 ret = 1;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
392 break;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
393 case HTTP_SERVER_REQUEST_STATE_ABORTED:
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
394 http_server_response_debug(resp,
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
395 "Request aborted while sending blocking payload");
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
396 ret = -1;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
397 break;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
398 default:
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
399 ret = 0;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
400 break;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
401 }
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
402
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
403 resp->payload_blocking = FALSE;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
404 resp->payload_direct = FALSE;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
405
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
406 /* callback may have messed with our pointer,
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
407 so unref using local variable */
19819
c1a959cba67a lib-http: http_server_request_unref() now always sets *req=NULL
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19782
diff changeset
408 if (!http_server_request_unref(&req))
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
409 *_resp = NULL;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
410
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
411 http_server_connection_unref(&conn);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
412 i_free(rpay.iov);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
413
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
414 /* Return status */
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
415 return ret;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
416 }
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
417
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
418 int http_server_response_send_payload(struct http_server_response **_resp,
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
419 const unsigned char *data, size_t size)
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
420 {
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
421 struct http_server_response *resp = *_resp;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
422 struct const_iovec iov;
19820
a0e487d9c6f9 lib-http: Clarify http_server_response_*_payload() API and minor change to it
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19819
diff changeset
423 int ret;
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
424
19747
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
425 i_assert(resp->blocking_output == NULL);
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
426
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
427 resp->payload_corked = TRUE;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
428
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
429 i_assert(data != NULL);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
430
21389
59437f8764c6 global: Replaced all instances of memset(p, 0, sizeof(*p)) with the new i_zero() macro.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 20264
diff changeset
431 i_zero(&iov);
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
432 iov.iov_base = data;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
433 iov.iov_len = size;
19820
a0e487d9c6f9 lib-http: Clarify http_server_response_*_payload() API and minor change to it
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19819
diff changeset
434 ret = http_server_response_output_payload(&resp, &iov, 1);
a0e487d9c6f9 lib-http: Clarify http_server_response_*_payload() API and minor change to it
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19819
diff changeset
435 if (ret < 0)
a0e487d9c6f9 lib-http: Clarify http_server_response_*_payload() API and minor change to it
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19819
diff changeset
436 *_resp = NULL;
a0e487d9c6f9 lib-http: Clarify http_server_response_*_payload() API and minor change to it
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19819
diff changeset
437 else {
a0e487d9c6f9 lib-http: Clarify http_server_response_*_payload() API and minor change to it
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19819
diff changeset
438 i_assert(ret == 0);
a0e487d9c6f9 lib-http: Clarify http_server_response_*_payload() API and minor change to it
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19819
diff changeset
439 i_assert(resp != NULL);
a0e487d9c6f9 lib-http: Clarify http_server_response_*_payload() API and minor change to it
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19819
diff changeset
440 }
a0e487d9c6f9 lib-http: Clarify http_server_response_*_payload() API and minor change to it
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19819
diff changeset
441 return ret;
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
442 }
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
443
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
444 int http_server_response_finish_payload(struct http_server_response **_resp)
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
445 {
19747
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
446 struct http_server_response *resp = *_resp;
19820
a0e487d9c6f9 lib-http: Clarify http_server_response_*_payload() API and minor change to it
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19819
diff changeset
447 int ret;
19747
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
448
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
449 i_assert(resp->blocking_output == NULL);
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
450
19820
a0e487d9c6f9 lib-http: Clarify http_server_response_*_payload() API and minor change to it
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19819
diff changeset
451 *_resp = NULL;
a0e487d9c6f9 lib-http: Clarify http_server_response_*_payload() API and minor change to it
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19819
diff changeset
452 ret = http_server_response_output_payload(&resp, NULL, 0);
a0e487d9c6f9 lib-http: Clarify http_server_response_*_payload() API and minor change to it
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19819
diff changeset
453 i_assert(ret != 0);
a0e487d9c6f9 lib-http: Clarify http_server_response_*_payload() API and minor change to it
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19819
diff changeset
454 return ret < 0 ? -1 : 0;
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
455 }
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
456
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
457 void http_server_response_abort_payload(struct http_server_response **_resp)
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
458 {
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
459 struct http_server_response *resp = *_resp;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
460 struct http_server_request *req = resp->request;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
461
19822
554ef83e133c lib-http: Always set *_obj=NULL first in deinit functions (mainly for consistency)
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19820
diff changeset
462 *_resp = NULL;
554ef83e133c lib-http: Always set *_obj=NULL first in deinit functions (mainly for consistency)
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19820
diff changeset
463
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
464 http_server_request_abort(&req,
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
465 "Aborted sending response payload");
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
466 }
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
467
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
468 static void
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
469 http_server_response_payload_input(struct http_server_response *resp)
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
470 {
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
471 struct http_server_connection *conn = resp->request->conn;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
472
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
473 if (conn->io_resp_payload != NULL)
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
474 io_remove(&conn->io_resp_payload);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
475
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
476 (void)http_server_connection_output(conn);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
477 }
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
478
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
479 int http_server_response_send_more(struct http_server_response *resp,
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
480 const char **error_r)
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
481 {
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
482 struct http_server_connection *conn = resp->request->conn;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
483 struct ostream *output = resp->payload_output;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
484 off_t ret;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
485
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
486 *error_r = NULL;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
487
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
488 i_assert(!resp->payload_blocking);
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
489 i_assert(resp->payload_input != NULL);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
490 i_assert(resp->payload_output != NULL);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
491
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
492 if (conn->io_resp_payload != NULL)
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
493 io_remove(&conn->io_resp_payload);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
494
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
495 /* chunked ostream needs to write to the parent stream's buffer */
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
496 o_stream_set_max_buffer_size(output, IO_BLOCK_SIZE);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
497 ret = o_stream_send_istream(output, resp->payload_input);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
498 o_stream_set_max_buffer_size(output, (size_t)-1);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
499
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
500 if (resp->payload_input->stream_errno != 0) {
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
501 /* we're in the middle of sending a response, so the connection
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
502 will also have to be aborted */
20264
0fd0fb05e2b3 global: Use [io]_stream_get_error() insted of %m
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 20186
diff changeset
503 *error_r = t_strdup_printf("read(%s) failed: %s",
0fd0fb05e2b3 global: Use [io]_stream_get_error() insted of %m
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 20186
diff changeset
504 i_stream_get_name(resp->payload_input),
0fd0fb05e2b3 global: Use [io]_stream_get_error() insted of %m
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 20186
diff changeset
505 i_stream_get_error(resp->payload_input));
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
506 ret = -1;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
507 } else if (output->stream_errno != 0) {
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
508 /* failed to send response */
20264
0fd0fb05e2b3 global: Use [io]_stream_get_error() insted of %m
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 20186
diff changeset
509 if (output->stream_errno != EPIPE &&
0fd0fb05e2b3 global: Use [io]_stream_get_error() insted of %m
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 20186
diff changeset
510 output->stream_errno != ECONNRESET) {
0fd0fb05e2b3 global: Use [io]_stream_get_error() insted of %m
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 20186
diff changeset
511 *error_r = t_strdup_printf("write(%s) failed: %s",
0fd0fb05e2b3 global: Use [io]_stream_get_error() insted of %m
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 20186
diff changeset
512 o_stream_get_name(output), o_stream_get_error(output));
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
513 }
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
514 ret = -1;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
515 } else {
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
516 i_assert(ret >= 0);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
517 }
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
518
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
519 if (ret < 0 || i_stream_is_eof(resp->payload_input)) {
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
520 /* finished sending */
18023
5cd30ecff35d lib-http server: If i/ostream fails, don't return wrong "stream input size changed" error.
Timo Sirainen <tss@iki.fi>
parents: 17797
diff changeset
521 if (ret >= 0 && !resp->payload_chunked &&
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
522 resp->payload_input->v_offset - resp->payload_offset !=
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
523 resp->payload_size) {
18023
5cd30ecff35d lib-http server: If i/ostream fails, don't return wrong "stream input size changed" error.
Timo Sirainen <tss@iki.fi>
parents: 17797
diff changeset
524 *error_r = t_strdup_printf(
5cd30ecff35d lib-http server: If i/ostream fails, don't return wrong "stream input size changed" error.
Timo Sirainen <tss@iki.fi>
parents: 17797
diff changeset
525 "Input stream %s size changed unexpectedly",
5cd30ecff35d lib-http server: If i/ostream fails, don't return wrong "stream input size changed" error.
Timo Sirainen <tss@iki.fi>
parents: 17797
diff changeset
526 i_stream_get_name(resp->payload_input));
5cd30ecff35d lib-http server: If i/ostream fails, don't return wrong "stream input size changed" error.
Timo Sirainen <tss@iki.fi>
parents: 17797
diff changeset
527 ret = -1;
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
528 }
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
529 /* finished sending payload */
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
530 http_server_response_finish_payload_out(resp);
20186
e4cbb2c587ad lib-http: Fixed checking if istream or ostream needs waiting.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19822
diff changeset
531 } else if (i_stream_have_bytes_left(resp->payload_input)) {
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
532 /* output is blocking */
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
533 conn->output_locked = TRUE;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
534 o_stream_set_flush_pending(output, TRUE);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
535 //http_server_response_debug(resp, "Partially sent payload");
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
536 } else {
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
537 /* input is blocking */
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
538 conn->output_locked = TRUE;
17723
74e5657964d3 lib-http server: Use io_add_istream() to wait for the payload istream.
Timo Sirainen <tss@iki.fi>
parents: 17722
diff changeset
539 conn->io_resp_payload = io_add_istream(resp->payload_input,
74e5657964d3 lib-http server: Use io_add_istream() to wait for the payload istream.
Timo Sirainen <tss@iki.fi>
parents: 17722
diff changeset
540 http_server_response_payload_input, resp);
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
541 }
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
542 return ret < 0 ? -1 : 0;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
543 }
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
544
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
545 static int http_server_response_send_real(struct http_server_response *resp,
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
546 const char **error_r)
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
547 {
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
548 struct http_server_request *req = resp->request;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
549 struct http_server_connection *conn = req->conn;
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
550 struct http_server *server = req->server;
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
551 struct ostream *output = conn->conn.output;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
552 string_t *rtext = t_str_new(256);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
553 struct const_iovec iov[3];
21409
1d5160a7b0fd lib-http: server: Prevent sending response payload when it is not allowed by the specification.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21390
diff changeset
554 bool is_head = http_request_method_is(&req->req, "HEAD");
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
555 int ret = 0;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
556
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
557 *error_r = NULL;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
558
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
559 i_assert(!conn->output_locked);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
560
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
561 /* create status line */
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
562 str_append(rtext, "HTTP/1.1 ");
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
563 str_printfa(rtext, "%u", resp->status);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
564 str_append(rtext, " ");
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
565 str_append(rtext, resp->reason);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
566
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
567 /* create special headers implicitly if not set explicitly using
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
568 http_server_response_add_header() */
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
569 if (!resp->have_hdr_date) {
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
570 str_append(rtext, "\r\nDate: ");
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
571 str_append(rtext, http_date_create(resp->date));
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
572 str_append(rtext, "\r\n");
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
573 }
17772
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
574 if (array_is_created(&resp->auth_challenges)) {
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
575 str_append(rtext, "WWW-Authenticate: ");
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
576 http_auth_create_challenges(rtext, &resp->auth_challenges);
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
577 str_append(rtext, "\r\n");
5ab0ab678497 lib-http: server: Added support for authentication.
Stephan Bosch <stephan@rename-it.nl>
parents: 17723
diff changeset
578 }
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
579 if (resp->payload_input != NULL || resp->payload_direct) {
21409
1d5160a7b0fd lib-http: server: Prevent sending response payload when it is not allowed by the specification.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21390
diff changeset
580 i_assert(resp->tunnel_callback == NULL && resp->status / 100 != 1 &&
1d5160a7b0fd lib-http: server: Prevent sending response payload when it is not allowed by the specification.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21390
diff changeset
581 resp->status != 204 && resp->status != 304);
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
582 if (resp->payload_chunked) {
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
583 if (http_server_request_version_equals(req, 1, 0)) {
21409
1d5160a7b0fd lib-http: server: Prevent sending response payload when it is not allowed by the specification.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21390
diff changeset
584 if (!is_head) {
1d5160a7b0fd lib-http: server: Prevent sending response payload when it is not allowed by the specification.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21390
diff changeset
585 /* cannot use Transfer-Encoding */
1d5160a7b0fd lib-http: server: Prevent sending response payload when it is not allowed by the specification.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21390
diff changeset
586 resp->payload_output = output;
1d5160a7b0fd lib-http: server: Prevent sending response payload when it is not allowed by the specification.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21390
diff changeset
587 o_stream_ref(output);
1d5160a7b0fd lib-http: server: Prevent sending response payload when it is not allowed by the specification.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21390
diff changeset
588 /* connection close marks end of payload */
1d5160a7b0fd lib-http: server: Prevent sending response payload when it is not allowed by the specification.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21390
diff changeset
589 resp->close = TRUE;
1d5160a7b0fd lib-http: server: Prevent sending response payload when it is not allowed by the specification.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21390
diff changeset
590 }
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
591 } else {
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
592 if (!resp->have_hdr_body_spec)
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
593 str_append(rtext, "Transfer-Encoding: chunked\r\n");
21409
1d5160a7b0fd lib-http: server: Prevent sending response payload when it is not allowed by the specification.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21390
diff changeset
594 if (!is_head) {
1d5160a7b0fd lib-http: server: Prevent sending response payload when it is not allowed by the specification.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21390
diff changeset
595 resp->payload_output =
1d5160a7b0fd lib-http: server: Prevent sending response payload when it is not allowed by the specification.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21390
diff changeset
596 http_transfer_chunked_ostream_create(output);
1d5160a7b0fd lib-http: server: Prevent sending response payload when it is not allowed by the specification.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21390
diff changeset
597 }
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
598 }
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
599 } else {
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
600 /* send Content-Length if we have specified a payload,
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
601 even if it's 0 bytes. */
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
602 if (!resp->have_hdr_body_spec) {
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
603 str_printfa(rtext, "Content-Length: %"PRIuUOFF_T"\r\n",
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
604 resp->payload_size);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
605 }
21409
1d5160a7b0fd lib-http: server: Prevent sending response payload when it is not allowed by the specification.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21390
diff changeset
606 if (!is_head) {
1d5160a7b0fd lib-http: server: Prevent sending response payload when it is not allowed by the specification.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21390
diff changeset
607 resp->payload_output = output;
1d5160a7b0fd lib-http: server: Prevent sending response payload when it is not allowed by the specification.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21390
diff changeset
608 o_stream_ref(output);
1d5160a7b0fd lib-http: server: Prevent sending response payload when it is not allowed by the specification.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21390
diff changeset
609 }
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
610 }
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
611 } else if (resp->tunnel_callback == NULL && resp->status / 100 != 1
21409
1d5160a7b0fd lib-http: server: Prevent sending response payload when it is not allowed by the specification.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21390
diff changeset
612 && resp->status != 204 && resp->status != 304 && !is_head) {
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
613 /* RFC 7230, Section 3.3: Message Body
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
614
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
615 Responses to the HEAD request method (Section 4.3.2 of [RFC7231])
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
616 never include a message body because the associated response header
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
617 fields (e.g., Transfer-Encoding, Content-Length, etc.), if present,
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
618 indicate only what their values would have been if the request method
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
619 had been GET (Section 4.3.1 of [RFC7231]). 2xx (Successful) responses
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
620 to a CONNECT request method (Section 4.3.6 of [RFC7231]) switch to
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
621 tunnel mode instead of having a message body. All 1xx (Informational),
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
622 204 (No Content), and 304 (Not Modified) responses do not include a
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
623 message body. All other responses do include a message body, although
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
624 the body might be of zero length.
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
625
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
626 RFC 7230, Section 3.3.2: Content-Length
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
627
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
628 A server MUST NOT send a Content-Length header field in any 2xx
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
629 (Successful) response to a CONNECT request (Section 4.3.6 of [RFC7231]).
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
630
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
631 -> Create empty body if it is missing.
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
632 */
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
633 if (!resp->have_hdr_body_spec)
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
634 str_append(rtext, "Content-Length: 0\r\n");
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
635 }
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
636 if (!resp->have_hdr_connection) {
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
637 if (resp->close && resp->tunnel_callback == NULL)
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
638 str_append(rtext, "Connection: close\r\n");
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
639 else if (http_server_request_version_equals(req, 1, 0))
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
640 str_append(rtext, "Connection: Keep-Alive\r\n");
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
641 }
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
642
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
643 /* status line + implicit headers */
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
644 iov[0].iov_base = str_data(rtext);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
645 iov[0].iov_len = str_len(rtext);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
646 /* explicit headers */
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
647 iov[1].iov_base = str_data(resp->headers);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
648 iov[1].iov_len = str_len(resp->headers);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
649 /* end of header */
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
650 iov[2].iov_base = "\r\n";
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
651 iov[2].iov_len = 2;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
652
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
653 req->state = HTTP_SERVER_REQUEST_STATE_PAYLOAD_OUT;
17797
736a3f6bd5a8 lib-http server: Keep output stream referenced to avoid accessing it after destroy.
Timo Sirainen <tss@iki.fi>
parents: 17772
diff changeset
654 o_stream_ref(output);
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
655 o_stream_cork(output);
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
656 if (o_stream_sendv(output, iov, N_ELEMENTS(iov)) < 0) {
20264
0fd0fb05e2b3 global: Use [io]_stream_get_error() insted of %m
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 20186
diff changeset
657 if (output->stream_errno != EPIPE &&
0fd0fb05e2b3 global: Use [io]_stream_get_error() insted of %m
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 20186
diff changeset
658 output->stream_errno != ECONNRESET) {
0fd0fb05e2b3 global: Use [io]_stream_get_error() insted of %m
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 20186
diff changeset
659 *error_r = t_strdup_printf("write(%s) failed: %s",
0fd0fb05e2b3 global: Use [io]_stream_get_error() insted of %m
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 20186
diff changeset
660 o_stream_get_name(output), o_stream_get_error(output));
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
661 }
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
662 ret = -1;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
663 }
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
664
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
665 if (ret >= 0) {
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
666 http_server_response_debug(resp, "Sent header");
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
667
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
668 if (resp->payload_blocking) {
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
669 /* blocking payload */
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
670 conn->output_locked = TRUE;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
671 if (server->ioloop != NULL)
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
672 io_loop_stop(server->ioloop);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
673 } else if (resp->payload_output != NULL) {
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
674 /* non-blocking payload */
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
675 if (http_server_response_send_more(resp, error_r) < 0)
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
676 ret = -1;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
677 } else {
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
678 /* no payload to send */
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
679 conn->output_locked = FALSE;
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
680 http_server_response_finish_payload_out(resp);
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
681 }
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
682 }
19746
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
683 if (!resp->payload_corked)
7527051eb56a lib-http: server: Created blocking http_server_response_send_payload() API that closely mimics the client equivalent.
Stephan Bosch <stephan@rename-it.nl>
parents: 19729
diff changeset
684 o_stream_uncork(output);
17797
736a3f6bd5a8 lib-http server: Keep output stream referenced to avoid accessing it after destroy.
Timo Sirainen <tss@iki.fi>
parents: 17772
diff changeset
685 o_stream_unref(&output);
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
686 return ret;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
687 }
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
688
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
689 int http_server_response_send(struct http_server_response *resp,
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
690 const char **error_r)
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
691 {
19729
283300040a6e lib-http: server: Fixed datastack framing problem in error handling of response sending.
Stephan Bosch <stephan@rename-it.nl>
parents: 19685
diff changeset
692 char *errstr = NULL;
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
693 int ret;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
694
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
695 T_BEGIN {
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
696 ret = http_server_response_send_real(resp, error_r);
19729
283300040a6e lib-http: server: Fixed datastack framing problem in error handling of response sending.
Stephan Bosch <stephan@rename-it.nl>
parents: 19685
diff changeset
697 if (ret < 0)
283300040a6e lib-http: server: Fixed datastack framing problem in error handling of response sending.
Stephan Bosch <stephan@rename-it.nl>
parents: 19685
diff changeset
698 errstr = i_strdup(*error_r);
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
699 } T_END;
19729
283300040a6e lib-http: server: Fixed datastack framing problem in error handling of response sending.
Stephan Bosch <stephan@rename-it.nl>
parents: 19685
diff changeset
700 *error_r = t_strdup(errstr);
283300040a6e lib-http: server: Fixed datastack framing problem in error handling of response sending.
Stephan Bosch <stephan@rename-it.nl>
parents: 19685
diff changeset
701 i_free(errstr);
17629
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
702 return ret;
edcbd75b76ba lib-http: Added initial support for server-side HTTP API.
Stephan Bosch <stephan@rename-it.nl>
parents:
diff changeset
703 }
19747
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
704
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
705 /*
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
706 * Payload output stream
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
707 */
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
708
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
709 struct http_server_ostream {
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
710 struct ostream_private ostream;
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
711
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
712 struct http_server_response *resp;
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
713 };
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
714
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
715 static ssize_t
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
716 http_server_ostream_sendv(struct ostream_private *stream,
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
717 const struct const_iovec *iov, unsigned int iov_count)
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
718 {
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
719 struct http_server_ostream *hsostream =
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
720 (struct http_server_ostream *)stream;
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
721 unsigned int i;
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
722 ssize_t ret;
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
723
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
724 if (http_server_response_output_payload
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
725 (&hsostream->resp, iov, iov_count) < 0) {
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
726 if (stream->parent->stream_errno != 0) {
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
727 o_stream_copy_error_from_parent(stream);
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
728 } else {
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
729 io_stream_set_error(&stream->iostream,
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
730 "HTTP connection broke while sending payload");
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
731 stream->ostream.stream_errno = EIO;
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
732 }
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
733 return -1;
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
734 }
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
735
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
736 ret = 0;
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
737 for (i = 0; i < iov_count; i++)
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
738 ret += iov[i].iov_len;
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
739 stream->ostream.offset += ret;
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
740 return ret;
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
741 }
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
742
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
743 static void http_server_ostream_close(struct iostream_private *stream,
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
744 bool close_parent ATTR_UNUSED)
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
745 {
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
746 struct http_server_ostream *hsostream =
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
747 (struct http_server_ostream *)stream;
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
748 struct ostream_private *ostream = &hsostream->ostream;
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
749
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
750 if (hsostream->resp == NULL)
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
751 return;
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
752 hsostream->resp->blocking_output = NULL;
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
753
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
754 if (http_server_response_output_payload
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
755 (&hsostream->resp, NULL, 0) < 0) {
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
756 if (ostream->parent->stream_errno != 0) {
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
757 o_stream_copy_error_from_parent(ostream);
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
758 } else {
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
759 io_stream_set_error(&ostream->iostream,
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
760 "HTTP connection broke while sending payload");
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
761 ostream->ostream.stream_errno = EIO;
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
762 }
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
763 }
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
764 hsostream->resp = NULL;
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
765 }
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
766
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
767 static void http_server_ostream_destroy(struct iostream_private *stream)
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
768 {
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
769 struct http_server_ostream *hsostream =
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
770 (struct http_server_ostream *)stream;
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
771
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
772 if (hsostream->resp != NULL) {
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
773 hsostream->resp->blocking_output = NULL;
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
774 http_server_response_abort_payload(&hsostream->resp);
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
775 }
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
776 }
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
777
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
778 struct ostream *
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
779 http_server_response_get_payload_output(struct http_server_response *resp,
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
780 bool blocking)
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
781 {
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
782 struct http_server_connection *conn = resp->request->conn;
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
783 struct http_server_ostream *hsostream;
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
784
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
785 i_assert(resp->payload_input == NULL);
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
786 i_assert(resp->blocking_output == NULL);
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
787
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
788 i_assert(blocking == TRUE); // FIXME: support non-blocking
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
789
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
790 hsostream = i_new(struct http_server_ostream, 1);
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
791 hsostream->ostream.sendv = http_server_ostream_sendv;
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
792 hsostream->ostream.iostream.close = http_server_ostream_close;
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
793 hsostream->ostream.iostream.destroy = http_server_ostream_destroy;
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
794 hsostream->resp = resp;
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
795
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
796 resp->blocking_output =
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
797 o_stream_create(&hsostream->ostream, conn->conn.output, -1);
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
798 return resp->blocking_output;
36963988e4f8 lib-http: server: Implemented blocking response output stream.
Stephan Bosch <stephan@rename-it.nl>
parents: 19746
diff changeset
799 }
19761
52a0e0fcf910 lib-http: Add accessors for some response details
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 19747
diff changeset
800
52a0e0fcf910 lib-http: Add accessors for some response details
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 19747
diff changeset
801 void http_server_response_get_status(struct http_server_response *resp,
52a0e0fcf910 lib-http: Add accessors for some response details
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 19747
diff changeset
802 int *status_r, const char **reason_r)
52a0e0fcf910 lib-http: Add accessors for some response details
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 19747
diff changeset
803 {
52a0e0fcf910 lib-http: Add accessors for some response details
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 19747
diff changeset
804 i_assert(resp != NULL);
52a0e0fcf910 lib-http: Add accessors for some response details
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 19747
diff changeset
805 *status_r = resp->status;
52a0e0fcf910 lib-http: Add accessors for some response details
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 19747
diff changeset
806 *reason_r = resp->reason;
52a0e0fcf910 lib-http: Add accessors for some response details
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 19747
diff changeset
807 }
52a0e0fcf910 lib-http: Add accessors for some response details
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 19747
diff changeset
808
52a0e0fcf910 lib-http: Add accessors for some response details
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 19747
diff changeset
809 uoff_t http_server_response_get_total_size(struct http_server_response *resp)
52a0e0fcf910 lib-http: Add accessors for some response details
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 19747
diff changeset
810 {
52a0e0fcf910 lib-http: Add accessors for some response details
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 19747
diff changeset
811 i_assert(resp != NULL);
52a0e0fcf910 lib-http: Add accessors for some response details
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 19747
diff changeset
812 return resp->payload_size + str_len(resp->headers);
52a0e0fcf910 lib-http: Add accessors for some response details
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 19747
diff changeset
813 }