Apache HTTPD
md_http.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <assert.h>
18
19#include <apr_lib.h>
20#include <apr_strings.h>
21#include <apr_buckets.h>
22
23#include "md_http.h"
24#include "md_log.h"
25#include "md_util.h"
26
27struct md_http_t {
33 void *impl_data; /* to be used by the implementation */
34 const char *user_agent;
35 const char *proxy_url;
36 const char *unix_socket_path;
38 const char *ca_file;
39};
40
42static int cur_init_done;
43
51
53{
54 md_http_t *http = data;
55 if (http && http->impl && http->impl->cleanup) {
56 http->impl->cleanup(http, http->pool);
57 }
58 return APR_SUCCESS;
59}
60
62 const char *proxy_url)
63{
64 md_http_t *http;
66
67 if (!cur_impl) {
68 *phttp = NULL;
69 return APR_ENOTIMPL;
70 }
71
72 if (!cur_init_done) {
73 if (APR_SUCCESS == (rv = cur_impl->init())) {
74 cur_init_done = 1;
75 }
76 else {
77 return rv;
78 }
79 }
80
81 http = apr_pcalloc(p, sizeof(*http));
82 http->pool = p;
83 http->impl = cur_impl;
84 http->user_agent = apr_pstrdup(p, user_agent);
85 http->proxy_url = proxy_url? apr_pstrdup(p, proxy_url) : NULL;
87 if (!http->bucket_alloc) {
88 return APR_EGENERAL;
89 }
91 *phttp = http;
92 return APR_SUCCESS;
93}
94
97{
98 apr_status_t rv;
99
100 rv = md_http_create(phttp, p, source_http->user_agent, source_http->proxy_url);
101 if (APR_SUCCESS == rv) {
102 (*phttp)->resp_limit = source_http->resp_limit;
103 (*phttp)->timeout = source_http->timeout;
104 if (source_http->unix_socket_path) {
105 (*phttp)->unix_socket_path = apr_pstrdup(p, source_http->unix_socket_path);
106 }
107 if (source_http->ca_file) {
108 (*phttp)->ca_file = apr_pstrdup(p, source_http->ca_file);
109 }
110 }
111 return rv;
112}
113
115{
116 http->impl_data = data;
117}
118
120{
121 return http->impl_data;
122}
123
125{
126 http->resp_limit = resp_limit;
127}
128
133
138
143
148
154
160
161void md_http_set_ca_file(md_http_t *http, const char *ca_file)
162{
163 http->ca_file = ca_file;
164}
165
167{
168 http->unix_socket_path = path;
169}
170
172 apr_bucket_brigade *body, apr_off_t body_len,
173 int detect_len)
174{
176
177 if (body && detect_len) {
178 rv = apr_brigade_length(body, 1, &body_len);
179 if (rv != APR_SUCCESS) {
180 return rv;
181 }
182 }
183
184 req->body = body;
185 req->body_len = body? body_len : 0;
186 if (content_type) {
187 apr_table_set(req->headers, "Content-Type", content_type);
188 }
189 else {
190 apr_table_unset(req->headers, "Content-Type");
191 }
192 return rv;
193}
194
196 const md_data_t *body)
197{
199 apr_status_t rv;
200
201 if (body && body->len > 0) {
203 rv = apr_brigade_write(bbody, NULL, NULL, body->data, body->len);
204 if (rv != APR_SUCCESS) {
205 return rv;
206 }
207 }
208 return req_set_body(req, content_type, bbody, body? (apr_off_t)body->len : 0, 0);
209}
210
212 const char *method, const char *url,
213 struct apr_table_t *headers)
214{
217 apr_status_t rv;
218
219 rv = apr_pool_create(&pool, http->pool);
220 if (rv != APR_SUCCESS) {
221 return rv;
222 }
223 apr_pool_tag(pool, "md_http_req");
224
225 req = apr_pcalloc(pool, sizeof(*req));
226 req->pool = pool;
227 req->id = http->next_id++;
228 req->bucket_alloc = http->bucket_alloc;
229 req->http = http;
230 req->method = method;
231 req->url = url;
232 req->headers = headers? apr_table_copy(req->pool, headers) : apr_table_make(req->pool, 5);
233 req->resp_limit = http->resp_limit;
234 req->user_agent = http->user_agent;
235 req->proxy_url = http->proxy_url;
236 req->timeout = http->timeout;
237 req->ca_file = http->ca_file;
239 *preq = req;
240 return rv;
241}
242
244{
245 if (req->internals) {
246 req->http->impl->req_cleanup(req);
247 req->internals = NULL;
248 }
250}
251
253{
254 req->cb.on_status = cb;
255 req->cb.on_status_data = baton;
256}
257
263
265{
266 return req->http->impl->perform(req);
267}
268
273
275 md_http_t *http, int in_flight)
276{
277 nextreq_proxy_t *proxy = baton;
278
279 return proxy->nextreq(preq, proxy->baton, http, in_flight);
280}
281
283{
284 nextreq_proxy_t proxy;
285
286 proxy.nextreq = nextreq;
287 proxy.baton = baton;
288 return http->impl->multi_perform(http, http->pool, proxy_nextreq, &proxy);
289}
290
292 struct apr_table_t *headers)
293{
295 apr_status_t rv;
296
297 rv = req_create(&req, http, "GET", url, headers);
298 *preq = (APR_SUCCESS == rv)? req : NULL;
299 return rv;
300}
301
303 struct apr_table_t *headers)
304{
306 apr_status_t rv;
307
308 rv = req_create(&req, http, "HEAD", url, headers);
309 *preq = (APR_SUCCESS == rv)? req : NULL;
310 return rv;
311}
312
314 struct apr_table_t *headers, const char *content_type,
315 struct apr_bucket_brigade *body, int detect_len)
316{
318 apr_status_t rv;
319
320 rv = req_create(&req, http, "POST", url, headers);
321 if (APR_SUCCESS == rv) {
322 rv = req_set_body(req, content_type, body, -1, detect_len);
323 }
324 *preq = (APR_SUCCESS == rv)? req : NULL;
325 return rv;
326}
327
329 struct apr_table_t *headers, const char *content_type,
330 const struct md_data_t *body)
331{
333 apr_status_t rv;
334
335 rv = req_create(&req, http, "POST", url, headers);
336 if (APR_SUCCESS != rv) goto cleanup;
337 rv = req_set_body_data(req, content_type, body);
338cleanup:
339 if (APR_SUCCESS == rv) {
340 *preq = req;
341 }
342 else {
343 *preq = NULL;
344 if (req) md_http_req_destroy(req);
345 }
346 return rv;
347}
348
350 const char *url, struct apr_table_t *headers,
351 md_http_response_cb *cb, void *baton)
352{
354 apr_status_t rv;
355
356 rv = md_http_GET_create(&req, http, url, headers);
357 if (APR_SUCCESS == rv) md_http_set_on_response_cb(req, cb, baton);
358 return (APR_SUCCESS == rv)? md_http_perform(req) : rv;
359}
360
362 const char *url, struct apr_table_t *headers,
363 md_http_response_cb *cb, void *baton)
364{
366 apr_status_t rv;
367
368 rv = md_http_HEAD_create(&req, http, url, headers);
369 if (APR_SUCCESS == rv) md_http_set_on_response_cb(req, cb, baton);
370 return (APR_SUCCESS == rv)? md_http_perform(req) : rv;
371}
372
374 struct apr_table_t *headers, const char *content_type,
375 apr_bucket_brigade *body, int detect_len,
376 md_http_response_cb *cb, void *baton)
377{
379 apr_status_t rv;
380
381 rv = md_http_POST_create(&req, http, url, headers, content_type, body, detect_len);
382 if (APR_SUCCESS == rv) md_http_set_on_response_cb(req, cb, baton);
383 return (APR_SUCCESS == rv)? md_http_perform(req) : rv;
384}
385
387 struct apr_table_t *headers, const char *content_type,
388 const md_data_t *body,
389 md_http_response_cb *cb, void *baton)
390{
392 apr_status_t rv;
393
394 rv = md_http_POSTd_create(&req, http, url, headers, content_type, body);
395 if (APR_SUCCESS == rv) md_http_set_on_response_cb(req, cb, baton);
396 return (APR_SUCCESS == rv)? md_http_perform(req) : rv;
397}
APR-UTIL Buckets/Bucket Brigades.
APR general purpose library routines.
APR Strings library.
request_rec int int apr_table_t const char * path
ap_vhost_iterate_conn_cb void * baton
Definition http_vhost.h:87
#define APR_EGENERAL
Definition apr_errno.h:313
#define APR_ENOTIMPL
Definition apr_errno.h:476
const char * url
Definition apr_escape.h:120
apr_size_t size
const char int apr_pool_t * pool
Definition apr_cstr.h:84
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
void * data
void const char apr_status_t(* cleanup)(void *))
apr_uint32_t apr_pool_t apr_uint32_t apr_pollset_method_e method
Definition apr_poll.h:195
#define apr_pool_create(newpool, parent)
Definition apr_pools.h:322
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
apr_int64_t apr_time_t
Definition apr_time.h:45
static md_http_impl_t impl
Definition md_curl.c:639
apr_pool_t * p
Definition md_event.c:32
void md_http_set_response_limit(md_http_t *http, apr_off_t resp_limit)
Definition md_http.c:124
static md_http_impl_t * cur_impl
Definition md_http.c:41
apr_status_t md_http_GET_perform(struct md_http_t *http, const char *url, struct apr_table_t *headers, md_http_response_cb *cb, void *baton)
Definition md_http.c:349
void md_http_set_connect_timeout(md_http_request_t *req, apr_time_t timeout)
Definition md_http.c:144
void md_http_set_ca_file(md_http_t *http, const char *ca_file)
Definition md_http.c:161
static apr_status_t req_set_body_data(md_http_request_t *req, const char *content_type, const md_data_t *body)
Definition md_http.c:195
apr_status_t md_http_clone(md_http_t **phttp, apr_pool_t *p, md_http_t *source_http)
Definition md_http.c:95
void md_http_set_connect_timeout_default(md_http_t *http, apr_time_t timeout)
Definition md_http.c:139
apr_status_t md_http_POSTd_create(md_http_request_t **preq, md_http_t *http, const char *url, struct apr_table_t *headers, const char *content_type, const struct md_data_t *body)
Definition md_http.c:328
static apr_status_t proxy_nextreq(md_http_request_t **preq, void *baton, md_http_t *http, int in_flight)
Definition md_http.c:274
void * md_http_get_impl_data(md_http_t *http)
Definition md_http.c:119
apr_status_t md_http_HEAD_perform(struct md_http_t *http, const char *url, struct apr_table_t *headers, md_http_response_cb *cb, void *baton)
Definition md_http.c:361
apr_status_t md_http_POST_perform(struct md_http_t *http, const char *url, struct apr_table_t *headers, const char *content_type, apr_bucket_brigade *body, int detect_len, md_http_response_cb *cb, void *baton)
Definition md_http.c:373
void md_http_set_stalling_default(md_http_t *http, long bytes_per_sec, apr_time_t timeout)
Definition md_http.c:149
apr_status_t md_http_multi_perform(md_http_t *http, md_http_next_req *nextreq, void *baton)
Definition md_http.c:282
void md_http_set_on_status_cb(md_http_request_t *req, md_http_status_cb *cb, void *baton)
Definition md_http.c:252
void md_http_set_unix_socket_path(md_http_t *http, const char *path)
Definition md_http.c:166
apr_status_t md_http_GET_create(md_http_request_t **preq, md_http_t *http, const char *url, struct apr_table_t *headers)
Definition md_http.c:291
static apr_status_t req_create(md_http_request_t **preq, md_http_t *http, const char *method, const char *url, struct apr_table_t *headers)
Definition md_http.c:211
void md_http_set_timeout_default(md_http_t *http, apr_time_t timeout)
Definition md_http.c:129
void md_http_set_on_response_cb(md_http_request_t *req, md_http_response_cb *cb, void *baton)
Definition md_http.c:258
apr_status_t md_http_perform(md_http_request_t *req)
Definition md_http.c:264
apr_status_t md_http_create(md_http_t **phttp, apr_pool_t *p, const char *user_agent, const char *proxy_url)
Definition md_http.c:61
static apr_status_t req_set_body(md_http_request_t *req, const char *content_type, apr_bucket_brigade *body, apr_off_t body_len, int detect_len)
Definition md_http.c:171
void md_http_use_implementation(md_http_impl_t *impl)
Definition md_http.c:44
void md_http_set_stalling(md_http_request_t *req, long bytes_per_sec, apr_time_t timeout)
Definition md_http.c:155
apr_status_t md_http_HEAD_create(md_http_request_t **preq, md_http_t *http, const char *url, struct apr_table_t *headers)
Definition md_http.c:302
apr_status_t md_http_POST_create(md_http_request_t **preq, md_http_t *http, const char *url, struct apr_table_t *headers, const char *content_type, struct apr_bucket_brigade *body, int detect_len)
Definition md_http.c:313
void md_http_set_timeout(md_http_request_t *req, apr_time_t timeout)
Definition md_http.c:134
apr_status_t md_http_POSTd_perform(md_http_t *http, const char *url, struct apr_table_t *headers, const char *content_type, const md_data_t *body, md_http_response_cb *cb, void *baton)
Definition md_http.c:386
void md_http_set_impl_data(md_http_t *http, void *data)
Definition md_http.c:114
static int cur_init_done
Definition md_http.c:42
static apr_status_t http_cleanup(void *data)
Definition md_http.c:52
void md_http_req_destroy(md_http_request_t *req)
Definition md_http.c:243
apr_status_t md_http_response_cb(const md_http_response_t *res, void *data)
Definition md_http.h:40
apr_status_t md_http_next_req(md_http_request_t **preq, void *baton, md_http_t *http, int in_flight)
Definition md_http.h:228
apr_status_t md_http_status_cb(const md_http_request_t *req, apr_status_t status, void *data)
Definition md_http.h:35
return NULL
Definition mod_so.c:359
const char * data
Definition md_util.h:42
apr_size_t len
Definition md_util.h:43
void * on_response_data
Definition md_http.h:47
md_http_response_cb * on_response
Definition md_http.h:46
void * on_status_data
Definition md_http.h:45
md_http_status_cb * on_status
Definition md_http.h:44
md_http_cleanup_cb * cleanup
Definition md_http.h:259
md_http_perform_cb * perform
Definition md_http.h:257
md_http_multi_perform_cb * multi_perform
Definition md_http.h:258
md_http_init_cb * init
Definition md_http.h:255
md_http_req_cleanup_cb * req_cleanup
Definition md_http.h:256
apr_pool_t * pool
Definition md_http.h:60
apr_table_t * headers
Definition md_http.h:69
struct apr_bucket_alloc_t * bucket_alloc
Definition md_http.h:62
apr_off_t body_len
Definition md_http.h:71
struct apr_bucket_brigade * body
Definition md_http.h:70
md_http_callbacks_t cb
Definition md_http.h:74
void * internals
Definition md_http.h:75
apr_off_t resp_limit
Definition md_http.h:72
const char * proxy_url
Definition md_http.h:66
const char * user_agent
Definition md_http.h:65
md_http_timeouts_t timeout
Definition md_http.h:73
const char * url
Definition md_http.h:64
const char * ca_file
Definition md_http.h:67
md_http_t * http
Definition md_http.h:59
const char * method
Definition md_http.h:63
const char * unix_socket_path
Definition md_http.h:68
apr_bucket_alloc_t * bucket_alloc
Definition md_http.c:29
void * impl_data
Definition md_http.c:33
apr_pool_t * pool
Definition md_http.c:28
int next_id
Definition md_http.c:30
const char * proxy_url
Definition md_http.c:35
md_http_impl_t * impl
Definition md_http.c:32
apr_off_t resp_limit
Definition md_http.c:31
const char * unix_socket_path
Definition md_http.c:36
const char * ca_file
Definition md_http.c:38
const char * user_agent
Definition md_http.c:34
md_http_timeouts_t timeout
Definition md_http.c:37
long stall_bytes_per_sec
Definition md_http.h:54
apr_time_t stalled
Definition md_http.h:55
apr_time_t connect
Definition md_http.h:53
apr_time_t overall
Definition md_http.h:52
md_http_next_req * nextreq
Definition md_http.c:270
IN ULONG IN INT timeout