Apache HTTPD
md_result.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#include <stddef.h>
19#include <stdio.h>
20#include <stdlib.h>
21
22#include <apr_lib.h>
23#include <apr_date.h>
24#include <apr_time.h>
25#include <apr_strings.h>
26
27#include "md.h"
28#include "md_json.h"
29#include "md_log.h"
30#include "md_result.h"
31
32static const char *dup_trim(apr_pool_t *p, const char *s)
33{
34 char *d = apr_pstrdup(p, s);
35 if (d) apr_collapse_spaces(d, d);
36 return d;
37}
38
40{
42
43 result = apr_pcalloc(p, sizeof(*result));
44 result->p = p;
45 result->md_name = MD_OTHER;
46 result->status = status;
47 return result;
48}
49
51{
53 result->md_name = md_name;
54 return result;
55}
56
58{
59 apr_pool_t *p = result->p;
60 memset(result, 0, sizeof(*result));
61 result->p = p;
62}
63
65{
66 if (result->on_change) result->on_change(result, result->on_change_data);
67}
68
69void md_result_activity_set(md_result_t *result, const char *activity)
70{
71 md_result_activity_setn(result, activity? apr_pstrdup(result->p, activity) : NULL);
72}
73
74void md_result_activity_setn(md_result_t *result, const char *activity)
75{
76 result->activity = activity;
77 result->problem = result->detail = NULL;
78 result->subproblems = NULL;
80}
81
90
92{
93 result->status = status;
94 result->problem = NULL;
95 result->detail = detail? apr_pstrdup(result->p, detail) : NULL;
96 result->subproblems = NULL;
98}
99
101 const char *problem, const char *detail,
102 const md_json_t *subproblems)
103{
104 result->status = status;
105 result->problem = dup_trim(result->p, problem);
106 result->detail = apr_pstrdup(result->p, detail);
107 result->subproblems = subproblems? md_json_clone(result->p, subproblems) : NULL;
109}
110
112 const char *problem, const char *fmt, ...)
113{
114 va_list ap;
115
116 result->status = status;
117 result->problem = dup_trim(result->p, problem);
118
119 va_start(ap, fmt);
120 result->detail = apr_pvsprintf(result->p, fmt, ap);
121 va_end(ap);
122 result->subproblems = NULL;
124}
125
127{
128 va_list ap;
129
130 result->status = status;
131 va_start(ap, fmt);
132 result->detail = apr_pvsprintf(result->p, fmt, ap);
133 va_end(ap);
134 result->subproblems = NULL;
136}
137
139{
140 result->ready_at = ready_at;
142}
143
145{
147 const char *s;
148
150 result->status = (int)md_json_getl(json, MD_KEY_STATUS, NULL);
151 result->problem = md_json_dups(p, json, MD_KEY_PROBLEM, NULL);
152 result->detail = md_json_dups(p, json, MD_KEY_DETAIL, NULL);
153 result->activity = md_json_dups(p, json, MD_KEY_ACTIVITY, NULL);
155 if (s && *s) result->ready_at = apr_date_parse_rfc(s);
156 result->subproblems = md_json_dupj(p, json, MD_KEY_SUBPROBLEMS, NULL);
157 return result;
158}
159
161{
162 md_json_t *json;
163 char ts[APR_RFC822_DATE_LEN];
164
165 json = md_json_create(p);
166 md_json_setl(result->status, json, MD_KEY_STATUS, NULL);
167 if (result->status > 0) {
169 apr_strerror(result->status, buffer, sizeof(buffer));
170 md_json_sets(buffer, json, "status-description", NULL);
171 }
172 if (result->problem) md_json_sets(result->problem, json, MD_KEY_PROBLEM, NULL);
173 if (result->detail) md_json_sets(result->detail, json, MD_KEY_DETAIL, NULL);
174 if (result->activity) md_json_sets(result->activity, json, MD_KEY_ACTIVITY, NULL);
175 if (result->ready_at > 0) {
176 apr_rfc822_date(ts, result->ready_at);
178 }
179 if (result->subproblems) {
180 md_json_setj(result->subproblems, json, MD_KEY_SUBPROBLEMS, NULL);
181 }
182 return json;
183}
184
185static int str_cmp(const char *s1, const char *s2)
186{
187 if (s1 == s2) return 0;
188 if (!s1) return -1;
189 if (!s2) return 1;
190 return strcmp(s1, s2);
191}
192
194{
195 int n;
196 if (r1 == r2) return 0;
197 if (!r1) return -1;
198 if (!r2) return 1;
199 if ((n = r1->status - r2->status)) return n;
200 if ((n = str_cmp(r1->problem, r2->problem))) return n;
201 if ((n = str_cmp(r1->detail, r2->detail))) return n;
202 if ((n = str_cmp(r1->activity, r2->activity))) return n;
203 return (int)(r1->ready_at - r2->ready_at);
204}
205
207{
208 dest->status = src->status;
209 dest->problem = src->problem;
210 dest->detail = src->detail;
211 dest->activity = src->activity;
212 dest->ready_at = src->ready_at;
213 dest->subproblems = src->subproblems;
214}
215
217{
218 dest->status = src->status;
219 dest->problem = src->problem? dup_trim(dest->p, src->problem) : NULL;
220 dest->detail = src->detail? apr_pstrdup(dest->p, src->detail) : NULL;
221 dest->activity = src->activity? apr_pstrdup(dest->p, src->activity) : NULL;
222 dest->ready_at = src->ready_at;
223 dest->subproblems = src->subproblems? md_json_clone(dest->p, src->subproblems) : NULL;
225}
226
227void md_result_log(md_result_t *result, unsigned int level)
228{
229 if (md_log_is_level(result->p, (md_log_level_t)level)) {
230 const char *sep = "";
231 const char *msg = "";
232
233 if (result->md_name) {
234 msg = apr_psprintf(result->p, "md[%s]", result->md_name);
235 sep = " ";
236 }
237 if (result->activity) {
238 msg = apr_psprintf(result->p, "%s%swhile[%s]", msg, sep, result->activity);
239 sep = " ";
240 }
241 if (result->problem) {
242 msg = apr_psprintf(result->p, "%s%sproblem[%s]", msg, sep, result->problem);
243 sep = " ";
244 }
245 if (result->detail) {
246 msg = apr_psprintf(result->p, "%s%sdetail[%s]", msg, sep, result->detail);
247 sep = " ";
248 }
249 if (result->subproblems) {
250 msg = apr_psprintf(result->p, "%s%ssubproblems[%s]", msg, sep,
252 sep = " ";
253 }
254 md_log_perror(MD_LOG_MARK, (md_log_level_t)level, result->status, result->p, "%s", msg);
255 }
256}
257
259{
260 result->on_change = cb;
261 result->on_change_data = data;
262}
263
265{
266 if (result->on_raise) return result->on_raise(result, result->on_raise_data, event, p);
267 return APR_SUCCESS;
268}
269
271{
272 if (result->on_holler) result->on_holler(result, result->on_holler_data, event, p);
273}
274
276{
277 result->on_raise = cb;
278 result->on_raise_data = data;
279}
280
282{
283 result->on_holler = cb;
284 result->on_holler_data = data;
285}
int n
Definition ap_regex.h:278
APR-UTIL date routines.
APR general purpose library routines.
apr_size_t const unsigned char unsigned int unsigned int d
Definition apr_siphash.h:72
APR Strings library.
APR Time Library.
#define HUGE_STRING_LEN
Definition httpd.h:303
const char * src
Definition apr_encode.h:167
apr_size_t size
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
void * data
char * buffer
apr_array_header_t ** result
apr_vformatter_buff_t const char * fmt
Definition apr_lib.h:175
apr_vformatter_buff_t const char va_list ap
Definition apr_lib.h:176
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
const char * sep
const char * s
Definition apr_strings.h:95
int int status
#define APR_RFC822_DATE_LEN
Definition apr_time.h:186
apr_int64_t apr_time_t
Definition apr_time.h:45
#define MD_KEY_VALID_FROM
Definition md.h:211
#define MD_KEY_ACTIVITY
Definition md.h:118
#define MD_KEY_PROBLEM
Definition md.h:177
#define MD_OTHER
Definition md.h:50
#define MD_KEY_SUBPROBLEMS
Definition md.h:198
#define MD_KEY_STATUS
Definition md.h:196
#define MD_KEY_DETAIL
Definition md.h:136
apr_pool_t * p
Definition md_event.c:32
md_json_t * md_json_create(apr_pool_t *pool)
Definition md_json.c:92
md_json_t * md_json_dupj(apr_pool_t *p, const md_json_t *json,...)
Definition md_json.c:492
apr_status_t md_json_sets(const char *value, md_json_t *json,...)
Definition md_json.c:430
long md_json_getl(const md_json_t *json,...)
Definition md_json.c:381
md_json_t * md_json_clone(apr_pool_t *pool, const md_json_t *json)
Definition md_json.c:116
apr_status_t md_json_setj(const md_json_t *value, md_json_t *json,...)
Definition md_json.c:527
const char * md_json_dups(apr_pool_t *p, const md_json_t *json,...)
Definition md_json.c:418
apr_status_t md_json_setl(long value, md_json_t *json,...)
Definition md_json.c:392
const char * md_json_writep(const md_json_t *json, apr_pool_t *p, md_json_fmt_t fmt)
Definition md_json.c:992
@ MD_JSON_FMT_COMPACT
Definition md_json.h:43
void md_log_perror(const char *file, int line, md_log_level_t level, apr_status_t rv, apr_pool_t *p, const char *fmt,...)
Definition md_log.c:68
int md_log_is_level(apr_pool_t *p, md_log_level_t level)
Definition md_log.c:60
#define MD_LOG_MARK
Definition md_log.h:39
md_log_level_t
Definition md_log.h:20
md_result_t * md_result_from_json(const struct md_json_t *json, apr_pool_t *p)
Definition md_result.c:144
void md_result_activity_printf(md_result_t *result, const char *fmt,...)
Definition md_result.c:82
struct md_json_t * md_result_to_json(const md_result_t *result, apr_pool_t *p)
Definition md_result.c:160
void md_result_on_holler(md_result_t *result, md_result_holler_cb *cb, void *data)
Definition md_result.c:281
void md_result_activity_setn(md_result_t *result, const char *activity)
Definition md_result.c:74
static int str_cmp(const char *s1, const char *s2)
Definition md_result.c:185
void md_result_dup(md_result_t *dest, const md_result_t *src)
Definition md_result.c:216
apr_status_t md_result_raise(md_result_t *result, const char *event, apr_pool_t *p)
Definition md_result.c:264
void md_result_on_change(md_result_t *result, md_result_change_cb *cb, void *data)
Definition md_result.c:258
void md_result_printf(md_result_t *result, apr_status_t status, const char *fmt,...)
Definition md_result.c:126
void md_result_problem_set(md_result_t *result, apr_status_t status, const char *problem, const char *detail, const md_json_t *subproblems)
Definition md_result.c:100
void md_result_assign(md_result_t *dest, const md_result_t *src)
Definition md_result.c:206
static const char * dup_trim(apr_pool_t *p, const char *s)
Definition md_result.c:32
md_result_t * md_result_make(apr_pool_t *p, apr_status_t status)
Definition md_result.c:39
void md_result_reset(md_result_t *result)
Definition md_result.c:57
void md_result_activity_set(md_result_t *result, const char *activity)
Definition md_result.c:69
static void on_change(md_result_t *result)
Definition md_result.c:64
int md_result_cmp(const md_result_t *r1, const md_result_t *r2)
Definition md_result.c:193
void md_result_log(md_result_t *result, unsigned int level)
Definition md_result.c:227
void md_result_problem_printf(md_result_t *result, apr_status_t status, const char *problem, const char *fmt,...)
Definition md_result.c:111
void md_result_set(md_result_t *result, apr_status_t status, const char *detail)
Definition md_result.c:91
md_result_t * md_result_md_make(apr_pool_t *p, const char *md_name)
Definition md_result.c:50
void md_result_delay_set(md_result_t *result, apr_time_t ready_at)
Definition md_result.c:138
void md_result_holler(md_result_t *result, const char *event, apr_pool_t *p)
Definition md_result.c:270
void md_result_on_raise(md_result_t *result, md_result_raise_cb *cb, void *data)
Definition md_result.c:275
void md_result_change_cb(md_result_t *result, void *data)
Definition md_result.h:25
void md_result_holler_cb(md_result_t *result, void *data, const char *event, apr_pool_t *p)
Definition md_result.h:27
apr_status_t md_result_raise_cb(md_result_t *result, void *data, const char *event, apr_pool_t *p)
Definition md_result.h:26
return NULL
Definition mod_so.c:359
apr_status_t apr_rfc822_date(char *date_str, apr_time_t t)
Definition timestr.c:42
typedef int(WSAAPI *apr_winapi_fpt_WSAPoll)(IN OUT LPWSAPOLLFD fdArray