Author: dsahlberg
Date: Sun Dec 14 17:04:51 2025
New Revision: 1930563

Log:
On the SERF-195-branch: sync with trunk @ 1930562

Added:
   serf/branches/SERF-195/test/manual/
      - copied from r1930562, serf/trunk/test/manual/
Modified:
   serf/branches/SERF-195/   (props changed)
   serf/branches/SERF-195/auth/auth_basic.c
   serf/branches/SERF-195/serf.h
   serf/branches/SERF-195/src/outgoing.c
   serf/branches/SERF-195/src/resolve.c
   serf/branches/SERF-195/test/serf_get.c

Modified: serf/branches/SERF-195/auth/auth_basic.c
==============================================================================
--- serf/branches/SERF-195/auth/auth_basic.c    Sun Dec 14 16:02:14 2025        
(r1930562)
+++ serf/branches/SERF-195/auth/auth_basic.c    Sun Dec 14 17:04:51 2025        
(r1930563)
@@ -45,8 +45,6 @@ serf__handle_basic_auth(const serf__auth
                         const char *auth_attr,
                         apr_pool_t *pool)
 {
-    const char *tmp;
-    apr_size_t tmp_len;
     serf_connection_t *conn = request->conn;
     serf_context_t *ctx = conn->ctx;
     serf__authn_info_t *authn_info;
@@ -55,6 +53,7 @@ serf__handle_basic_auth(const serf__auth
     apr_pool_t *scratch_pool;
     apr_hash_t *attr_dict;
     char *username, *password;
+    const char *basic_creds;
     const char *realm_name, *realm = NULL;
 
     /* Can't do Basic authentication if there's no callback to get
@@ -93,14 +92,11 @@ serf__handle_basic_auth(const serf__auth
         return status;
     }
 
-    tmp = apr_pstrcat(conn->pool, username, ":", password, NULL);
-    tmp_len = strlen(tmp);
-    apr_pool_destroy(scratch_pool);
-
-    serf__encode_auth_header(&basic_info->value,
-                             scheme->name,
-                             tmp, tmp_len, pool);
+    basic_creds = apr_pstrcat(scratch_pool, username, ":", password, NULL);
+    serf__encode_auth_header(&basic_info->value, scheme->name,
+                             basic_creds, strlen(basic_creds), pool);
     basic_info->header = SERF__HEADER_FROM_CODE(code);
+    apr_pool_destroy(scratch_pool);
 
     return APR_SUCCESS;
 }

Modified: serf/branches/SERF-195/serf.h
==============================================================================
--- serf/branches/SERF-195/serf.h       Sun Dec 14 16:02:14 2025        
(r1930562)
+++ serf/branches/SERF-195/serf.h       Sun Dec 14 17:04:51 2025        
(r1930563)
@@ -54,12 +54,6 @@ typedef struct serf_incoming_request_t s
 
 typedef struct serf_request_t serf_request_t;
 
-#if 0
-typedef struct serf_connection_type_t serf_connection_type_t;
-typedef struct serf_protocol_t serf_protocol_t;
-typedef struct serf_protocol_type_t serf_protocol_type_t;
-#endif /* Connection and protocol API v2 */
-
 typedef struct serf_config_t serf_config_t;
 
 /**
@@ -470,15 +464,17 @@ typedef apr_status_t (*serf_credentials_
  * destroying this pool will close the connection, and terminate any
  * outstanding requests or responses.
  *
+ * The @a setup callback will be invoked, and @a setup_baton passed to it,
+ * once the connection is actually established. @see serf_connection_setup_t.
+ *
  * When the connection is closed (upon request or because of an error),
  * then the @a closed callback is invoked, and @a closed_baton is passed.
  *
- * ### doc on setup(_baton). tweak below comment re: acceptor.
- * NULL may be passed for @a acceptor and @a closed; default implementations
+ * NULL may be passed for @a setup and @a closed; default implementations
  * will be used.
  *
- * @note The connection is not made immediately. It will be opened on
- * the next call to @see serf_context_run.
+ * @note the connection is not made immediately. It will be opened
+ * asynchronously on the next call to serf_context_run().
  */
 serf_connection_t *serf_connection_create(
     serf_context_t *ctx,
@@ -492,59 +488,37 @@ serf_connection_t *serf_connection_creat
 /**
  * Create a new connection associated with the @a ctx serf context.
  *
- * Like @see serf_connection_create3 but with @a host_address set to @c NULL.
- */
-apr_status_t serf_connection_create2(
-    serf_connection_t **conn,
-    serf_context_t *ctx,
-    apr_uri_t host_info,
-    serf_connection_setup_t setup,
-    void *setup_baton,
-    serf_connection_closed_t closed,
-    void *closed_baton,
-    apr_pool_t *pool);
-
-
-/**
- * Create a new connection associated with the @a ctx serf context.
- *
  * A connection will be created to (eventually) connect to the address
- * specified by @a address. The address must live at least as long as
- * @a pool (thus, as long as the connection object).
- *
- * If @a host_address is @c NULL, the host address will be looked up
- * based on the hostname in @a host_info; otherwise @a host_address
- * will be used to connect and @a host_info will only be used for
- * setting request headers.
+ * specified by @a host_info (either directly or through a proxy), which
+ * must live at least as long as @a pool (thus, as long as the connection
+ * object). The @a host_info will also be used for setting request headers.
  *
  * The connection object will be allocated within @a pool. Clearing or
  * destroying this pool will close the connection, and terminate any
  * outstanding requests or responses.
  *
+ * The @a setup callback will be invoked, and @a setup_baton passed to it,
+ * once the connection is actually established. @see serf_connection_setup_t.
+ *
  * When the connection is closed (upon request or because of an error),
  * then the @a closed callback is invoked, and @a closed_baton is passed.
  *
- * ### doc on setup(_baton). tweak below comment re: acceptor.
- * NULL may be passed for @a acceptor and @a closed; default implementations
+ * NULL may be passed for @a setup and @a closed; default implementations
  * will be used.
  *
- * @note the connection is not made immediately. It will be opened on
- * the next call to @see serf_context_run.
- *
- * @since New in 1.4.
+ * @note The connection is not made immediately. It will be opened
+ * asynchronously on the next call to serf_context_run().
  */
-apr_status_t serf_connection_create3(
+apr_status_t serf_connection_create2(
     serf_connection_t **conn,
     serf_context_t *ctx,
     apr_uri_t host_info,
-    apr_sockaddr_t *host_address,
     serf_connection_setup_t setup,
     void *setup_baton,
     serf_connection_closed_t closed,
     void *closed_baton,
     apr_pool_t *pool);
 
-
 /**
  * Notification callback when an address hae been resolved.
  *
@@ -574,8 +548,11 @@ typedef void (*serf_address_resolved_t)(
  * Asynchronously resolve an address.
  *
  * The address represented by @a host_info is intended to be used to create
- * new connections in @a ctx; proxy configuration will be taken into account
- * during resolution. See, for example, serf_connection_create3().
+ * new connections in @a ctx; see, for example, serf_connection_create().
+ * However, unlike in the connection creation functions, the address will be
+ * resolved regardless of proxy configuration. In order to avoid unnecessary
+ * address resolution, use serf_connection_create_async(), which does take
+ * proxy configuration into account.
  *
  * The @a resolve callback will be called during a subsequent call to
  * serf_context_run() or serf_context_prerun() and will receive the same
@@ -625,14 +602,15 @@ typedef void (*serf_connection_created_t
  * Asyncchronously create a new connection associated with
  * the @a ctx serf context.
  *
- * Like serf_connection_create3() with @a host_address set to @c NULL,
- * except that address resolution is performed asynchronously, similarly to
- * serf_address_resolve_async().
+ * Like serf_connection_create2() except that address resolution is performed
+ * asynchronously, similarly to serf_address_resolve_async(). Address 
resolution
+ * will be skipped if a proxy is configured; in this case, the function becomes
+ * synchronous and effectively equivalent to serf_connection_create2().
  *
  * The @a created callback with @a created_baton is called when the connection
  * is created but before it is opened. Note that depending on the configuration
- * of @a ctx,the connection may be created and this callback be invoked
- * synchronously during the scope of this function call.
+ * of @a ctx and @a host_info, the connection may be created and this callback
+ * be invoked synchronously during the scope of this function call.
  *
  * @since New in 1.4.
  */
@@ -1040,8 +1018,8 @@ serf_bucket_t *serf_context_bucket_socke
  * settings.
  *
  * This function will set following header(s):
- * - Host: if the connection was created with @see serf_connection_create2
- *         or @see serf_connection_create3
+ * - Host: if the connection was created serf_connection_create2()
+ *         or serf_connection_create_async()
  */
 serf_bucket_t *serf_request_bucket_request_create(
     serf_request_t *request,
@@ -1903,241 +1881,6 @@ apr_status_t serf_logging_add_output(ser
                                      const serf_log_output_t *output);
 
 
-/*** Connection and protocol API v2 ***/
-#if 0
-/* ### docco.  */
-apr_status_t serf_connection_switch_protocol(
-    serf_connection_t *conn,
-    serf_protocol_t *proto
-    /* ### other params?  */
-    );
-
-
-/* ### docco.  */
-typedef struct serf_queue_item_t serf_queue_item_t;
-
-
-/**
- * Present a response to the application.
- *
- * Called when a response has been processed by the current protocol (to any
- * extent necessary) and is ready for the application to handle.
- *
- * Note: @a request may be NULL if this response is server-pushed rather than
- *       specifically requested.
- *
- * @since New in 1.4.
- */
-typedef apr_status_t (*serf_begin_response_t)(
-    /* ### args not settled  */
-    void **handler_baton,
-    serf_request_t *request,
-    serf_bucket_t *response,
-    apr_pool_t *scratch_pool);
-
-
-/* ### better name?  */
-typedef apr_status_t (*serf_handler_t)(
-    /* ### args not settled  */
-    void *handler_baton,
-    serf_bucket_t *response,
-    apr_pool_t *scratch_pool);
-
-
-struct serf_protocol_type_t {
-    /** Name of this protocol type.  */
-    const char *name;
-
-    /** Vtable version.  */
-    int version;
-#define SERF_PROTOCOL_TYPE_VERSION 1
-
-    /**
-     * When a pending request reaches the front of the queue, then it becomes
-     * "active". This callback is used to build/provide the protocol-specific
-     * request bucket.
-     *
-     * ### more docco
-     */
-    apr_status_t (*serf_request_activate_t)(
-        serf_bucket_t **request_bkt,
-        serf_queue_item_t *request_qi,
-        void *request_baton,
-        serf_bucket_alloc_t *request_bktalloc,
-        apr_pool_t *scratch_pool);
-
-    /**
-     * Construct a protocol parsing bucket, for passing to the process_data
-     * vtable entry.
-     *
-     * When data arrives on the connection, and a parser is not already
-     * processing the connection's data, then build a new bucket to parse
-     * this incoming data (according to the protocol).
-     */
-    serf_bucket_t * (*build_parser)(serf_protocol_t *proto,
-                                    apr_pool_t *scratch_pool);
-
-    /**
-     * The protocol should parse all available response data, per the protocol.
-     *
-     * This is called when data has become available to the parser. The 
protocol
-     * should read all available data before returning.
-     */
-    apr_status_t (*process_data)(serf_protocol_t *proto,
-                                 serf_bucket_t *parser,
-                                 apr_pool_t *scratch_pool);
-};
-
-
-/**
- * Activate an HTTP request when it reaches the front of the queue.
- *
- * ### more docco
- *
- * @since New in 1.4.
- */
-typedef apr_status_t (*serf_http_activate_t)(
-    serf_bucket_t **body_bkt,
-    serf_bucket_t *request_bkt,  /* type REQUEST  */
-    serf_queue_item_t *request_qi,
-    void *request_baton,
-    serf_bucket_alloc_t *request_bktalloc,
-    apr_pool_t *scratch_pool);
-
-
-/**
- * Create a new connection and associated HTTP protocol parser.
- *
- * The new connection/protocol will be associated with @a ctx. It will be
- * opened once a request is placed into its outgoing queue. The connection
- * will use @a hostname and @a port for the origin server. If
- * @a proxy_hostname is not NULL, then all requests will go through the
- * proxy specified by @a proxy_hostname and @a proxy_port.
- *
- * DNS lookups for @a hostname and @a proxy_hostname will be performed
- * when the connection first opened, then cached in case the connection
- * ever needs to be re-opened.
- *
- * When a queued request reaches the front of the queue, and is ready for
- * delivery, then @a activate_cb will be called to prepare the request.
- *
- * @a authn_types specifies the types of authentication allowed on this
- * connection. Normally, it should be SERF_AUTHN_ALL. When authentication
- * credentials are required (for the origin server or the proxy), then
- * @a creds_cb will be called with @a app_baton.
- *
- * When the connection is closed (upon request or because of an error),
- * then @a closed_cb will be called with @a app_baton.
- *
- * The connection and protocol paresr will be allocated in @a result_pool.
- * This function will use @a scratch_pool for temporary allocations.
- *
- * @since New in 1.4.
- */
-apr_status_t serf_http_protocol_create(
-    serf_protocol_t **proto,
-    serf_context_t *ctx,
-    const char *hostname,
-    int port,
-    const char *proxy_hostname,
-    int proxy_port,
-    int authn_types,
-    serf_http_activate_t activate_cb,
-    /* ### do we need different params for CREDS_CB and CLOSED_CB ?  */
-    serf_credentials_callback_t creds_cb,
-    serf_connection_closed_t closed_cb,
-    void *app_baton,
-    apr_pool_t *result_pool,
-    apr_pool_t *scratch_pool);
-
-
-/* ### docco. create http proto parser with an encrypted connection.  */
-apr_status_t serf_https_protocol_create(
-    serf_protocol_t **proto,
-    serf_context_t *ctx,
-    const char *hostname,
-    int port,
-    /* ### client certs, credential validation callbacks, etc  */
-    serf_connection_closed_t closed,
-    void *closed_baton,
-    apr_pool_t *result_pool,
-    apr_pool_t *scratch_pool);
-
-
-/* ### docco. queue up an http request.  */
-serf_queue_item_t *serf_http_request_queue(
-    serf_protocol_t *proto,
-    int priority,
-    void *request_baton);
-
-/**
- * ### rationalize against "serf connections and request" group above
- *
- * @defgroup serf connections
- * @ingroup serf
- * @{
- */
-
-struct serf_connection_type_t {
-    /** Name of this connection type.  */
-    const char *name;
-
-    /** Vtable version.  */
-    int version;
-#define SERF_CONNECTION_TYPE_VERSION 1
-
-    /**
-     * Initiate a connection to the server.
-     *
-     * ### docco. note async. note that request(s) may be queued.
-     * ### can we somehow defer the SSL tunnel's CONNECT to the higher
-     * ### layer? then have the HTTP protocol layer wrap a CONN_PLAIN
-     * ### into a CONN_TLS connection once the tunnel is established?
-     */
-    apr_status_t (*connect)(serf_connection_t *conn);
-
-    /**
-     * Returns a bucket for reading from this connection.
-     *
-     * This bucket remains constant for the lifetime of the connection. It has
-     * built-in BARRIER bucket protection, so it can safely be "destroyed"
-     * without problem (and a later call to this vtable function will return
-     * the same bucket again).
-     *
-     * For all intents and purposes, this bucket is borrowed by the caller.
-     *
-     * This bucket effectively maps to the underlying socket, or possibly to
-     * a decrypting bucket layered over the socket.
-     */
-    serf_bucket_t * (*get_read_bucket)(serf_connection_t *conn);
-
-    /**
-     * Write some data into into the connection.
-     *
-     * Attempt to write a number of iovecs into the connection. The number of
-     * vectors *completely* written will be returned in @a vecs_written. If 
that
-     * equals @a vecs_size, then @a last_written will be set to 0. If it is 
less
-     * (not all iovecs were written), then the amount written from the next,
-     * incompletely written iovec is returned in @a last_written.
-     *
-     * In other words, the first byte of unwritten content is located at:
-     *
-     * <pre>
-     *   first = vecs[vecs_written][last_written];
-     * </pre>
-     *
-     * If all bytes are written, then APR_SUCCESS is returned. If only a 
portion
-     * was written, then APR_EAGAIN will be returned.
-     */
-    apr_status_t (*writev)(serf_connection_t *conn,
-                           int vecs_size, struct iovec *vecs,
-                           int *vecs_written, apr_size_t *last_written);
-};
-
-#endif /* Connection and protocol API v2 */
-/** @} */
-
-
 /* Internal functions for bucket use and lifecycle tracking.
    ### Some of these are directly or via Macros used by third party
    ### applications, such as Apache Subversion */

Modified: serf/branches/SERF-195/src/outgoing.c
==============================================================================
--- serf/branches/SERF-195/src/outgoing.c       Sun Dec 14 16:02:14 2025        
(r1930562)
+++ serf/branches/SERF-195/src/outgoing.c       Sun Dec 14 17:04:51 2025        
(r1930563)
@@ -1262,33 +1262,15 @@ serf_connection_t *serf_connection_creat
     return conn;
 }
 
-apr_status_t serf_connection_create2(
-    serf_connection_t **conn,
-    serf_context_t *ctx,
-    apr_uri_t host_info,
-    serf_connection_setup_t setup,
-    void *setup_baton,
-    serf_connection_closed_t closed,
-    void *closed_baton,
-    apr_pool_t *pool)
-{
-    return serf_connection_create3(conn, ctx, host_info, NULL,
-                                   setup, setup_baton,
-                                   closed, closed_baton,
-                                   pool);
-}
-
-
-apr_status_t serf_connection_create3(
-    serf_connection_t **conn,
-    serf_context_t *ctx,
-    apr_uri_t host_info,
-    apr_sockaddr_t *host_address,
-    serf_connection_setup_t setup,
-    void *setup_baton,
-    serf_connection_closed_t closed,
-    void *closed_baton,
-    apr_pool_t *pool)
+static apr_status_t create_connection(serf_connection_t **conn,
+                                      serf_context_t *ctx,
+                                      apr_uri_t host_info,
+                                      apr_sockaddr_t *host_address,
+                                      serf_connection_setup_t setup,
+                                      void *setup_baton,
+                                      serf_connection_closed_t closed,
+                                      void *closed_baton,
+                                      apr_pool_t *pool)
 {
     apr_status_t status = APR_SUCCESS;
     serf_config_t *config;
@@ -1346,6 +1328,22 @@ apr_status_t serf_connection_create3(
     return status;
 }
 
+apr_status_t serf_connection_create2(
+    serf_connection_t **conn,
+    serf_context_t *ctx,
+    apr_uri_t host_info,
+    serf_connection_setup_t setup,
+    void *setup_baton,
+    serf_connection_closed_t closed,
+    void *closed_baton,
+    apr_pool_t *pool)
+{
+    return create_connection(conn, ctx, host_info, NULL,
+                             setup, setup_baton,
+                             closed, closed_baton,
+                             pool);
+}
+
 
 struct async_create_baton
 {
@@ -1375,12 +1373,12 @@ static void async_conn_create(serf_conte
                                             baton->conn_pool);
         }
         if (status == APR_SUCCESS) {
-            status = serf_connection_create3(&conn, ctx,
-                                             baton->host_info,
-                                             host_address,
-                                             baton->setup, baton->setup_baton,
-                                             baton->closed, 
baton->closed_baton,
-                                             baton->conn_pool);
+            status = create_connection(&conn, ctx,
+                                       baton->host_info,
+                                       host_address,
+                                       baton->setup, baton->setup_baton,
+                                       baton->closed, baton->closed_baton,
+                                       baton->conn_pool);
         }
     }
 
@@ -1405,14 +1403,14 @@ apr_status_t serf_connection_create_asyn
     if (ctx->proxy_address)
     {
         /* If we're using a proxy, we do *not* resolve the host
-           (see serf_connection_create3(), above), so just create
+           (see create_connection(), above), so just create
            the connection immediately. */
         serf_connection_t *conn;
-        status = serf_connection_create3(&conn, ctx,
-                                         host_info, NULL,
-                                         setup, setup_baton,
-                                         closed, closed_baton,
-                                         pool);
+        status = create_connection(&conn, ctx,
+                                   host_info, NULL,
+                                   setup, setup_baton,
+                                   closed, closed_baton,
+                                   pool);
         if (status == APR_SUCCESS)
             created(ctx, created_baton, conn, status, scratch_pool);
     }

Modified: serf/branches/SERF-195/src/resolve.c
==============================================================================
--- serf/branches/SERF-195/src/resolve.c        Sun Dec 14 16:02:14 2025        
(r1930562)
+++ serf/branches/SERF-195/src/resolve.c        Sun Dec 14 17:04:51 2025        
(r1930563)
@@ -108,16 +108,6 @@ apr_status_t serf_address_resolve_async(
     }
 
     apr_pool_create(&resolve_pool, ctx->pool);
-
-    /* See serf_connection_create3(): if there's a proxy configured in the
-       context, don't resolve the host address, just register the result. */
-    if (ctx->proxy_address)
-    {
-        push_resolve_result(ctx, NULL, APR_SUCCESS,
-                            resolved, resolved_baton, resolve_pool);
-        return APR_SUCCESS;
-    }
-
     return resolve_address_async(ctx, host_info, resolved, resolved_baton,
                                  resolve_pool, pool);
 }

Modified: serf/branches/SERF-195/test/serf_get.c
==============================================================================
--- serf/branches/SERF-195/test/serf_get.c      Sun Dec 14 16:02:14 2025        
(r1930562)
+++ serf/branches/SERF-195/test/serf_get.c      Sun Dec 14 17:04:51 2025        
(r1930563)
@@ -329,6 +329,7 @@ typedef struct handler_baton_t {
     const char *username;
     const char *password;
     int auth_attempts;
+    int conn_count;
     serf_bucket_t *req_hdrs;
 } handler_baton_t;
 
@@ -493,7 +494,8 @@ credentials_callback(char **username,
 {
     handler_baton_t *ctx = baton;
 
-    if (ctx->auth_attempts > 0)
+    /* Every connection should be allowed to connect once. */
+    if (ctx->auth_attempts > ctx->conn_count)
     {
         return SERF_ERROR_AUTHN_FAILED;
     }
@@ -873,6 +875,7 @@ int main(int argc, const char **argv)
     handler_ctx.username = username;
     handler_ctx.password = password;
     handler_ctx.auth_attempts = 0;
+    handler_ctx.conn_count = conn_count;
 
     handler_ctx.req_body_path = req_body_path;
 

Reply via email to