Skip to content

Commit 0823869

Browse files
committed
On the user-defined-authn branch: In the interaction diagram, correct the
position in the handshake sequence where pipelining is optionally turned off on a connection. Add the option to reset pipelining on two more callbacks; current internal schemes sometimes restore it during the 'handle' phase, and sometimes (notably spnego) during the response validation phase. This makes the API for user-defined implementations more flexible at the cost of having to deal with far too long argument lists. Ain't no fun if it's less than six parameters, right? * serf.h: Update the authentication interaction diagram. (serf_authn_handle_func_t): Add the reset_pipelining argument and update the docstring to hopefully make it clear what that argument means. (serf_authn_setup_request_func_t): Add the reset_pipelining argument. (serf_authn_validate_response_func_t): Update the docstring. * auth/auth_user_defined.c (struct authn_baton_wrapper::pipelining_was_reset): Rename from the shorter but more ambiguous pipelining_reset. (validate_handler): Add docstring. (maybe_reset_pipelining): New. Now common code extracted from one of the callbacks. (serf__authn_user__handle, serf__authn_user__setup_request): Implement the reset_pipelining argument. (serf__authn_user__validate_response): Call maybe_reset_pipelining. * test/test_auth.c (user_authn_handle, user_authn_setup_request): Implement the reset_pipelining argument. git-svn-id: https://svn.apache.org/repos/asf/serf/branches/user-defined-authn@1926858 13f79535-47bb-0310-9956-ffa450edef68
1 parent c13ded1 commit 0823869

File tree

3 files changed

+70
-27
lines changed

3 files changed

+70
-27
lines changed

auth/auth_user_defined.c

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,14 @@ struct authn_baton_wrapper {
5353
int pipelining;
5454

5555
/* Was pipelining reset to its previous value?. */
56-
bool pipelining_reset;
56+
bool pipelining_was_reset;
5757

5858
/* The user-defined scheme's per-connection baton. */
5959
void *user_authn_baton;
6060
};
6161

6262

63+
/* Common callback parameter validation. */
6364
typedef apr_status_t (*callback_fn_t)();
6465
static apr_status_t validate_handler(serf_config_t *config,
6566
const serf__authn_scheme_t *scheme,
@@ -89,6 +90,34 @@ static apr_status_t validate_handler(serf_config_t *config,
8990
}
9091

9192

93+
/* Reset request pipelining on the connection if required. */
94+
static void maybe_reset_pipelining(const serf__authn_scheme_t *scheme,
95+
struct authn_baton_wrapper *authn_baton,
96+
serf_connection_t *conn,
97+
apr_status_t status,
98+
int reset_pipelining)
99+
{
100+
if (!reset_pipelining
101+
|| status != APR_SUCCESS
102+
|| authn_baton->pipelining_was_reset
103+
|| (scheme->user_flags & SERF_AUTHN_FLAG_PIPE))
104+
{
105+
serf__log(LOGLVL_DEBUG, LOGCOMP_AUTHN, __FILE__, conn->config,
106+
"User-defined scheme %s: no pipelining change for %s\n",
107+
scheme->name, conn->host_url);
108+
return;
109+
}
110+
111+
serf__log(LOGLVL_DEBUG, LOGCOMP_AUTHN, __FILE__, conn->config,
112+
"User-defined scheme %s: pipelining reset to %s for %s\n",
113+
scheme->name,
114+
authn_baton->pipelining ? "on" : "off",
115+
conn->host_url);
116+
serf__connection_set_pipelining(conn, authn_baton->pipelining);
117+
authn_baton->pipelining_was_reset = true;
118+
}
119+
120+
92121
apr_status_t
93122
serf__authn_user__init_conn(const serf__authn_scheme_t *scheme,
94123
int code,
@@ -135,9 +164,9 @@ serf__authn_user__init_conn(const serf__authn_scheme_t *scheme,
135164
"User-defined scheme %s: pipelining off for %s\n",
136165
scheme->name, conn->host_url);
137166
authn_baton->pipelining = serf__connection_set_pipelining(conn, 0);
138-
authn_baton->pipelining_reset = false;
167+
authn_baton->pipelining_was_reset = false;
139168
} else {
140-
authn_baton->pipelining_reset = true;
169+
authn_baton->pipelining_was_reset = true;
141170
}
142171
return status;
143172
}
@@ -156,6 +185,7 @@ serf__authn_user__handle(const serf__authn_scheme_t *scheme,
156185
serf__authn_info_t *const authn_info = get_authn_info(code, conn);
157186
serf_context_t *const ctx = conn->ctx;
158187
struct authn_baton_wrapper *authn_baton;
188+
int reset_pipelining = 0;
159189
char *username, *password;
160190
apr_pool_t *scratch_pool;
161191
apr_hash_t *auth_param;
@@ -222,7 +252,8 @@ serf__authn_user__handle(const serf__authn_scheme_t *scheme,
222252
username = password = NULL;
223253
}
224254

225-
status = scheme->user_handle_func(scheme->user_baton,
255+
status = scheme->user_handle_func(&reset_pipelining,
256+
scheme->user_baton,
226257
authn_baton->user_authn_baton, code,
227258
auth_hdr, auth_param,
228259
SERF__HEADER_FROM_CODE(code),
@@ -231,6 +262,7 @@ serf__authn_user__handle(const serf__authn_scheme_t *scheme,
231262
pool, scratch_pool);
232263

233264
cleanup:
265+
maybe_reset_pipelining(scheme, authn_baton, conn, status, reset_pipelining);
234266
apr_pool_destroy(scratch_pool);
235267
return status;
236268
}
@@ -249,6 +281,7 @@ serf__authn_user__setup_request(const serf__authn_scheme_t *scheme,
249281
const int peer_id = SERF__CODE_FROM_PEER(peer);
250282
serf__authn_info_t *const authn_info = get_authn_info(peer_id, conn);
251283
struct authn_baton_wrapper *authn_baton;
284+
int reset_pipelining = 0;
252285
apr_pool_t *scratch_pool;
253286
apr_status_t status;
254287

@@ -271,11 +304,14 @@ serf__authn_user__setup_request(const serf__authn_scheme_t *scheme,
271304

272305
authn_baton = authn_info->baton;
273306
apr_pool_create(&scratch_pool, conn->pool);
274-
status = scheme->user_setup_request_func(scheme->user_baton,
307+
status = scheme->user_setup_request_func(&reset_pipelining,
308+
scheme->user_baton,
275309
authn_baton->user_authn_baton,
276310
conn, request,
277311
method, uri, hdrs_bkt,
278312
scratch_pool);
313+
314+
maybe_reset_pipelining(scheme, authn_baton, conn, status, reset_pipelining);
279315
apr_pool_destroy(scratch_pool);
280316
return status;
281317
}
@@ -334,19 +370,7 @@ serf__authn_user__validate_response(const serf__authn_scheme_t *scheme,
334370
request, response,
335371
scratch_pool);
336372

337-
/* Reset pipelining if the scheme requires it. */
338-
if (status == APR_SUCCESS && reset_pipelining
339-
&& !authn_baton->pipelining_reset
340-
&& !(scheme->user_flags & SERF_AUTHN_FLAG_PIPE)) {
341-
serf__log(LOGLVL_DEBUG, LOGCOMP_AUTHN, __FILE__, conn->config,
342-
"User-defined scheme %s: pipelining reset to %s for %s\n",
343-
scheme->name,
344-
authn_baton->pipelining ? "on" : "off",
345-
conn->host_url);
346-
serf__connection_set_pipelining(conn, authn_baton->pipelining);
347-
authn_baton->pipelining_reset = true;
348-
}
349-
373+
maybe_reset_pipelining(scheme, authn_baton, conn, status, reset_pipelining);
350374
apr_pool_destroy(scratch_pool);
351375
return status;
352376
}

serf.h

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -962,19 +962,22 @@ serf_bucket_t *serf_request_bucket_request_create(
962962
* | +<---- authenticate <----+ (401 or 407)
963963
* +<------ init-conn <------+ |
964964
* | | |
965+
* | (pipelining off) <--+ (optional) |
965966
* | (get credentials) <--+ (optional) |
966967
* | | |
967968
* +<-------- handle <-------+ |
968969
* | | |
969-
* | (pipelining off) <--+ (optional) |
970+
* | (reset pipelining) <--+ (optional) |
970971
* | | |
971972
* +<---- setup-requiest <---+ |
973+
* | | |
974+
* | (reset pipelining) <--+ (optional) |
972975
* | +---> request + authn -->+
973976
* | | |
974977
* | +<------ response <------+
975978
* +<-- validate-response <--+ |
976979
* | | |
977-
* | (pipelining on) <--+ (optional) |
980+
* | (reset pipelining) <--+ (optional) |
978981
* | | |
979982
* ```
980983
*/
@@ -1077,12 +1080,22 @@ typedef apr_status_t
10771080
* @a request is the pending request and @a response is the response that
10781081
* caused this callback to be called.
10791082
*
1083+
* If the scheme flag @c SERF_AUTHN_FLAG_PIPE is *not* set, return a boolean
1084+
* value in @a reset_pipelining to indicate whether pipelining on @a conn
1085+
* should be restored to the value before the init-conn callback was invoked.
1086+
* The value of this flag is set to @c false by the caller, so the
1087+
* implementation does not have to modify it if the pipelining state should
1088+
* remain unchanged. This parameter has the same meaning in the
1089+
* serf_authn_setup_request_func_t and serf_authn_validate_response_func_t
1090+
* callbacks and will only take effect the first time its value @c true.
1091+
*
10801092
* Use @a scratch_pool for temporary allocations.
10811093
*
10821094
* @since New in 1.4.
10831095
*/
10841096
typedef apr_status_t
1085-
(*serf_authn_handle_func_t)(void *baton,
1097+
(*serf_authn_handle_func_t)(int *reset_pipelining,
1098+
void *baton,
10861099
void *authn_baton,
10871100
int code,
10881101
const char *authn_header,
@@ -1106,12 +1119,15 @@ typedef apr_status_t
11061119
* @a method and @a uri are the requests attributes and @a headers are the
11071120
* request headers where the credentials are usually set.
11081121
*
1122+
* For the meaning of @a reset_pipelining, see serf_authn_handle_func_t.
1123+
*
11091124
* Use @a scratch_pool for temporary allocations.
11101125
*
11111126
* @since New in 1.4.
11121127
*/
11131128
typedef apr_status_t
1114-
(*serf_authn_setup_request_func_t)(void *baton,
1129+
(*serf_authn_setup_request_func_t)(int *reset_pipelining,
1130+
void *baton,
11151131
void *authn_baton,
11161132
serf_connection_t *conn,
11171133
serf_request_t *request,
@@ -1134,9 +1150,7 @@ typedef apr_status_t
11341150
* response header. This argument will be NULL @a response does not contain
11351151
* one of those headers.
11361152
*
1137-
* If the scheme flag @c SERF_AUTHN_FLAG_PIPE is *not* set, return a boolean
1138-
* value in @a reset_pipelining to indicate whether pipelining on @a conn should
1139-
* be restored to the value before the init-conn callback was invoked.
1153+
* For the meaning of @a reset_pipelining, see serf_authn_handle_func_t.
11401154
*
11411155
* Use @a scratch_pool for temporary allocations.
11421156
*

test/test_auth.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -733,7 +733,8 @@ static apr_status_t user_authn_get_realm(const char **realm_name,
733733
return APR_SUCCESS;
734734
}
735735

736-
static apr_status_t user_authn_handle(void *baton,
736+
static apr_status_t user_authn_handle(int *reset_pipelining,
737+
void *baton,
737738
void *authn_baton,
738739
int code,
739740
const char *authn_header,
@@ -753,10 +754,12 @@ static apr_status_t user_authn_handle(void *baton,
753754
ab->header = apr_pstrdup(result_pool, response_header);
754755
ab->value = apr_pstrcat(result_pool, b->name, " ", password, NULL);
755756

757+
*reset_pipelining = 1;
756758
return APR_SUCCESS;
757759
}
758760

759-
static apr_status_t user_authn_setup_request(void *baton,
761+
static apr_status_t user_authn_setup_request(int *reset_pipelining,
762+
void *baton,
760763
void *authn_baton,
761764
serf_connection_t *conn,
762765
serf_request_t *request,
@@ -777,6 +780,8 @@ static apr_status_t user_authn_setup_request(void *baton,
777780
ab->header, ab->value);
778781

779782
serf_bucket_headers_setn(headers, ab->header, ab->value);
783+
784+
*reset_pipelining = 1;
780785
return APR_SUCCESS;
781786
}
782787

0 commit comments

Comments
 (0)