<commit_before>/*
 * Copyright (c) 2017 <NAME>, Fastly, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */
#ifndef h2o__httpclient_h
#define h2o__httpclient_h

#ifdef __cplusplus
extern "C" {
#endif

#include "quicly.h"
#include "h2o/header.h"
#include "h2o/hostinfo.h"
#include "h2o/http3_common.h"
#include "h2o/send_state.h"
#include "h2o/socket.h"
#include "h2o/socketpool.h"

typedef struct st_h2o_httpclient_t h2o_httpclient_t;

/**
 * Additional properties related to the HTTP request being issued.
 * When the connect callback is being called, the properties of the objects are set to their initial values. Applications MAY alter
 * the properties to achieve desirable behavior. The reason we require the protocol stacks to initialize the values to their default
 * values instead of requiring applications to set all the values correctly is to avoid requiring applications making changes
 * every time a new field is added to the object.
 */
typedef struct st_h2o_httpclient_properties_t {
    /**
     * When the value is a non-NULL pointer (at the moment, only happens with the HTTP/1 client), the application MAY set it to an
     * iovec pointing to the payload of the PROXY protocol (i.e., the first line).
     */
    h2o_iovec_t *proxy_protocol;
    /**
     * When the value is a non-NULL pointer (at the moment, only happens with the HTTP/1 client), the application MAY set it to 1 to
     * indicate that the request body should be encoded using the chunked transfer-encoding.
     */
    int *chunked;
    /**
     * When the value is a non-NULL pointer (at the moment, only happens with the HTTP/1 client), the application MAY set it to the
     * value of the connection header field to be sent to the server. This can be used for upgrading an HTTP/1.1 connection.
     */
    h2o_iovec_t *connection_header;
} h2o_httpclient_properties_t;

typedef void (*h2o_httpclient_proceed_req_cb)(h2o_httpclient_t *client, size_t written, h2o_send_state_t send_state);
typedef int (*h2o_httpclient_body_cb)(h2o_httpclient_t *client, const char *errstr);
typedef h2o_httpclient_body_cb (*h2o_httpclient_head_cb)(h2o_httpclient_t *client, const char *errstr, int version, int status,
                                                         h2o_iovec_t msg, h2o_header_t *headers, size_t num_headers,
                                                         int header_requires_dup);
/**
 * Called when the protocol stack is ready to issue a request. Application must set all the output parameters (i.e. all except
 * `client`, `errstr`, `origin`) and return a callback that will be called when the protocol stack receives the response headers
 * from the server.
 */
typedef h2o_httpclient_head_cb (*h2o_httpclient_connect_cb)(h2o_httpclient_t *client, const char *errstr, h2o_iovec_t *method,
                                                            h2o_url_t *url, const h2o_header_t **headers, size_t *num_headers,
                                                            h2o_iovec_t *body, h2o_httpclient_proceed_req_cb *proceed_req_cb,
                                                            h2o_httpclient_properties_t *props, h2o_url_t *origin);
typedef int (*h2o_httpclient_informational_cb)(h2o_httpclient_t *client, int version, int status, h2o_iovec_t msg,
                                               h2o_header_t *headers, size_t num_headers);

typedef void (*h2o_httpclient_finish_cb)(h2o_httpclient_t *client);

typedef struct st_h2o_httpclient_connection_pool_t {
    /**
     * used to establish connections and pool those when h1 is used.
     * socketpool is shared among multiple threads while connection pool is dedicated to each thread
     */
    h2o_socketpool_t *socketpool;

    struct {
        h2o_linklist_t conns;
    } http2;

    struct {
        h2o_linklist_t conns;
    } http3;

} h2o_httpclient_connection_pool_t;

typedef struct st_h2o_httpclient_ctx_t {
    h2o_loop_t *loop;
    h2o_multithread_receiver_t *getaddr_receiver;
    uint64_t io_timeout;
    uint64_t connect_timeout;
    uint64_t first_byte_timeout;
    uint64_t *websocket_timeout; /* NULL if upgrade to websocket is not allowed */
    uint64_t keepalive_timeout;  /* only used for http2 for now */
    size_t max_buffer_size;

    struct st_h2o_httpclient_protocol_selector_t {
        struct {
            /**
             * If non-negative, indicates the percentage of requests for which use of HTTP/2 will be attempted. If set to negative,
             * all connections are established with ALPN offering both H1 and H2, then the load is balanced between the different
             * protocol versions. This behavior helps balance the load among a mixture of servers behind a load balancer, some
             * supporting both H1 and H2 and some supporting only H1.
             */
            int8_t http2;
            /**
             * Indicates the percentage of requests for which HTTP/3 should be used. Unlike HTTP/2, this value cannot be negative,
             * because unlike ALPN over TLS over TCP, the choice of the protocol is up to the client.
             */
            int8_t http3;
        } ratio;
        /**
         * Each deficit is initialized to zero, then incremented by the respective percentage, and the protocol corresponding to the
         * one with the highest value is chosen. Then, the chosen variable is decremented by 100.
         */
        int16_t _deficits[4];
    } protocol_selector;

    /**
     * HTTP/2-specific settings
     */
    struct {
        h2o_socket_latency_optimization_conditions_t latency_optimization;
        uint32_t max_concurrent_streams;
    } http2;

    struct {
        /**
         * 1-to-(0|1) relationship; NULL when h3 is not used
         */
        struct st_h2o_quic_ctx_t *ctx;
        /**
         * Optional callback invoked by the HTTP/3 client implementation to obtain information used for resuming a connection. When
         * the connection is to be resumed, the callback should set `*address_token` and `*session_ticket` to a vector that can be
         * freed by calling free (3), as well as writing the resumed transport parameters to `*resumed_tp`. Otherwise,
         * `*address_token`, `*session_ticket`, `*resumed_tp` can be left untouched, and a full handshake will be exercised. The
         * function returns if the operation was successful. When false is returned, the connection attempt is aborted.
         */
        int (*load_session)(struct st_h2o_httpclient_ctx_t *ctx, struct sockaddr *server_addr, const char *server_name,
                            ptls_iovec_t *address_token, ptls_iovec_t *session_ticket, quicly_transport_parameters_t *resumed_tp);
    } http3;

} h2o_httpclient_ctx_t;

typedef struct st_h2o_httpclient_timings_t {
    struct timeval start_at;
    struct timeval request_begin_at;
    struct timeval request_end_at;
    struct timeval response_start_at;
    struct timeval response_end_at;
} h2o_httpclient_timings_t;

/**
 * Properties of a HTTP client connection.
 */
typedef struct st_h2o_httpclient_ssl_properties_t {
    /**
     * TLS properties. Definitions match that returned by corresponding h2o_socket function: `h2o_socket_ssl_*`.
     */
    struct {<commit_msg>fix the struct name too (amends #2539)<commit_after>/*
 * Copyright (c) 2017 <NAME>, Fastly, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */
#ifndef h2o__httpclient_h
#define h2o__httpclient_h

#ifdef __cplusplus
extern "C" {
#endif

#include "quicly.h"
#include "h2o/header.h"
#include "h2o/hostinfo.h"
#include "h2o/http3_common.h"
#include "h2o/send_state.h"
#include "h2o/socket.h"
#include "h2o/socketpool.h"

typedef struct st_h2o_httpclient_t h2o_httpclient_t;

/**
 * Additional properties related to the HTTP request being issued.
 * When the connect callback is being called, the properties of the objects are set to their initial values. Applications MAY alter
 * the properties to achieve desirable behavior. The reason we require the protocol stacks to initialize the values to their default
 * values instead of requiring applications to set all the values correctly is to avoid requiring applications making changes
 * every time a new field is added to the object.
 */
typedef struct st_h2o_httpclient_properties_t {
    /**
     * When the value is a non-NULL pointer (at the moment, only happens with the HTTP/1 client), the application MAY set it to an
     * iovec pointing to the payload of the PROXY protocol (i.e., the first line).
     */
    h2o_iovec_t *proxy_protocol;
    /**
     * When the value is a non-NULL pointer (at the moment, only happens with the HTTP/1 client), the application MAY set it to 1 to
     * indicate that the request body should be encoded using the chunked transfer-encoding.
     */
    int *chunked;
    /**
     * When the value is a non-NULL pointer (at the moment, only happens with the HTTP/1 client), the application MAY set it to the
     * value of the connection header field to be sent to the server. This can be used for upgrading an HTTP/1.1 connection.
     */
    h2o_iovec_t *connection_header;
} h2o_httpclient_properties_t;

typedef void (*h2o_httpclient_proceed_req_cb)(h2o_httpclient_t *client, size_t written, h2o_send_state_t send_state);
typedef int (*h2o_httpclient_body_cb)(h2o_httpclient_t *client, const char *errstr);
typedef h2o_httpclient_body_cb (*h2o_httpclient_head_cb)(h2o_httpclient_t *client, const char *errstr, int version, int status,
                                                         h2o_iovec_t msg, h2o_header_t *headers, size_t num_headers,
                                                         int header_requires_dup);
/**
 * Called when the protocol stack is ready to issue a request. Application must set all the output parameters (i.e. all except
 * `client`, `errstr`, `origin`) and return a callback that will be called when the protocol stack receives the response headers
 * from the server.
 */
typedef h2o_httpclient_head_cb (*h2o_httpclient_connect_cb)(h2o_httpclient_t *client, const char *errstr, h2o_iovec_t *method,
                                                            h2o_url_t *url, const h2o_header_t **headers, size_t *num_headers,
                                                            h2o_iovec_t *body, h2o_httpclient_proceed_req_cb *proceed_req_cb,
                                                            h2o_httpclient_properties_t *props, h2o_url_t *origin);
typedef int (*h2o_httpclient_informational_cb)(h2o_httpclient_t *client, int version, int status, h2o_iovec_t msg,
                                               h2o_header_t *headers, size_t num_headers);

typedef void (*h2o_httpclient_finish_cb)(h2o_httpclient_t *client);

typedef struct st_h2o_httpclient_connection_pool_t {
    /**
     * used to establish connections and pool those when h1 is used.
     * socketpool is shared among multiple threads while connection pool is dedicated to each thread
     */
    h2o_socketpool_t *socketpool;

    struct {
        h2o_linklist_t conns;
    } http2;

    struct {
        h2o_linklist_t conns;
    } http3;

} h2o_httpclient_connection_pool_t;

typedef struct st_h2o_httpclient_ctx_t {
    h2o_loop_t *loop;
    h2o_multithread_receiver_t *getaddr_receiver;
    uint64_t io_timeout;
    uint64_t connect_timeout;
    uint64_t first_byte_timeout;
    uint64_t *websocket_timeout; /* NULL if upgrade to websocket is not allowed */
    uint64_t keepalive_timeout;  /* only used for http2 for now */
    size_t max_buffer_size;

    struct st_h2o_httpclient_protocol_selector_t {
        struct {
            /**
             * If non-negative, indicates the percentage of requests for which use of HTTP/2 will be attempted. If set to negative,
             * all connections are established with ALPN offering both H1 and H2, then the load is balanced between the different
             * protocol versions. This behavior helps balance the load among a mixture of servers behind a load balancer, some
             * supporting both H1 and H2 and some supporting only H1.
             */
            int8_t http2;
            /**
             * Indicates the percentage of requests for which HTTP/3 should be used. Unlike HTTP/2, this value cannot be negative,
             * because unlike ALPN over TLS over TCP, the choice of the protocol is up to the client.
             */
            int8_t http3;
        } ratio;
        /**
         * Each deficit is initialized to zero, then incremented by the respective percentage, and the protocol corresponding to the
         * one with the highest value is chosen. Then, the chosen variable is decremented by 100.
         */
        int16_t _deficits[4];
    } protocol_selector;

    /**
     * HTTP/2-specific settings
     */
    struct {
        h2o_socket_latency_optimization_conditions_t latency_optimization;
        uint32_t max_concurrent_streams;
    } http2;

    struct {
        /**
         * 1-to-(0|1) relationship; NULL when h3 is not used
         */
        struct st_h2o_quic_ctx_t *ctx;
        /**
         * Optional callback invoked by the HTTP/3 client implementation to obtain information used for resuming a connection. When
         * the connection is to be resumed, the callback should set `*address_token` and `*session_ticket` to a vector that can be
         * freed by calling free (3), as well as writing the resumed transport parameters to `*resumed_tp`. Otherwise,
         * `*address_token`, `*session_ticket`, `*resumed_tp` can be left untouched, and a full handshake will be exercised. The
         * function returns if the operation was successful. When false is returned, the connection attempt is aborted.
         */
        int (*load_session)(struct st_h2o_httpclient_ctx_t *ctx, struct sockaddr *server_addr, const char *server_name,
                            ptls_iovec_t *address_token, ptls_iovec_t *session_ticket, quicly_transport_parameters_t *resumed_tp);
    } http3;

} h2o_httpclient_ctx_t;

typedef struct st_h2o_httpclient_timings_t {
    struct timeval start_at;
    struct timeval request_begin_at;
    struct timeval request_end_at;
    struct timeval response_start_at;
    struct timeval response_end_at;
} h2o_httpclient_timings_t;

/**
 * Properties of a HTTP client connection.
 */
typedef struct st_h2o_httpclient_conn_properties_t {
    /**
     * TLS properties. Definitions match that returned by corresponding h2o_socket function: `h2o_socket_ssl_*`.
     */
    struct {
{'fraction_non_alphanumeric': 0.06078715441265242, 'fraction_numerical': 0.013763129300977906, 'mean_word_length': 2.9643455372098586, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 24, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6780797', 'n_tokens_mistral': 4776, 'n_tokens_neox': 4614, 'n_words': 1802}