]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add ability to set static headers to rlm_rest
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Thu, 20 Oct 2022 02:40:34 +0000 (22:40 -0400)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Thu, 20 Oct 2022 02:40:43 +0000 (22:40 -0400)
raddb/mods-available/rest
src/lib/util/talloc.h
src/modules/rlm_rest/rest.c
src/modules/rlm_rest/rest.h
src/modules/rlm_rest/rlm_rest.c

index caa08b22bf6ef6dc79f7bc33aa5d3772b2842bff..de426d2adbbd029ffcaf1b6ee4d15cc45a2a028c 100644 (file)
@@ -201,6 +201,7 @@ rest {
        #                     variables set like http_proxy.
        #  | `method`       | HTTP method to use, one of 'get', 'post', 'put', 'patch',
        #                     'delete' or any custom HTTP method.
+       #  | `header`       | A custom header in the format '<header>: <value>'.
        #  | `body`         | The format of the HTTP body sent to the remote server.
        #                     May be 'none', 'post' or 'json', defaults to 'none'.
        #  | `data`         | Send custom freeform data in the HTTP body. `Content-type`
index 0d1a85254b61a77b563e934792e736eb2e7e37ce..275a7999129a60905efcbad5bf3de59aaa5ef1a1 100644 (file)
@@ -74,7 +74,7 @@ talloc_foreach(vpt_m, vpt) {
  */
 #define talloc_foreach(_array, _iter) \
        for (__typeof__(_array[0]) _iter, *_p = (void *)(_array), *_end = (void *)((_array) + talloc_array_length(_array)); \
-            (_p < _end) && (_iter = *((void **)(_p))); \
+            (_p < _end) && (_iter = *((void **)(uintptr_t)(_p))); \
             _p = (__typeof__(_p))((__typeof__(_array))_p) + 1)
 
 typedef int(* fr_talloc_free_func_t)(void *fire_ctx, void *uctx);
index 28098dded6387b7f043dfdb64101b84d6fdf43d7..4851d132e8062d73f22eae5fec1916537a985e48 100644 (file)
@@ -1734,9 +1734,6 @@ int rest_request_config(module_ctx_t const *mctx, rlm_rest_section_t const *sect
        char const              *option = "unknown";
        char const              *content_type;
 
-       fr_pair_t               *header;
-       fr_dcursor_t            headers;
-
        char                    buffer[512];
 
        fr_assert(candle);
@@ -1805,22 +1802,43 @@ int rest_request_config(module_ctx_t const *mctx, rlm_rest_section_t const *sect
        ctx->headers = curl_slist_append(ctx->headers, buffer);
        if (!ctx->headers) goto error_header;
 
-       for (header =  fr_pair_dcursor_by_da_init(&headers, &request->control_pairs, attr_rest_http_header);
-            header;
-            header = fr_dcursor_next(&headers)) {
-               header = fr_dcursor_remove(&headers);
-               if (!strchr(header->vp_strvalue, ':')) {
-                       RWDEBUG("Invalid HTTP header \"%s\" must be in format '<attribute>: <value>'.  Skipping...",
-                               header->vp_strvalue);
-                       talloc_free(header);
-                       continue;
+       /*
+        *      Add in the section headers
+        */
+       if (section->headers) {
+               talloc_foreach(section->headers, header) {
+                       RINDENT();
+                       RDEBUG3("%pV", fr_box_strvalue_buffer(header));
+                       REXDENT();
+
+                       ctx->headers = curl_slist_append(ctx->headers, header);
                }
-               RINDENT();
-               RDEBUG3("%pV", &header->data);
-               REXDENT();
+       }
 
-               ctx->headers = curl_slist_append(ctx->headers, header->vp_strvalue);
-               talloc_free(header);
+       /*
+        *      Add in dynamic headers from the request
+        */
+       {
+               fr_pair_t       *header;
+               fr_dcursor_t    headers;
+
+               for (header =  fr_pair_dcursor_by_da_init(&headers, &request->control_pairs, attr_rest_http_header);
+                    header;
+                    header = fr_dcursor_next(&headers)) {
+                       header = fr_dcursor_remove(&headers);
+                       if (!strchr(header->vp_strvalue, ':')) {
+                               RWDEBUG("Invalid HTTP header \"%s\" must be in format '<attribute>: <value>'.  Skipping...",
+                                       header->vp_strvalue);
+                               talloc_free(header);
+                               continue;
+                       }
+                       RINDENT();
+                       RDEBUG3("%pV", &header->data);
+                       REXDENT();
+
+                       ctx->headers = curl_slist_append(ctx->headers, header->vp_strvalue);
+                       talloc_free(header);
+               }
        }
 
        /*
index a196a1b9d8b2f59c3741ebe5e879078d48e85d94..1cf5a76fed026877670addd4c7ef6c1d345ecb3a 100644 (file)
@@ -125,6 +125,7 @@ typedef struct {
        http_body_type_t        force_to;       //!< Override the Content-Type header in the response
                                                //!< to force decoding as a particular type.
 
+       char const              **headers;      //!< Custom headers to set (optional).
        char const              *data;          //!< Custom body data (optional).
 
        bool                    auth_is_set;    //!< Whether a value was provided for auth_str.
index 9d45cfbae83a05f3a905e746d7fa80b104111ab4..978cf92a75ca3044cd752e7fd4069dc7b19fa859 100644 (file)
@@ -90,6 +90,7 @@ static const CONF_PARSER section_config[] = {
        { FR_CONF_OFFSET("uri", FR_TYPE_STRING | FR_TYPE_XLAT, rlm_rest_section_t, uri), .dflt = "" },
        { FR_CONF_OFFSET("proxy", FR_TYPE_STRING, rlm_rest_section_t, proxy), .func = rest_proxy_parse },
        { FR_CONF_OFFSET("method", FR_TYPE_STRING, rlm_rest_section_t, method_str), .dflt = "GET" },
+       { FR_CONF_OFFSET("header", FR_TYPE_STRING | FR_TYPE_MULTI, rlm_rest_section_t, headers) },
        { FR_CONF_OFFSET("body", FR_TYPE_STRING, rlm_rest_section_t, body_str), .dflt = "none" },
        { FR_CONF_OFFSET("data", FR_TYPE_STRING | FR_TYPE_XLAT, rlm_rest_section_t, data) },
        { FR_CONF_OFFSET("force_to", FR_TYPE_STRING, rlm_rest_section_t, force_to_str) },
@@ -117,6 +118,9 @@ static const CONF_PARSER xlat_config[] = {
        /* User authentication */
        { FR_CONF_OFFSET_IS_SET("auth", FR_TYPE_VOID, rlm_rest_section_t, auth),
          .func = cf_table_parse_int, .uctx = &(cf_table_parse_ctx_t){ .table = http_auth_table, .len = &http_auth_table_len }, .dflt = "none" },
+
+       { FR_CONF_OFFSET("header", FR_TYPE_STRING | FR_TYPE_MULTI, rlm_rest_section_t, headers) },
+
        { FR_CONF_OFFSET("username", FR_TYPE_STRING | FR_TYPE_XLAT, rlm_rest_section_t, username) },
        { FR_CONF_OFFSET("password", FR_TYPE_STRING | FR_TYPE_XLAT, rlm_rest_section_t, password) },
        { FR_CONF_OFFSET("require_auth", FR_TYPE_BOOL, rlm_rest_section_t, require_auth), .dflt = "no" },