Asterisk - The Open Source Telephony Project GIT-master-abe0018
Data Structures | Functions
Collaboration diagram for Header Callback:

Data Structures

struct  curl_header_data
 Context structure passed to ast_curl_header_default_cb. More...
 

Functions

size_t curl_header_cb (char *data, size_t size, size_t nitems, void *client_data)
 A default implementation of a header callback. More...
 
void curl_header_data_free (void *obj)
 

Detailed Description

If you need to access the headers returned on the response, you can define a callback that curl will call for every header it receives.

Your callback must follow the specification defined for CURLOPT_HEADERFUNCTION and implement the curl_write_callback prototype.

The following ast_curl_headers objects compose a default implementation that will accumulate the headers in an ast_variable list.

Function Documentation

◆ curl_header_cb()

size_t curl_header_cb ( char *  data,
size_t  size,
size_t  nitems,
void *  client_data 
)

A default implementation of a header callback.

This is an implementation of #CURLOPT_HEADERFUNCTION that performs basic sanity checks and saves headers in the ast_curl_header_data.headers ast_variable list.

The curl prototype for this function is curl_write_callback

Warning
If you decide to write your own callback, curl doesn't guarantee a terminating NULL in data passed to the callbacks!
Parameters
dataWill contain a header line that may not be NULL terminated.
sizeAlways 1.
nitemsThe number of bytes in data.
client_dataA pointer to whatever structure you passed to ast_curler in the curl_header_data parameter.
Returns
Number of bytes handled. Must be (size * nitems) or an error is signalled.

Definition at line 39 of file curl_utils.c.

41{
42 struct curl_header_data *cb_data = client_data;
43 size_t realsize = size * nitems;
44 size_t adjusted_size = realsize;
45 char *debug_info = S_OR(cb_data->debug_info, "");
46 char *start = data;
47 char *colon = NULL;
48 struct ast_variable *h;
49 char *header;
50 char *value;
51 SCOPE_ENTER(5, "'%s': Header received with %zu bytes\n",
52 debug_info, realsize);
53
54 if (cb_data->max_header_len == 0) {
56 }
57
58 if (realsize > cb_data->max_header_len) {
59 /*
60 * Silently ignore any header over the length limit.
61 */
62 SCOPE_EXIT_RTN_VALUE(realsize, "oversize header: %zu > %zu\n",
63 realsize, cb_data->max_header_len);
64 }
65
66 /* Per CURL: buffer may not be NULL terminated. */
67
68 /* Skip blanks */
69 while (*start && ((unsigned char) *start) < 33 && start < data + realsize) {
70 start++;
71 adjusted_size--;
72 }
73
74 if (adjusted_size < strlen("HTTP/") + 1) {
75 /* this is probably the \r\n\r\n sequence that ends the headers */
76 cb_data->_capture = 0;
77 SCOPE_EXIT_RTN_VALUE(realsize, "undersized header. probably end-of-headers marker: %zu\n",
78 adjusted_size);
79 }
80
81 /*
82 * We only want headers from a 2XX response
83 * so don't start capturing until we see
84 * the 2XX.
85 */
86 if (ast_begins_with(start, "HTTP/")) {
87 int code;
88 /*
89 * HTTP/1.1 200 OK
90 * We want there to be a version after the HTTP/
91 * and reason text after the code but we don't care
92 * what they are.
93 */
94 int rc = sscanf(start, "HTTP/%*s %d %*s", &code);
95 if (rc == 1) {
96 if (code / 100 == 2) {
97 cb_data->_capture = 1;
98 }
99 }
100 SCOPE_EXIT_RTN_VALUE(realsize, "HTTP response code: %d\n",
101 code);
102 }
103
104 if (!cb_data->_capture) {
105 SCOPE_EXIT_RTN_VALUE(realsize, "not capturing\n");
106 }
107
108 header = ast_alloca(adjusted_size + 1);
109 ast_copy_string(header, start, adjusted_size + 1);
110
111 /* We have a NULL terminated string now */
112
113 colon = strchr(header, ':');
114 if (!colon) {
115 SCOPE_EXIT_RTN_VALUE(realsize, "No colon in the header. Weird\n");
116 }
117
118 *colon++ = '\0';
119 value = colon;
121
122 h = ast_variable_new(header, value, __FILE__);
123 if (!h) {
125 "'%s': Unable to allocate memory for header '%s'\n",
126 debug_info, header);
127 }
128 ast_variable_list_append(&cb_data->headers, h);
129
130 SCOPE_EXIT_RTN_VALUE(realsize, "header: <%s> value: <%s>",
131 header, value);
132}
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
#define CURL_WRITEFUNC_ERROR
Definition: curl_utils.h:28
#define AST_CURL_DEFAULT_MAX_HEADER_LEN
Definition: curl_utils.h:25
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
#define SCOPE_EXIT_LOG_RTN_VALUE(__value, __log_level,...)
#define SCOPE_ENTER(level,...)
#define ast_variable_new(name, value, filename)
#define ast_variable_list_append(head, new_var)
#define LOG_WARNING
#define NULL
Definition: resample.c:96
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
char * ast_trim_blanks(char *str)
Trims trailing whitespace characters from a string.
Definition: strings.h:186
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Checks whether a string begins with another.
Definition: strings.h:97
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:161
Structure for variables, used for configurations and for channel variables.
Context structure passed to ast_curl_header_default_cb.
Definition: curl_utils.h:163
struct ast_variable * headers
Definition: curl_utils.h:182
size_t max_header_len
Definition: curl_utils.h:173
int value
Definition: syslog.c:37

References curl_header_data::_capture, ast_alloca, ast_begins_with(), ast_copy_string(), AST_CURL_DEFAULT_MAX_HEADER_LEN, ast_skip_blanks(), ast_trim_blanks(), ast_variable_list_append, ast_variable_new, CURL_WRITEFUNC_ERROR, curl_header_data::debug_info, curl_header_data::headers, LOG_WARNING, curl_header_data::max_header_len, NULL, S_OR, SCOPE_ENTER, SCOPE_EXIT_LOG_RTN_VALUE, SCOPE_EXIT_RTN_VALUE, and value.

Referenced by curler().

◆ curl_header_data_free()

void curl_header_data_free ( void *  obj)

Definition at line 26 of file curl_utils.c.

27{
28 struct curl_header_data *cb_data = obj;
29 if (!cb_data) {
30 return;
31 }
33 if (cb_data->debug_info) {
34 ast_free(cb_data->debug_info);
35 }
36 ast_free(cb_data);
37}
#define ast_free(a)
Definition: astmm.h:180
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262

References ast_free, ast_variables_destroy(), curl_header_data::debug_info, and curl_header_data::headers.

Referenced by retrieve_cert_from_url().