LCOV - code coverage report
Current view: top level - lib - lwan-private.h (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 8 12 66.7 %
Date: 2023-04-18 16:19:03 Functions: 1 2 50.0 %

          Line data    Source code
       1             : /*
       2             :  * lwan - web server
       3             :  * Copyright (c) 2012 L. A. F. Pereira <l@tia.mat.br>
       4             :  *
       5             :  * This program is free software; you can redistribute it and/or
       6             :  * modify it under the terms of the GNU General Public License
       7             :  * as published by the Free Software Foundation; either version 2
       8             :  * of the License, or any later version.
       9             :  *
      10             :  * This program is distributed in the hope that it will be useful,
      11             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             :  * GNU General Public License for more details.
      14             :  *
      15             :  * You should have received a copy of the GNU General Public License
      16             :  * along with this program; if not, write to the Free Software
      17             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
      18             :  */
      19             : 
      20             : #pragma once
      21             : 
      22             : #include <stdlib.h>
      23             : #include <limits.h>
      24             : 
      25             : #include "lwan.h"
      26             : 
      27             : struct lwan_request_parser_helper {
      28             :     struct lwan_value *buffer;          /* The whole request buffer */
      29             :     char *next_request;                 /* For pipelined requests */
      30             : 
      31             :     char **header_start;                /* Headers: n: start, n+1: end */
      32             :     size_t n_header_start;              /* len(header_start) */
      33             : 
      34             :     struct lwan_value accept_encoding;  /* Accept-Encoding: */
      35             : 
      36             :     struct lwan_value query_string;     /* Stuff after ? and before # */
      37             : 
      38             :     struct lwan_value body_data; /* Request body for POST and PUT */
      39             :     struct lwan_value content_type;     /* Content-Type: for POST and PUT */
      40             :     struct lwan_value content_length;   /* Content-Length: */
      41             : 
      42             :     struct lwan_value connection;       /* Connection: */
      43             : 
      44             :     struct lwan_value host;             /* Host: */
      45             : 
      46             :     struct lwan_key_value_array cookies, query_params, post_params;
      47             : 
      48             :     struct { /* If-Modified-Since: */
      49             :         struct lwan_value raw;
      50             :         time_t parsed;
      51             :     } if_modified_since;
      52             : 
      53             :     struct { /* Range: */
      54             :         struct lwan_value raw;
      55             :         off_t from, to;
      56             :     } range;
      57             : 
      58             :     uint64_t request_id;                /* Request ID for debugging purposes */
      59             : 
      60             :     time_t error_when_time;             /* Time to abort request read */
      61             :     int error_when_n_packets;           /* Max. number of packets */
      62             :     int urls_rewritten;                 /* Times URLs have been rewritten */
      63             : };
      64             : 
      65             : #define DEFAULT_BUFFER_SIZE 4096
      66             : #define DEFAULT_HEADERS_SIZE 2048
      67             : 
      68             : #define N_HEADER_START 64
      69             : 
      70             : #define LWAN_CONCAT(a_, b_) a_ ## b_
      71             : #define LWAN_TMP_ID_DETAIL(n_) LWAN_CONCAT(lwan_tmp_id, n_)
      72             : #define LWAN_TMP_ID LWAN_TMP_ID_DETAIL(__COUNTER__)
      73             : 
      74             : #define LWAN_MIN_MAX_DETAIL(a_, b_, name_a_, name_b_, op_)                     \
      75             :     ({                                                                         \
      76             :         const __typeof__((a_) + 0) name_a_ = (a_);                             \
      77             :         const __typeof__((b_) + 0) name_b_ = (b_);                             \
      78             :         name_a_ op_ name_b_ ? name_b_ : name_a_;                               \
      79             :     })
      80             : 
      81             : #define LWAN_MIN(a_, b_) LWAN_MIN_MAX_DETAIL(a_, b_, LWAN_TMP_ID, LWAN_TMP_ID, >)
      82             : 
      83             : #define LWAN_MAX(a_, b_) LWAN_MIN_MAX_DETAIL(a_, b_, LWAN_TMP_ID, LWAN_TMP_ID, <)
      84             : 
      85             : void lwan_set_thread_name(const char *name);
      86             : 
      87             : void lwan_response_init(struct lwan *l);
      88             : void lwan_response_shutdown(struct lwan *l);
      89             : 
      90             : int lwan_create_listen_socket(const struct lwan *l,
      91             :                               bool print_listening_msg,
      92             :                               bool is_https);
      93             : 
      94             : void lwan_thread_init(struct lwan *l);
      95             : void lwan_thread_shutdown(struct lwan *l);
      96             : 
      97             : void lwan_status_init(struct lwan *l);
      98             : void lwan_status_shutdown(struct lwan *l);
      99             : 
     100             : void lwan_job_thread_init(void);
     101             : void lwan_job_thread_main_loop(void);
     102             : void lwan_job_thread_shutdown(void);
     103             : void lwan_job_add(bool (*cb)(void *data), void *data);
     104             : void lwan_job_del(bool (*cb)(void *data), void *data);
     105             : 
     106             : void lwan_tables_init(void);
     107             : void lwan_tables_shutdown(void);
     108             : 
     109             : void lwan_readahead_init(void);
     110             : void lwan_readahead_shutdown(void);
     111             : void lwan_readahead_queue(int fd, off_t off, size_t size);
     112             : void lwan_madvise_queue(void *addr, size_t size);
     113             : 
     114             : char *lwan_strbuf_extend_unsafe(struct lwan_strbuf *s, size_t by);
     115             : 
     116             : void lwan_process_request(struct lwan *l, struct lwan_request *request);
     117             : size_t lwan_prepare_response_header_full(struct lwan_request *request,
     118             :      enum lwan_http_status status, char headers[],
     119             :      size_t headers_buf_size, const struct lwan_key_value *additional_headers);
     120             : 
     121             : void lwan_response(struct lwan_request *request, enum lwan_http_status status);
     122             : void lwan_default_response(struct lwan_request *request,
     123             :                            enum lwan_http_status status);
     124             : void lwan_fill_default_response(struct lwan_strbuf *buffer,
     125             :                                 enum lwan_http_status status);
     126             : 
     127             : 
     128             : const char *lwan_get_config_path(char *path_buf, size_t path_buf_len);
     129             : 
     130             : uint8_t lwan_char_isspace(char ch) __attribute__((pure));
     131             : uint8_t lwan_char_isxdigit(char ch) __attribute__((pure));
     132             : uint8_t lwan_char_isdigit(char ch) __attribute__((pure));
     133             : 
     134             : static ALWAYS_INLINE __attribute__((pure)) size_t lwan_nextpow2(size_t number)
     135             : {
     136             : #if defined(LWAN_HAVE_BUILTIN_CLZLL)
     137             :     static const int size_bits = (int)sizeof(number) * CHAR_BIT;
     138             : 
     139             :     if (sizeof(size_t) == sizeof(unsigned int)) {
     140             :         return (size_t)1 << (size_bits - __builtin_clz((unsigned int)number));
     141             :     } else if (sizeof(size_t) == sizeof(unsigned long)) {
     142        3009 :         return (size_t)1 << (size_bits - __builtin_clzl((unsigned long)number));
     143             :     } else if (sizeof(size_t) == sizeof(unsigned long long)) {
     144             :         return (size_t)1 << (size_bits - __builtin_clzll((unsigned long long)number));
     145             :     } else {
     146             :         (void)size_bits;
     147             :     }
     148             : #endif
     149             : 
     150             :     number--;
     151             :     number |= number >> 1;
     152             :     number |= number >> 2;
     153             :     number |= number >> 4;
     154             :     number |= number >> 8;
     155             :     number |= number >> 16;
     156             : #if __SIZE_WIDTH__ == 64
     157             :     number |= number >> 32;
     158             : #endif
     159             : 
     160             :     return number + 1;
     161             : }
     162             : 
     163             : #if defined(LWAN_HAVE_MBEDTLS)
     164             : #include <mbedtls/ctr_drbg.h>
     165             : #include <mbedtls/entropy.h>
     166             : #include <mbedtls/ssl.h>
     167             : 
     168             : struct lwan_tls_context {
     169             :     mbedtls_ssl_config config;
     170             :     mbedtls_x509_crt server_cert;
     171             :     mbedtls_pk_context server_key;
     172             : 
     173             :     mbedtls_entropy_context entropy;
     174             : 
     175             :     mbedtls_ctr_drbg_context ctr_drbg;
     176             : };
     177             : #endif
     178             : 
     179             : #ifdef LWAN_HAVE_LUA
     180             : #include <lua.h>
     181             : 
     182             : lua_State *lwan_lua_create_state(const char *script_file, const char *script);
     183             : void lwan_lua_state_push_request(lua_State *L, struct lwan_request *request);
     184             : const char *lwan_lua_state_last_error(lua_State *L);
     185             : #endif
     186             : 
     187             : /* This macro is used as an attempt to convince the compiler that it should
     188             :  * never elide an expression -- for instance, when writing fuzz-test or
     189             :  * micro-benchmarks. */
     190             : #define LWAN_NO_DISCARD(...)                                                   \
     191             :     do {                                                                       \
     192             :         __typeof__(__VA_ARGS__) no_discard_ = __VA_ARGS__;                     \
     193             :         __asm__ __volatile__("" ::"g"(no_discard_) : "memory");                \
     194             :     } while (0)
     195             : 
     196           0 : static inline void lwan_always_bzero(void *ptr, size_t len)
     197             : {
     198           0 :     LWAN_NO_DISCARD(memset(ptr, 0, len));
     199           0 : }
     200             : 
     201             : #ifdef __APPLE__
     202             : #define SECTION_START(name_) __start_##name_[] __asm("section$start$__DATA$" #name_)
     203             : #define SECTION_END(name_)   __stop_##name_[] __asm("section$end$__DATA$" #name_)
     204             : #else
     205             : #define SECTION_START(name_) __start_##name_[]
     206             : #define SECTION_END(name_) __stop_##name_[]
     207             : #endif
     208             : 
     209             : #define SECTION_START_SYMBOL(section_name_, iter_)                             \
     210             :     ({                                                                         \
     211             :         extern const typeof(*iter_) SECTION_START(section_name_);              \
     212             :         __start_##section_name_;                                               \
     213             :     })
     214             : 
     215             : #define SECTION_STOP_SYMBOL(section_name_, iter_)                              \
     216             :     ({                                                                         \
     217             :         extern const typeof(*iter_) SECTION_END(section_name_);                \
     218             :         __stop_##section_name_;                                                \
     219             :     })
     220             : 
     221             : #define LWAN_SECTION_FOREACH(section_name_, iter_)                             \
     222             :     for (iter_ = SECTION_START_SYMBOL(section_name_, iter_);                   \
     223             :          iter_ < SECTION_STOP_SYMBOL(section_name_, iter_); (iter_)++)
     224             : 
     225             : extern clockid_t monotonic_clock_id;
     226             : 
     227             : static inline void *
     228       13834 : lwan_aligned_alloc(size_t n, size_t alignment)
     229             : {
     230             :     void *ret;
     231             : 
     232       13834 :     assert((alignment & (alignment - 1)) == 0);
     233       13834 :     assert((alignment % (sizeof(void *))) == 0);
     234             : 
     235       13834 :     n = (n + alignment - 1) & ~(alignment - 1);
     236       13834 :     if (UNLIKELY(posix_memalign(&ret, alignment, n)))
     237           0 :         return NULL;
     238             : 
     239       13834 :     return ret;
     240             : }
     241             : 
     242             : static ALWAYS_INLINE int lwan_calculate_n_packets(size_t total)
     243             : {
     244             :     /* 740 = 1480 (a common MTU) / 2, so that Lwan'll optimistically error out
     245             :      * after ~2x number of expected packets to fully read the request body.*/
     246         334 :     return LWAN_MAX(5, (int)(total / 740));
     247             : }
     248             : 
     249             : long int lwan_getentropy(void *buffer, size_t buffer_len, int flags);
     250             : uint64_t lwan_random_uint64();
     251             : 
     252             : const char *lwan_http_status_as_string(enum lwan_http_status status)
     253             :     __attribute__((const)) __attribute__((warn_unused_result));
     254             : const char *lwan_http_status_as_string_with_code(enum lwan_http_status status)
     255             :     __attribute__((const)) __attribute__((warn_unused_result));
     256             : const char *lwan_http_status_as_descriptive_string(enum lwan_http_status status)
     257             :     __attribute__((const)) __attribute__((warn_unused_result));
     258             : 
     259             : int lwan_connection_get_fd(const struct lwan *lwan,
     260             :                            const struct lwan_connection *conn)
     261             :     __attribute__((pure)) __attribute__((warn_unused_result));
     262             : 
     263             : int lwan_format_rfc_time(const time_t in, char out LWAN_ARRAY_PARAM(30));
     264             : int lwan_parse_rfc_time(const char in LWAN_ARRAY_PARAM(30), time_t *out);
     265             : 
     266             : void lwan_straitjacket_enforce_from_config(struct config *c);
     267             : 
     268             : uint64_t lwan_request_get_id(struct lwan_request *request);
     269             : 
     270             : ssize_t lwan_find_headers(char **header_start, struct lwan_value *buffer,
     271             :                           char **next_request);
     272             : const char *lwan_request_get_header_from_helper(struct lwan_request_parser_helper *helper,
     273             :                                                 const char *header);
     274             : 
     275             : sa_family_t lwan_socket_parse_address(char *listener, char **node, char **port);
     276             : 
     277             : void lwan_request_foreach_header_for_cgi(struct lwan_request *request,
     278             :                                          void (*cb)(const char *header_name,
     279             :                                                     size_t header_len,
     280             :                                                     const char *value,
     281             :                                                     size_t value_len,
     282             :                                                     void *user_data),
     283             :                                          void *user_data);

Generated by: LCOV version 1.15-2-gb9d6727