├── deps └── base64 │ ├── bun-base64.o │ ├── neonbase64 │ ├── neonbase64.o │ ├── chromiumbase64.o │ ├── fastavxbase64.o │ ├── README.md │ ├── bun-base64.h │ ├── fastavxbase64.h │ ├── bun-base64.c │ ├── chromiumbase64.h │ ├── neonbase64.cc │ ├── fastavxbase64.c │ └── chromiumbase64.c ├── scripts ├── link-brew-libs.sh ├── build-zig.sh ├── make-deps.sh ├── build-webkit-macos.sh ├── build-webkit-linux.sh ├── setup-env.sh └── install-webkit-deps-linux.sh ├── package.json ├── .gitignore ├── README.md ├── .gitmodules ├── .github └── workflows │ └── build.yml ├── pkg └── include │ ├── picohttpparser.h │ ├── _libusockets.h │ ├── picohttpparser.c │ └── libuwsockets.cpp └── Makefile /deps/base64/bun-base64.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oven-sh/bun-dependencies/HEAD/deps/base64/bun-base64.o -------------------------------------------------------------------------------- /deps/base64/neonbase64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oven-sh/bun-dependencies/HEAD/deps/base64/neonbase64 -------------------------------------------------------------------------------- /deps/base64/neonbase64.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oven-sh/bun-dependencies/HEAD/deps/base64/neonbase64.o -------------------------------------------------------------------------------- /deps/base64/chromiumbase64.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oven-sh/bun-dependencies/HEAD/deps/base64/chromiumbase64.o -------------------------------------------------------------------------------- /deps/base64/fastavxbase64.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oven-sh/bun-dependencies/HEAD/deps/base64/fastavxbase64.o -------------------------------------------------------------------------------- /scripts/link-brew-libs.sh: -------------------------------------------------------------------------------- 1 | for dir in $BREW_DEPS_DIR/*/ ; do 2 | dir=${dir%*/} 3 | dir="${dir##*/}" 4 | 5 | brew link $dir 6 | done 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Jarred Sumner", 3 | "name": "bun-dependencies", 4 | "files": [ 5 | "/deps/*.a", 6 | "/deps/*.o" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /scripts/build-zig.sh: -------------------------------------------------------------------------------- 1 | cd ./deps 2 | 3 | cmake ./zig 4 | 5 | if [ $? -ne 0 ] ; then 6 | printf "Failed to run cmake command.\n" 7 | exit 1 8 | fi 9 | 10 | cd .. 11 | -------------------------------------------------------------------------------- /deps/base64/README.md: -------------------------------------------------------------------------------- 1 | # Base64 2 | 3 | This uses https://github.com/lemire/fastbase64 4 | 5 | Changes: 6 | 7 | - chromiumbase64 doesn't add a null byte 8 | - chromiumbase64 handles some whitespace characters more loosely 9 | -------------------------------------------------------------------------------- /deps/base64/bun-base64.h: -------------------------------------------------------------------------------- 1 | 2 | #include "chromiumbase64.h" 3 | #include "fastavxbase64.h" 4 | 5 | size_t bun_base64_decode(char *dest, const char *src, size_t len, 6 | size_t *outlen); 7 | size_t bun_base64_encode(char *dest, const char *str, size_t len); -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | deps/*.a 2 | deps/*.o 3 | /bun-webkit 4 | zig-cache 5 | zig-out 6 | .vscode/ 7 | 8 | /pkg/lib/* 9 | /pkg/include/* 10 | 11 | !/pkg/include/_libusockets.h 12 | !/pkg/include/libuwsockets.cpp 13 | !/pkg/include/picohttpparser.c 14 | !/pkg/include/picohttpparser.h 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # bun-dependencies 2 | 3 | Bun is too hard to contribute to right now. The main issue is all the dependencies. Instead of git submodules in the main repository, the plan is to experiment with using prebuilt binary npm packages. This repository will contain the dependencies as submodules, build, and publish them. 4 | -------------------------------------------------------------------------------- /scripts/make-deps.sh: -------------------------------------------------------------------------------- 1 | deps=("tinycc" "lolhtml" "mimalloc" "picohttp" "zlib" "boringssl" "usockets" "uws" "base64" "libarchive" "libbacktrace") 2 | 3 | Red='\033[0;31m' 4 | Green='\033[0;32m' 5 | Yellow='\033[0;33m' 6 | Reset='\033[0m' 7 | 8 | for dependency in "${deps[@]}" 9 | do 10 | printf "${Yellow}$dependency - in progress${Reset}\n" 11 | make $dependency 12 | 13 | if [[ $? -ne 0 ]] ; then 14 | printf "${Red}$dependency - failed${Reset}\n" 15 | exit 1 16 | fi 17 | 18 | printf "${Green}$dependency - done${Reset}\n" 19 | done 20 | -------------------------------------------------------------------------------- /scripts/build-webkit-macos.sh: -------------------------------------------------------------------------------- 1 | if [ "$GH_ACTIONS" != "true" ] ; then 2 | source ./scripts/setup-env.sh 3 | fi 4 | 5 | cd $WEBKIT_DIR 6 | 7 | cmake \ 8 | -DPORT="JSCOnly" \ 9 | -DENABLE_STATIC_JSC=ON \ 10 | -DCMAKE_BUILD_TYPE=$WEBKIT_RELEASE_TYPE \ 11 | -DUSE_THIN_ARCHIVES=OFF \ 12 | -DENABLE_FTL_JIT=ON \ 13 | -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ 14 | -G Ninja \ 15 | -DCMAKE_CXX_COMPILER=$CXX \ 16 | -DCMAKE_C_COMPILER=$CC \ 17 | $WEBKIT_DIR 18 | 19 | if [ $? -ne 0 ] ; then 20 | printf "Failed to build JSC.\n" 21 | exit 1 22 | fi 23 | 24 | CFLAGS="$CFLAGS -ffat-lto-objects" && \ 25 | CXXFLAGS="$CXXFLAGS -ffat-lto-objects" && \ 26 | cmake --build $WEBKIT_DIR --config $WEBKIT_RELEASE_TYPE -- "jsc" -j$(sysctl -n hw.logicalcpu) 27 | 28 | if [ $? -ne 0 ] ; then 29 | printf "Failed to build WebKit.\n" 30 | exit 1 31 | fi 32 | -------------------------------------------------------------------------------- /scripts/build-webkit-linux.sh: -------------------------------------------------------------------------------- 1 | if [ "$GH_ACTIONS" != "true" ] ; then 2 | source ./scripts/setup-env.sh 3 | fi 4 | 5 | # TODO(sno2): add error checks after edgy commands 6 | 7 | cd $WEBKIT_DIR 8 | 9 | cmake \ 10 | -DPORT="JSCOnly" \ 11 | -DENABLE_STATIC_JSC=ON \ 12 | -DCMAKE_BUILD_TYPE=$WEBKIT_RELEASE_TYPE \ 13 | -DUSE_THIN_ARCHIVES=OFF \ 14 | -DENABLE_FTL_JIT=ON \ 15 | -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ 16 | -G Ninja \ 17 | -DCMAKE_CXX_COMPILER=$CXX \ 18 | -DCMAKE_C_COMPILER=$CC \ 19 | $WEBKIT_DIR 20 | 21 | if [ $? -ne 0 ] ; then 22 | printf "Failed to build JSC.\n" 23 | exit 1 24 | fi 25 | 26 | CFLAGS="$CFLAGS -ffat-lto-objects" && \ 27 | CXXFLAGS="$CXXFLAGS -ffat-lto-objects" && \ 28 | cmake --build $WEBKIT_DIR --config $WEBKIT_RELEASE_TYPE -- "jsc" -j$(nproc) 29 | 30 | if [ $? -ne 0 ] ; then 31 | printf "Failed to build WebKit.\n" 32 | exit 1 33 | fi 34 | -------------------------------------------------------------------------------- /scripts/setup-env.sh: -------------------------------------------------------------------------------- 1 | set_env () { 2 | if [ "$GH_ACTIONS" == true ] ; then 3 | echo "$1=$2" >> $GITHUB_ENV 4 | else 5 | export $1=$2 6 | fi 7 | } 8 | 9 | main () { 10 | set_env OS_NAME $(uname -s | tr '[:upper:]' '[:lower:]') 11 | 12 | local BREW_DEPS_DIR_0= 13 | 14 | if [ "$OS_NAME" == "linux" ] ; then 15 | BREW_DEPS_DIR_0="/home/linuxbrew/.linuxbrew/Cellar" 16 | else 17 | BREW_DEPS_DIR_0="/usr/local/Cellar" 18 | fi 19 | 20 | set_env BREW_DEPS_DIR $BREW_DEPS_DIR_0 21 | set_env BUN_PKG $(pwd)/pkg 22 | set_env BUN_PKG_INCLUDE $(pwd)/pkg/include 23 | set_env BUN_PKG_LIB $(pwd)/pkg/lib 24 | 25 | set_env WEBKIT_DIR $(pwd)/deps/WebKit 26 | set_env WEBKIT_RELEASE_TYPE release 27 | 28 | local LLVM_PREFIX_0="$BREW_DEPS_DIR_0/llvm@13/13.0.1" 29 | 30 | set_env LLVM_PREFIX $LLVM_PREFIX_0 31 | set_env CC "$LLVM_PREFIX_0/bin/clang" 32 | set_env CXX "$LLVM_PREFIX_0/bin/clang++" 33 | set_env AR "$LLVM_PREFIX_0/bin/llvm-ar" 34 | } 35 | 36 | main 37 | -------------------------------------------------------------------------------- /deps/base64/fastavxbase64.h: -------------------------------------------------------------------------------- 1 | #if defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) 2 | 3 | #ifndef EXPAVX_B64 4 | #define EXPAVX_B64 5 | 6 | /** 7 | * Assumes recent x64 hardware with AVX2 instructions. 8 | */ 9 | 10 | #include "chromiumbase64.h" 11 | #include 12 | #include 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif /* __cplusplus */ 17 | 18 | /** 19 | * This code extends Nick Galbreath's high performance base 64decoder (used in 20 | * Chromium), the API is the same effectively, see chromium64.h. 21 | */ 22 | 23 | /* 24 | * AVX2 accelerated version of Galbreath's chromium_base64_decode function 25 | * Usage remains the same, see chromium.h. 26 | */ 27 | size_t fast_avx2_base64_decode(char *out, const char *src, size_t srclen, 28 | size_t *outlen); 29 | 30 | /* 31 | * AVX2 accelerated version of Galbreath's chromium_base64_encode function 32 | * Usage remains the same, see chromium.h. 33 | */ 34 | size_t fast_avx2_base64_encode(char *dest, const char *str, size_t len); 35 | 36 | #ifdef __cplusplus 37 | } 38 | #endif /* __cplusplus */ 39 | 40 | #endif 41 | #endif -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "picohttpparser"] 2 | path = deps/picohttpparser 3 | url = https://github.com/h2o/picohttpparser.git 4 | ignore = dirty 5 | depth = 1 6 | [submodule "WebKit"] 7 | path = deps/WebKit 8 | url = https://github.com/Jarred-Sumner/WebKit.git 9 | [submodule "mimalloc"] 10 | path = deps/mimalloc 11 | url = https://github.com/Jarred-Sumner/mimalloc.git 12 | [submodule "zlib"] 13 | path = deps/zlib 14 | url = https://github.com/cloudflare/zlib.git 15 | [submodule "libarchive"] 16 | path = deps/libarchive 17 | url = https://github.com/libarchive/libarchive.git 18 | [submodule "boringssl"] 19 | path = deps/boringssl 20 | url = https://github.com/google/boringssl.git 21 | [submodule "libbacktrace"] 22 | path = deps/libbacktrace 23 | url = https://github.com/ianlancetaylor/libbacktrace 24 | [submodule "lol-html"] 25 | path = deps/lol-html 26 | url = https://github.com/cloudflare/lol-html 27 | [submodule "uws"] 28 | path = deps/uws 29 | url = https://github.com/Jarred-Sumner/uWebSockets 30 | [submodule "tinycc"] 31 | path = deps/tinycc 32 | url = https://github.com/Jarred-Sumner/tinycc.git 33 | [submodule "zig"] 34 | path = deps/zig 35 | url = https://github.com/Jarred-Sumner/zig 36 | -------------------------------------------------------------------------------- /scripts/install-webkit-deps-linux.sh: -------------------------------------------------------------------------------- 1 | apt-get update 2 | 3 | # These are the packages we skip in installation because they're already 4 | # installed. 5 | # 6 | # make \ 7 | # clang-13 \ 8 | # libc++-13-dev \ 9 | # libc++abi-13-dev \ 10 | # libclang-13-dev \ 11 | # liblld-13-dev \ 12 | # lld-13 \ 13 | # ninja-build \ 14 | # curl \ 15 | 16 | # This tries to install clang-format-13.0, then clang-format-13, then clang-format 17 | CLANG_APT_INSTALL_PREFIX="apt-get install --no-install-recommends -y" 18 | $CLANG_APT_INSTALL_PREFIX clang-format-13.0 19 | if [ $? -ne 0 ] ; then 20 | $CLANG_APT_INSTALL_PREFIX clang-format-13 21 | if [ $? -ne 0 ] ; then 22 | $CLANG_APT_INSTALL_PREFIX clang-format 23 | if [ $? -ne 0 ] ; then 24 | printf "Failed to install clang-format.\n" 25 | exit 1 26 | fi 27 | fi 28 | fi 29 | 30 | 31 | apt-get install --no-install-recommends -y \ 32 | bc \ 33 | build-essential \ 34 | ca-certificates \ 35 | cmake \ 36 | cpio \ 37 | file \ 38 | g++ \ 39 | gcc \ 40 | git \ 41 | gnupg2 \ 42 | libicu66 \ 43 | libssl-dev \ 44 | perl \ 45 | python2 \ 46 | rsync \ 47 | ruby \ 48 | ninja-build \ 49 | software-properties-common \ 50 | unzip \ 51 | wget 52 | 53 | if [ $? -ne 0 ] ; then 54 | printf "Failed to install WebKit dependencies for Linux.\n" 55 | exit 1 56 | fi 57 | -------------------------------------------------------------------------------- /deps/base64/bun-base64.c: -------------------------------------------------------------------------------- 1 | 2 | #include "bun-base64.h" 3 | 4 | #if defined(__GNUC__) && defined(__ARM_NEON__) 5 | 6 | int neon_base64_decode(char *out, const char *src, size_t srclen, 7 | size_t *outlen); 8 | 9 | #elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) 10 | 11 | #include "fastavxbase64.h" 12 | 13 | #endif 14 | 15 | #if defined(__GNUC__) && defined(__ARM_NEON__) 16 | size_t bun_base64_decode(char *dest, const char *src, size_t len, 17 | size_t *outlen) { 18 | // neon base64 is decode only 19 | return neon_base64_decode(dest, src, len, outlen); 20 | } 21 | size_t bun_base64_encode(char *dest, const char *src, size_t len) { 22 | return chromium_base64_encode(dest, src, len); 23 | } 24 | 25 | #elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) 26 | 27 | size_t bun_base64_decode(char *dest, const char *src, size_t len, 28 | size_t *outlen) { 29 | return fast_avx2_base64_decode(dest, src, len, outlen); 30 | } 31 | size_t bun_base64_encode(char *dest, const char *src, size_t len) { 32 | 33 | return fast_avx2_base64_encode(dest, src, len); 34 | } 35 | 36 | #else 37 | 38 | size_t bun_base64_decode(char *dest, const char *src, size_t len, 39 | size_t *outlen) { 40 | return chromium_base64_decode(dest, src, len, outlen); 41 | } 42 | size_t bun_base64_encode(char *dest, const char *src, size_t len) { 43 | return chromium_base64_encode(dest, src, len); 44 | } 45 | 46 | #endif -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: CI 4 | 5 | # Controls when the workflow will run 6 | on: 7 | # Triggers the workflow on push or pull request events but only for the "master" branch 8 | push: 9 | branches: [ "master" ] 10 | 11 | # Allows you to run this workflow manually from the Actions tab 12 | workflow_dispatch: 13 | 14 | jobs: 15 | build_x64: 16 | name: ${{ matrix.kind }} ${{ matrix.os }} 17 | runs-on: ${{ matrix.os }} 18 | timeout-minutes: 90 19 | strategy: 20 | matrix: 21 | os: [ubuntu-latest, macOS-latest] 22 | 23 | env: 24 | GH_ACTIONS: true 25 | 26 | steps: 27 | - name: Checkout repository and submodules 28 | uses: actions/checkout@v3 29 | with: 30 | submodules: recursive 31 | 32 | - name: Set Environment Variables (1) 33 | run: source ./scripts/setup-env.sh 34 | 35 | - name: Create Package Directory 36 | run: | 37 | mkdir -p $BUN_PKG_INCLUDE; 38 | mkdir -p $BUN_PKG_LIB 39 | 40 | - name: Cache dependencies 41 | id: cache 42 | uses: actions/cache@v3 43 | with: 44 | path: | 45 | ${{ env.BREW_DEPS_DIR }} 46 | ${{ env.WEBKIT_DIR }} 47 | key: ${{ runner.os }}-cache-dependencies-all 48 | restore-keys: ${{ runner.os }}-cache-dependencies 49 | 50 | - name: Link brew libraries 51 | if: steps.cache.outputs.cache-hit == 'true' 52 | run: ./scripts/link-brew-libs.sh 53 | 54 | - name: Install LLVM 55 | if: steps.cache.outputs.cache-hit != 'true' 56 | run: brew install llvm@13 ncurses s3cmd automake 57 | 58 | # TODO(sno2): find a better way to do this to override old versions set 59 | - name: Set Environment Variables (2) 60 | run: source ./scripts/setup-env.sh 61 | 62 | - name: Install Ninja 63 | if: steps.cache.outputs.cache-hit != 'true' 64 | run: brew install ninja 65 | 66 | - name: Install Rust 67 | uses: hecrj/setup-rust-action@v1 68 | with: 69 | rust-version: "1.62.0" 70 | 71 | - name: Make deps 72 | run: ./scripts/make-deps.sh 73 | 74 | # TODO(sno2): implement caching 75 | - name: Install WebKit Dependencies (linux) 76 | if: matrix.os == 'ubuntu-latest' 77 | run: sudo bash ./scripts/install-webkit-deps-linux.sh 78 | 79 | - name: Build WebKit (linux) 80 | if: matrix.os == 'ubuntu-latest' && steps.cache.outputs.cache-hit != 'true' 81 | run: sudo bash ./scripts/build-webkit-linux.sh 82 | 83 | - name: Build WebKit (macOS) 84 | if: matrix.os == 'macOS-latest' && steps.cache.outputs.cache-hit != 'true' 85 | run: sudo bash ./scripts/build-webkit-macos.sh 86 | -------------------------------------------------------------------------------- /pkg/include/picohttpparser.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2014 Kazuho Oku, Tokuhiro Matsuno, Daisuke Murase, 3 | * Shigeo Mitsunari 4 | * 5 | * The software is licensed under either the MIT License (below) or the Perl 6 | * license. 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to 10 | * deal in the Software without restriction, including without limitation the 11 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 12 | * sell copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 24 | * IN THE SOFTWARE. 25 | */ 26 | 27 | #ifndef picohttpparser_h 28 | #define picohttpparser_h 29 | 30 | #include 31 | 32 | #ifdef _MSC_VER 33 | #define ssize_t intptr_t 34 | #endif 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif 39 | 40 | /* contains name and value of a header (name == NULL if is a continuing line 41 | * of a multiline header */ 42 | struct phr_header { 43 | const char *name; 44 | size_t name_len; 45 | const char *value; 46 | size_t value_len; 47 | }; 48 | 49 | /* returns number of bytes consumed if successful, -2 if request is partial, 50 | * -1 if failed */ 51 | int phr_parse_request(const char *buf, size_t len, const char **method, size_t *method_len, const char **path, size_t *path_len, 52 | int *minor_version, struct phr_header *headers, size_t *num_headers, size_t last_len); 53 | 54 | /* ditto */ 55 | int phr_parse_response(const char *_buf, size_t len, int *minor_version, int *status, const char **msg, size_t *msg_len, 56 | struct phr_header *headers, size_t *num_headers, size_t last_len); 57 | 58 | /* ditto */ 59 | int phr_parse_headers(const char *buf, size_t len, struct phr_header *headers, size_t *num_headers, size_t last_len); 60 | 61 | /* should be zero-filled before start */ 62 | struct phr_chunked_decoder { 63 | size_t bytes_left_in_chunk; /* number of bytes left in current chunk */ 64 | char consume_trailer; /* if trailing headers should be consumed */ 65 | char _hex_count; 66 | char _state; 67 | }; 68 | 69 | /* the function rewrites the buffer given as (buf, bufsz) removing the chunked- 70 | * encoding headers. When the function returns without an error, bufsz is 71 | * updated to the length of the decoded data available. Applications should 72 | * repeatedly call the function while it returns -2 (incomplete) every time 73 | * supplying newly arrived data. If the end of the chunked-encoded data is 74 | * found, the function returns a non-negative number indicating the number of 75 | * octets left undecoded, that starts from the offset returned by `*bufsz`. 76 | * Returns -1 on error. 77 | */ 78 | ssize_t phr_decode_chunked(struct phr_chunked_decoder *decoder, char *buf, size_t *bufsz); 79 | 80 | /* returns if the chunked decoder is in middle of chunked data */ 81 | int phr_decode_chunked_is_in_data(struct phr_chunked_decoder *decoder); 82 | 83 | #ifdef __cplusplus 84 | } 85 | #endif 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /deps/base64/chromiumbase64.h: -------------------------------------------------------------------------------- 1 | /*************** 2 | * Taken more or less as-is from the chromium project 3 | ****************/ 4 | 5 | /** 6 | * \file 7 | *
  8 |  * High performance base64 encoder / decoder
  9 |  * Version 1.3 -- 17-Mar-2006
 10 |  *
 11 |  * Copyright © 2005, 2006, Nick Galbreath -- nickg [at] modp [dot] com
 12 |  * All rights reserved.
 13 |  *
 14 |  * http://modp.com/release/base64
 15 |  *
 16 |  * Released under bsd license.  See modp_b64.c for details.
 17 |  * 
18 | * 19 | * The default implementation is the standard b64 encoding with padding. 20 | * It's easy to change this to use "URL safe" characters and to remove 21 | * padding. See the modp_b64.c source code for details. 22 | * 23 | */ 24 | 25 | #ifndef MODP_B64 26 | #define MODP_B64 27 | 28 | #include 29 | #include 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | #define MODP_B64_ERROR ((size_t)-1) 36 | /** 37 | * Encode a raw binary string into base 64. 38 | * src contains the bytes 39 | * len contains the number of bytes in the src 40 | * dest should be allocated by the caller to contain 41 | * at least chromium_base64_encode_len(len) bytes (see below) 42 | * This will contain the null-terminated b64 encoded result 43 | * returns length of the destination string plus the ending null byte 44 | * i.e. the result will be equal to strlen(dest) + 1 45 | * 46 | * Example 47 | * 48 | * \code 49 | * char* src = ...; 50 | * int srclen = ...; //the length of number of bytes in src 51 | * char* dest = (char*) malloc(chromium_base64_encode_len(srclen)); 52 | * int len = chromium_base64_encode(dest, src, sourcelen); 53 | * if (len == MODP_B64_ERROR) { 54 | * printf("Error\n"); 55 | * } else { 56 | * printf("b64 = %s\n", dest); 57 | * } 58 | * \endcode 59 | * 60 | */ 61 | size_t chromium_base64_encode(char *dest, const char *str, size_t len); 62 | 63 | /** 64 | * Decode a base64 encoded string 65 | * 66 | * 67 | * src should contain exactly len bytes of b64 characters. 68 | * if src contains -any- non-base characters (such as white 69 | * space, MODP_B64_ERROR is returned. 70 | * 71 | * dest should be allocated by the caller to contain at least 72 | * len * 3 / 4 bytes. 73 | * 74 | * Returns the length (strlen) of the output, or MODP_B64_ERROR if unable to 75 | * decode 76 | * 77 | * \code 78 | * char* src = ...; 79 | * int srclen = ...; // or if you don't know use strlen(src) 80 | * char* dest = (char*) malloc(chromium_base64_decode_len(srclen)); 81 | * int len = chromium_base64_decode(dest, src, sourcelen); 82 | * if (len == MODP_B64_ERROR) { error } 83 | * \endcode 84 | */ 85 | size_t chromium_base64_decode(char *dest, const char *src, size_t len, 86 | size_t *out_len); 87 | 88 | /** 89 | * Given a source string of length len, this returns the amount of 90 | * memory the destination string should have. 91 | * 92 | * remember, this is integer math 93 | * 3 bytes turn into 4 chars 94 | * ceiling[len / 3] * 4 + 1 95 | * 96 | * +1 is for any extra null. 97 | */ 98 | #define chromium_base64_encode_len(A) ((A + 2) / 3 * 4 + 1) 99 | 100 | /** 101 | * Given a base64 string of length len, 102 | * this returns the amount of memory required for output string 103 | * It maybe be more than the actual number of bytes written. 104 | * NOTE: remember this is integer math 105 | * this allocates a bit more memory than traditional versions of b64 106 | * decode 4 chars turn into 3 bytes 107 | * floor[len * 3/4] + 2 108 | */ 109 | #define chromium_base64_decode_len(A) (A / 4 * 3 + 2) 110 | 111 | /** 112 | * Will return the strlen of the output from encoding. 113 | * This may be less than the required number of bytes allocated. 114 | * 115 | * This allows you to 'deserialized' a struct 116 | * \code 117 | * char* b64encoded = "..."; 118 | * int len = strlen(b64encoded); 119 | * 120 | * struct datastuff foo; 121 | * if (chromium_base64_encode_strlen(sizeof(struct datastuff)) != len) { 122 | * // wrong size 123 | * return false; 124 | * } else { 125 | * // safe to do; 126 | * if (chromium_base64_encode((char*) &foo, b64encoded, len) == 127 | * MODP_B64_ERROR) { 128 | * // bad characters 129 | * return false; 130 | * } 131 | * } 132 | * // foo is filled out now 133 | * \endcode 134 | */ 135 | #define chromium_base64_encode_strlen(A) ((A + 2) / 3 * 4) 136 | 137 | #ifdef __cplusplus 138 | } 139 | 140 | #include 141 | 142 | /** 143 | * base 64 decode a string (self-modifing) 144 | * On failure, the string is empty. 145 | * 146 | * This function is for C++ only (duh) 147 | * 148 | * \param[in,out] s the string to be decoded 149 | * \return a reference to the input string 150 | */ 151 | inline std::string &chromium_base64_encode(std::string &s) { 152 | std::string x(chromium_base64_encode_len(s.size()), '\0'); 153 | size_t d = chromium_base64_encode(const_cast(x.data()), s.data(), 154 | (int)s.size()); 155 | if (d == MODP_B64_ERROR) { 156 | x.clear(); 157 | } else { 158 | x.erase(d, std::string::npos); 159 | } 160 | s.swap(x); 161 | return s; 162 | } 163 | 164 | #endif /* __cplusplus */ 165 | #endif -------------------------------------------------------------------------------- /deps/base64/neonbase64.cc: -------------------------------------------------------------------------------- 1 | // clang-format off 2 | #if defined (__GNUC__) && defined(__ARM_NEON__) 3 | 4 | #include 5 | #include 6 | #include "chromiumbase64.h" 7 | #define MODP_B64_ERROR ((size_t)-1) 8 | 9 | // #include 10 | 11 | 12 | extern "C" int neon_base64_decode(char *out, const char *src, size_t srclen, size_t *outlen); 13 | 14 | 15 | // The input consists of six character sets in the Base64 alphabet, 16 | // which we need to map back to the 6-bit values they represent. 17 | // There are three ranges, two singles, and then there's the rest. 18 | // 19 | // # From To Add Characters 20 | // 1 [43] [62] +19 + 21 | // 2 [47] [63] +16 / 22 | // 3 [48..57] [52..61] +4 0..9 23 | // 4 [65..90] [0..25] -65 A..Z 24 | // 5 [97..122] [26..51] -71 a..z 25 | // (6) Everything else => invalid input 26 | 27 | int neon_base64_decode(char *out, const char *src, size_t srclen, size_t *outlen) { 28 | char *out_orig = out; 29 | const uint8x16_t lut_lo = {0x15, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 30 | 0x11, 0x11, 0x13, 0x1A, 0x1B, 0x1B, 0x1B, 0x1A}; 31 | const uint8x16_t lut_hi = {0x10, 0x10, 0x01, 0x02, 0x04, 0x08, 0x04, 0x08, 32 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10}; 33 | const uint8x16_t lut_roll = {0, 16, 19, 4, 191, 191, 185, 185, 34 | 0, 0, 0, 0, 0, 0, 0, 0}; 35 | const uint8x16_t zero8 = vdupq_n_u8(0); 36 | const uint16x8_t zero16 = vdupq_n_u16(0); 37 | const uint8x16_t k2f = vdupq_n_u8(0x2f); 38 | const uint8x16_t kf = vdupq_n_u8(0xf); 39 | const uint8x8_t cst = {0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}; 40 | const uint16x4_t cst1 = {0x1000, 0x1000, 0x1000, 0x1000}; 41 | 42 | const uint8x8_t shuf0 = {2, 1, 0, 6, 5, 4, 2 + 8, 1 + 8}; 43 | const uint8x8_t shuf1 = {0 + 8, 6 + 8, 5 + 8, 4 + 8, 44 | 2 + 16, 1 + 16, 0 + 16, 6 + 16}; 45 | const uint8x8_t shuf2 = {5 + 16, 4 + 16, 2 + 24, 1 + 24, 46 | 0 + 24, 6 + 24, 5 + 24, 4 + 24}; 47 | 48 | uint8x8x4_t pack; 49 | uint8x8_t res[3]; 50 | uint8x16_t str[2]; 51 | 52 | while (srclen >= 8 * 4) { 53 | __builtin_memcpy(str, src, 8 * 4); 54 | 55 | uint8x16_t in0 = str[0]; 56 | uint8x16_t in1 = str[1]; 57 | uint8x16_t lo_nibbles0 = vandq_u8(in0, kf); 58 | uint8x16_t lo_nibbles1 = vandq_u8(in1, kf); 59 | uint8x16_t hi_nibbles0 = vshrq_n_u8(in0, 4); 60 | uint8x16_t hi_nibbles1 = vshrq_n_u8(in1, 4); 61 | 62 | uint8x16_t lo0 = vqtbl1q_u8(lut_lo, lo_nibbles0); 63 | uint8x16_t lo1 = vqtbl1q_u8(lut_lo, lo_nibbles1); 64 | uint8x16_t hi0 = vqtbl1q_u8(lut_hi, hi_nibbles0); 65 | uint8x16_t hi1 = vqtbl1q_u8(lut_hi, hi_nibbles1); 66 | uint8x16_t test0 = vtstq_u8(lo0, hi0); 67 | uint8x16_t test1 = vtstq_u8(lo1, hi1); 68 | uint8x16_t orr0 = vorrq_u8(test0, test1); 69 | uint8x8_t orr1 = vorr_u8(vget_low_u8(orr0), vget_high_u8(orr0)); 70 | if ((uint64_t)orr1) 71 | break; 72 | 73 | uint8x16_t eq_2F0 = vceqq_u8(in0, k2f); 74 | uint8x16_t eq_2F1 = vceqq_u8(in1, k2f); 75 | uint8x16_t add0 = vaddq_u8(eq_2F0, hi_nibbles0); 76 | uint8x16_t add1 = vaddq_u8(eq_2F1, hi_nibbles1); 77 | uint8x16_t roll0 = vqtbl1q_u8(lut_roll, add0); 78 | uint8x16_t roll1 = vqtbl1q_u8(lut_roll, add1); 79 | uint8x16_t rolled0 = vaddq_u8(in0, roll0); 80 | uint8x16_t rolled1 = vaddq_u8(in1, roll1); 81 | 82 | // Step 1: swap and merge adjacent 6-bit fields. 83 | uint8x16x2_t unzip8 = vuzpq_u8(rolled0, rolled1); 84 | uint8x16x2_t zip8 = vzipq_u8(unzip8.val[1], zero8); 85 | uint16x8_t mul0 = vmlal_u8(vreinterpretq_u16_u8(zip8.val[0]), 86 | vget_low_u8(unzip8.val[0]), cst); 87 | uint16x8_t mul1 = vmlal_u8(vreinterpretq_u16_u8(zip8.val[1]), 88 | vget_high_u8(unzip8.val[0]), cst); 89 | 90 | // Step 2: swap and merge 12-bit words into a 24-bit word. 91 | uint16x8x2_t unzip16 = vuzpq_u16(mul0, mul1); 92 | uint16x8x2_t zip16 = vzipq_u16(unzip16.val[1], zero16); 93 | uint32x4_t merge0 = vmlal_u16(vreinterpretq_u32_u16(zip16.val[0]), 94 | vget_low_u16(unzip16.val[0]), cst1); 95 | uint32x4_t merge1 = vmlal_u16(vreinterpretq_u32_u16(zip16.val[1]), 96 | vget_high_u16(unzip16.val[0]), cst1); 97 | pack.val[0] = vget_low_u8(vreinterpretq_u8_u32(merge0)); 98 | pack.val[1] = vget_high_u8(vreinterpretq_u8_u32(merge0)); 99 | pack.val[2] = vget_low_u8(vreinterpretq_u8_u32(merge1)); 100 | pack.val[3] = vget_high_u8(vreinterpretq_u8_u32(merge1)); 101 | 102 | res[0] = vtbl4_u8(pack, shuf0); 103 | res[1] = vtbl4_u8(pack, shuf1); 104 | res[2] = vtbl4_u8(pack, shuf2); 105 | __builtin_memcpy(out, res, 6 * 4); 106 | 107 | out += 6 * 4; 108 | srclen -= 8 * 4; 109 | src += 8 * 4; 110 | } 111 | 112 | // std::cout << "Chromium? " << (out - out_orig) << std::endl; 113 | size_t scalarret = chromium_base64_decode(out, src, srclen, outlen); 114 | *outlen += (out - out_orig); 115 | if (scalarret == MODP_B64_ERROR) 116 | return (int)MODP_B64_ERROR; 117 | return (out - out_orig) + scalarret; 118 | } 119 | 120 | #endif -------------------------------------------------------------------------------- /deps/base64/fastavxbase64.c: -------------------------------------------------------------------------------- 1 | #if defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) 2 | #include "fastavxbase64.h" 3 | 4 | #include 5 | #include 6 | 7 | /** 8 | * This code borrows from Wojciech Mula's library at 9 | * https://github.com/WojciechMula/base64simd (published under BSD) 10 | * as well as code from Alfred Klomp's library https://github.com/aklomp/base64 11 | * (published under BSD) 12 | * 13 | */ 14 | 15 | /** 16 | * Note : Hardware such as Knights Landing might do poorly with this AVX2 code 17 | * since it relies on shuffles. Alternatives might be faster. 18 | */ 19 | 20 | static inline __m256i enc_reshuffle(const __m256i input) { 21 | 22 | // translation from SSE into AVX2 of procedure 23 | // https://github.com/WojciechMula/base64simd/blob/master/encode/unpack_bigendian.cpp 24 | const __m256i in = _mm256_shuffle_epi8( 25 | input, 26 | _mm256_set_epi8(10, 11, 9, 10, 7, 8, 6, 7, 4, 5, 3, 4, 1, 2, 0, 1, 27 | 28 | 14, 15, 13, 14, 11, 12, 10, 11, 8, 9, 7, 8, 5, 6, 4, 5)); 29 | 30 | const __m256i t0 = _mm256_and_si256(in, _mm256_set1_epi32(0x0fc0fc00)); 31 | const __m256i t1 = _mm256_mulhi_epu16(t0, _mm256_set1_epi32(0x04000040)); 32 | 33 | const __m256i t2 = _mm256_and_si256(in, _mm256_set1_epi32(0x003f03f0)); 34 | const __m256i t3 = _mm256_mullo_epi16(t2, _mm256_set1_epi32(0x01000010)); 35 | 36 | return _mm256_or_si256(t1, t3); 37 | } 38 | 39 | static inline __m256i enc_translate(const __m256i in) { 40 | const __m256i lut = _mm256_setr_epi8( 41 | 65, 71, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -19, -16, 0, 0, 65, 71, 42 | -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -19, -16, 0, 0); 43 | __m256i indices = _mm256_subs_epu8(in, _mm256_set1_epi8(51)); 44 | __m256i mask = _mm256_cmpgt_epi8((in), _mm256_set1_epi8(25)); 45 | indices = _mm256_sub_epi8(indices, mask); 46 | __m256i out = _mm256_add_epi8(in, _mm256_shuffle_epi8(lut, indices)); 47 | return out; 48 | } 49 | 50 | static inline __m256i dec_reshuffle(__m256i in) { 51 | 52 | // inlined procedure pack_madd from 53 | // https://github.com/WojciechMula/base64simd/blob/master/decode/pack.avx2.cpp 54 | // The only difference is that elements are reversed, 55 | // only the multiplication constants were changed. 56 | 57 | const __m256i merge_ab_and_bc = _mm256_maddubs_epi16( 58 | in, 59 | _mm256_set1_epi32(0x01400140)); //_mm256_maddubs_epi16 is likely expensive 60 | __m256i out = 61 | _mm256_madd_epi16(merge_ab_and_bc, _mm256_set1_epi32(0x00011000)); 62 | // end of inlined 63 | 64 | // Pack bytes together within 32-bit words, discarding words 3 and 7: 65 | out = _mm256_shuffle_epi8(out, _mm256_setr_epi8(2, 1, 0, 6, 5, 4, 10, 9, 8, 66 | 14, 13, 12, -1, -1, -1, -1, 2, 67 | 1, 0, 6, 5, 4, 10, 9, 8, 14, 68 | 13, 12, -1, -1, -1, -1)); 69 | // the call to _mm256_permutevar8x32_epi32 could be replaced by a call to 70 | // _mm256_storeu2_m128i but it is doubtful that it would help 71 | return _mm256_permutevar8x32_epi32( 72 | out, _mm256_setr_epi32(0, 1, 2, 4, 5, 6, -1, -1)); 73 | } 74 | 75 | size_t fast_avx2_base64_encode(char *dest, const char *str, size_t len) { 76 | const char *const dest_orig = dest; 77 | if (len >= 32 - 4) { 78 | // first load is masked 79 | __m256i inputvector = _mm256_maskload_epi32( 80 | (int const *)(str - 4), 81 | _mm256_set_epi32(0x80000000, 0x80000000, 0x80000000, 0x80000000, 82 | 83 | 0x80000000, 0x80000000, 0x80000000, 84 | 0x00000000 // we do not load the first 4 bytes 85 | )); 86 | ////////// 87 | // Intel docs: Faults occur only due to mask-bit required memory accesses 88 | // that caused the faults. Faults will not occur due to referencing any 89 | // memory location if the corresponding mask bit for 90 | // that memory location is 0. For example, no faults will be detected if the 91 | // mask bits are all zero. 92 | //////////// 93 | while (true) { 94 | inputvector = enc_reshuffle(inputvector); 95 | inputvector = enc_translate(inputvector); 96 | _mm256_storeu_si256((__m256i *)dest, inputvector); 97 | str += 24; 98 | dest += 32; 99 | len -= 24; 100 | if (len >= 32) { 101 | inputvector = 102 | _mm256_loadu_si256((__m256i *)(str - 4)); // no need for a mask here 103 | // we could do a mask load as long as len >= 24 104 | } else { 105 | break; 106 | } 107 | } 108 | } 109 | size_t scalarret = chromium_base64_encode(dest, str, len); 110 | if (scalarret == MODP_B64_ERROR) 111 | return MODP_B64_ERROR; 112 | return (dest - dest_orig) + scalarret; 113 | } 114 | 115 | size_t fast_avx2_base64_decode(char *out, const char *src, size_t srclen, 116 | size_t *outlen) { 117 | char *out_orig = out; 118 | while (srclen >= 45) { 119 | 120 | // The input consists of six character sets in the Base64 alphabet, 121 | // which we need to map back to the 6-bit values they represent. 122 | // There are three ranges, two singles, and then there's the rest. 123 | // 124 | // # From To Add Characters 125 | // 1 [43] [62] +19 + 126 | // 2 [47] [63] +16 / 127 | // 3 [48..57] [52..61] +4 0..9 128 | // 4 [65..90] [0..25] -65 A..Z 129 | // 5 [97..122] [26..51] -71 a..z 130 | // (6) Everything else => invalid input 131 | 132 | __m256i str = _mm256_loadu_si256((__m256i *)src); 133 | 134 | // code by @aqrit from 135 | // https://github.com/WojciechMula/base64simd/issues/3#issuecomment-271137490 136 | // transated into AVX2 137 | const __m256i lut_lo = _mm256_setr_epi8( 138 | 0x15, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x13, 0x1A, 139 | 0x1B, 0x1B, 0x1B, 0x1A, 0x15, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 140 | 0x11, 0x11, 0x13, 0x1A, 0x1B, 0x1B, 0x1B, 0x1A); 141 | const __m256i lut_hi = _mm256_setr_epi8( 142 | 0x10, 0x10, 0x01, 0x02, 0x04, 0x08, 0x04, 0x08, 0x10, 0x10, 0x10, 0x10, 143 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x01, 0x02, 0x04, 0x08, 0x04, 0x08, 144 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10); 145 | const __m256i lut_roll = _mm256_setr_epi8( 146 | 0, 16, 19, 4, -65, -65, -71, -71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 19, 4, 147 | -65, -65, -71, -71, 0, 0, 0, 0, 0, 0, 0, 0); 148 | 149 | const __m256i mask_2F = _mm256_set1_epi8(0x2f); 150 | 151 | // lookup 152 | __m256i hi_nibbles = _mm256_srli_epi32(str, 4); 153 | __m256i lo_nibbles = _mm256_and_si256(str, mask_2F); 154 | 155 | const __m256i lo = _mm256_shuffle_epi8(lut_lo, lo_nibbles); 156 | const __m256i eq_2F = _mm256_cmpeq_epi8(str, mask_2F); 157 | 158 | hi_nibbles = _mm256_and_si256(hi_nibbles, mask_2F); 159 | const __m256i hi = _mm256_shuffle_epi8(lut_hi, hi_nibbles); 160 | const __m256i roll = 161 | _mm256_shuffle_epi8(lut_roll, _mm256_add_epi8(eq_2F, hi_nibbles)); 162 | 163 | if (!_mm256_testz_si256(lo, hi)) { 164 | break; 165 | } 166 | 167 | str = _mm256_add_epi8(str, roll); 168 | // end of copied function 169 | 170 | srclen -= 32; 171 | src += 32; 172 | 173 | // end of inlined function 174 | 175 | // Reshuffle the input to packed 12-byte output format: 176 | str = dec_reshuffle(str); 177 | _mm256_storeu_si256((__m256i *)out, str); 178 | out += 24; 179 | } 180 | size_t scalarret = chromium_base64_decode(out, src, srclen, outlen); 181 | *outlen += (out - out_orig); 182 | if (scalarret == MODP_B64_ERROR) 183 | return MODP_B64_ERROR; 184 | return (out - out_orig) + scalarret; 185 | } 186 | #endif -------------------------------------------------------------------------------- /pkg/include/_libusockets.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef LIBUWS_CAPI_HEADER 4 | #define LIBUWS_CAPI_HEADER 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #ifndef STRING_POINTER 11 | #define STRING_POINTER 12 | typedef struct StringPointer { 13 | uint32_t off; 14 | uint32_t len; 15 | } StringPointer; 16 | #endif 17 | 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | 22 | typedef enum { 23 | /* These are not actual compression options */ 24 | _COMPRESSOR_MASK = 0x00FF, 25 | _DECOMPRESSOR_MASK = 0x0F00, 26 | /* Disabled, shared, shared are "special" values */ 27 | DISABLED = 0, 28 | SHARED_COMPRESSOR = 1, 29 | SHARED_DECOMPRESSOR = 1 << 8, 30 | /* Highest 4 bits describe decompressor */ 31 | DEDICATED_DECOMPRESSOR_32KB = 15 << 8, 32 | DEDICATED_DECOMPRESSOR_16KB = 14 << 8, 33 | DEDICATED_DECOMPRESSOR_8KB = 13 << 8, 34 | DEDICATED_DECOMPRESSOR_4KB = 12 << 8, 35 | DEDICATED_DECOMPRESSOR_2KB = 11 << 8, 36 | DEDICATED_DECOMPRESSOR_1KB = 10 << 8, 37 | DEDICATED_DECOMPRESSOR_512B = 9 << 8, 38 | /* Same as 32kb */ 39 | DEDICATED_DECOMPRESSOR = 15 << 8, 40 | 41 | /* Lowest 8 bit describe compressor */ 42 | DEDICATED_COMPRESSOR_3KB = 9 << 4 | 1, 43 | DEDICATED_COMPRESSOR_4KB = 9 << 4 | 2, 44 | DEDICATED_COMPRESSOR_8KB = 10 << 4 | 3, 45 | DEDICATED_COMPRESSOR_16KB = 11 << 4 | 4, 46 | DEDICATED_COMPRESSOR_32KB = 12 << 4 | 5, 47 | DEDICATED_COMPRESSOR_64KB = 13 << 4 | 6, 48 | DEDICATED_COMPRESSOR_128KB = 14 << 4 | 7, 49 | DEDICATED_COMPRESSOR_256KB = 15 << 4 | 8, 50 | /* Same as 256kb */ 51 | DEDICATED_COMPRESSOR = 15 << 4 | 8 52 | } uws_compress_options_t; 53 | 54 | typedef enum { 55 | CONTINUATION = 0, 56 | TEXT = 1, 57 | BINARY = 2, 58 | CLOSE = 8, 59 | PING = 9, 60 | PONG = 10 61 | } uws_opcode_t; 62 | 63 | typedef enum { BACKPRESSURE, SUCCESS, DROPPED } uws_sendstatus_t; 64 | 65 | typedef struct { 66 | 67 | int port; 68 | const char *host; 69 | int options; 70 | } uws_app_listen_config_t; 71 | 72 | struct uws_app_s; 73 | struct uws_req_s; 74 | struct uws_res_s; 75 | struct uws_websocket_s; 76 | struct uws_header_iterator_s; 77 | typedef struct uws_app_s uws_app_t; 78 | typedef struct uws_req_s uws_req_t; 79 | typedef struct uws_res_s uws_res_t; 80 | typedef struct uws_socket_context_s uws_socket_context_t; 81 | typedef struct uws_websocket_s uws_websocket_t; 82 | 83 | typedef void (*uws_websocket_handler)(uws_websocket_t *ws); 84 | typedef void (*uws_websocket_message_handler)(uws_websocket_t *ws, 85 | const char *message, 86 | size_t length, 87 | uws_opcode_t opcode); 88 | typedef void (*uws_websocket_ping_pong_handler)(uws_websocket_t *ws, 89 | const char *message, 90 | size_t length); 91 | typedef void (*uws_websocket_close_handler)(uws_websocket_t *ws, int code, 92 | const char *message, size_t length); 93 | typedef void (*uws_websocket_upgrade_handler)(uws_res_t *response, 94 | uws_req_t *request, 95 | uws_socket_context_t *context); 96 | 97 | typedef struct { 98 | uws_compress_options_t compression; 99 | /* Maximum message size we can receive */ 100 | unsigned int maxPayloadLength; 101 | /* 2 minutes timeout is good */ 102 | unsigned short idleTimeout; 103 | /* 64kb backpressure is probably good */ 104 | unsigned int maxBackpressure; 105 | bool closeOnBackpressureLimit; 106 | /* This one depends on kernel timeouts and is a bad default */ 107 | bool resetIdleTimeoutOnSend; 108 | /* A good default, esp. for newcomers */ 109 | bool sendPingsAutomatically; 110 | /* Maximum socket lifetime in seconds before forced closure (defaults to 111 | * disabled) */ 112 | unsigned short maxLifetime; 113 | 114 | uws_websocket_upgrade_handler upgrade; 115 | uws_websocket_handler open; 116 | uws_websocket_message_handler message; 117 | uws_websocket_handler drain; 118 | uws_websocket_ping_pong_handler ping; 119 | uws_websocket_ping_pong_handler pong; 120 | uws_websocket_close_handler close; 121 | } uws_socket_behavior_t; 122 | 123 | typedef void (*uws_listen_handler)(struct us_listen_socket_t *listen_socket, 124 | uws_app_listen_config_t config, 125 | void *user_data); 126 | typedef void (*uws_method_handler)(uws_res_t *response, uws_req_t *request, 127 | void *user_data); 128 | typedef void (*uws_filter_handler)(uws_res_t *response, int, void *user_data); 129 | typedef void (*uws_missing_server_handler)(const char *hostname, 130 | void *user_data); 131 | // Basic HTTP 132 | uws_app_t *uws_create_app(int ssl, struct us_socket_context_options_t options); 133 | void uws_app_destroy(int ssl, uws_app_t *app); 134 | void uws_app_get(int ssl, uws_app_t *app, const char *pattern, 135 | uws_method_handler handler, void *user_data); 136 | void uws_app_post(int ssl, uws_app_t *app, const char *pattern, 137 | uws_method_handler handler, void *user_data); 138 | void uws_app_options(int ssl, uws_app_t *app, const char *pattern, 139 | uws_method_handler handler, void *user_data); 140 | void uws_app_delete(int ssl, uws_app_t *app, const char *pattern, 141 | uws_method_handler handler, void *user_data); 142 | void uws_app_patch(int ssl, uws_app_t *app, const char *pattern, 143 | uws_method_handler handler, void *user_data); 144 | void uws_app_put(int ssl, uws_app_t *app, const char *pattern, 145 | uws_method_handler handler, void *user_data); 146 | void uws_app_head(int ssl, uws_app_t *app, const char *pattern, 147 | uws_method_handler handler, void *user_data); 148 | void uws_app_connect(int ssl, uws_app_t *app, const char *pattern, 149 | uws_method_handler handler, void *user_data); 150 | void uws_app_trace(int ssl, uws_app_t *app, const char *pattern, 151 | uws_method_handler handler, void *user_data); 152 | void uws_app_any(int ssl, uws_app_t *app, const char *pattern, 153 | uws_method_handler handler, void *user_data); 154 | 155 | void uws_app_run(int ssl, uws_app_t *); 156 | 157 | void uws_app_listen(int ssl, uws_app_t *app, int port, 158 | uws_listen_handler handler, void *user_data); 159 | void uws_app_listen_with_config(int ssl, uws_app_t *app, 160 | uws_app_listen_config_t config, 161 | uws_listen_handler handler, void *user_data); 162 | bool uws_constructor_failed(int ssl, uws_app_t *app); 163 | unsigned int uws_num_subscribers(int ssl, uws_app_t *app, const char *topic); 164 | bool uws_publish(int ssl, uws_app_t *app, const char *topic, 165 | size_t topic_length, const char *message, 166 | size_t message_length, uws_opcode_t opcode, bool compress); 167 | void *uws_get_native_handle(int ssl, uws_app_t *app); 168 | void uws_remove_server_name(int ssl, uws_app_t *app, 169 | const char *hostname_pattern); 170 | void uws_add_server_name(int ssl, uws_app_t *app, const char *hostname_pattern); 171 | void uws_add_server_name_with_options( 172 | int ssl, uws_app_t *app, const char *hostname_pattern, 173 | struct us_socket_context_options_t options); 174 | void uws_missing_server_name(int ssl, uws_app_t *app, 175 | uws_missing_server_handler handler, 176 | void *user_data); 177 | void uws_filter(int ssl, uws_app_t *app, uws_filter_handler handler, 178 | void *user_data); 179 | 180 | // WebSocket 181 | void uws_ws(int ssl, uws_app_t *app, const char *pattern, 182 | uws_socket_behavior_t behavior); 183 | void *uws_ws_get_user_data(int ssl, uws_websocket_t *ws); 184 | void uws_ws_close(int ssl, uws_websocket_t *ws); 185 | uws_sendstatus_t uws_ws_send(int ssl, uws_websocket_t *ws, const char *message, 186 | size_t length, uws_opcode_t opcode); 187 | uws_sendstatus_t uws_ws_send_with_options(int ssl, uws_websocket_t *ws, 188 | const char *message, size_t length, 189 | uws_opcode_t opcode, bool compress, 190 | bool fin); 191 | uws_sendstatus_t uws_ws_send_fragment(int ssl, uws_websocket_t *ws, 192 | const char *message, size_t length, 193 | bool compress); 194 | uws_sendstatus_t uws_ws_send_first_fragment(int ssl, uws_websocket_t *ws, 195 | const char *message, size_t length, 196 | bool compress); 197 | uws_sendstatus_t 198 | uws_ws_send_first_fragment_with_opcode(int ssl, uws_websocket_t *ws, 199 | const char *message, size_t length, 200 | uws_opcode_t opcode, bool compress); 201 | uws_sendstatus_t uws_ws_send_last_fragment(int ssl, uws_websocket_t *ws, 202 | const char *message, size_t length, 203 | bool compress); 204 | void uws_ws_end(int ssl, uws_websocket_t *ws, int code, const char *message, 205 | size_t length); 206 | void uws_ws_cork(int ssl, uws_websocket_t *ws, void (*handler)(void *user_data), 207 | void *user_data); 208 | bool uws_ws_subscribe(int ssl, uws_websocket_t *ws, const char *topic, 209 | size_t length); 210 | bool uws_ws_unsubscribe(int ssl, uws_websocket_t *ws, const char *topic, 211 | size_t length); 212 | bool uws_ws_is_subscribed(int ssl, uws_websocket_t *ws, const char *topic, 213 | size_t length); 214 | void uws_ws_iterate_topics(int ssl, uws_websocket_t *ws, 215 | void (*callback)(const char *topic, size_t length, 216 | void *user_data), 217 | void *user_data); 218 | bool uws_ws_publish(int ssl, uws_websocket_t *ws, const char *topic, 219 | size_t topic_length, const char *message, 220 | size_t message_length); 221 | bool uws_ws_publish_with_options(int ssl, uws_websocket_t *ws, 222 | const char *topic, size_t topic_length, 223 | const char *message, size_t message_length, 224 | uws_opcode_t opcode, bool compress); 225 | unsigned int uws_ws_get_buffered_amount(int ssl, uws_websocket_t *ws); 226 | size_t uws_ws_get_remote_address(int ssl, uws_websocket_t *ws, 227 | const char **dest); 228 | size_t uws_ws_get_remote_address_as_text(int ssl, uws_websocket_t *ws, 229 | const char **dest); 230 | 231 | // Response 232 | void uws_res_end(int ssl, uws_res_t *res, const char *data, size_t length, 233 | bool close_connection); 234 | void uws_res_pause(int ssl, uws_res_t *res); 235 | void uws_res_resume(int ssl, uws_res_t *res); 236 | void uws_res_write_continwue(int ssl, uws_res_t *res); 237 | void uws_res_write_status(int ssl, uws_res_t *res, const char *status, 238 | size_t length); 239 | void uws_res_write_header(int ssl, uws_res_t *res, const char *key, 240 | size_t key_length, const char *value, 241 | size_t value_length); 242 | 243 | void uws_res_write_header_int(int ssl, uws_res_t *res, const char *key, 244 | size_t key_length, uint64_t value); 245 | void uws_res_end_without_body(int ssl, uws_res_t *res); 246 | void uws_res_end_stream(int ssl, uws_res_t *res, bool close_connection); 247 | bool uws_res_write(int ssl, uws_res_t *res, const char *data, size_t length); 248 | uintmax_t uws_res_get_write_offset(int ssl, uws_res_t *res); 249 | bool uws_res_has_responded(int ssl, uws_res_t *res); 250 | void uws_res_on_writable(int ssl, uws_res_t *res, 251 | bool (*handler)(uws_res_t *res, uintmax_t, 252 | void *opcional_data), 253 | void *user_data); 254 | void uws_res_on_aborted(int ssl, uws_res_t *res, 255 | void (*handler)(uws_res_t *res, void *opcional_data), 256 | void *opcional_data); 257 | void uws_res_on_data(int ssl, uws_res_t *res, 258 | void (*handler)(uws_res_t *res, const char *chunk, 259 | size_t chunk_length, bool is_end, 260 | void *opcional_data), 261 | void *opcional_data); 262 | void uws_res_upgrade(int ssl, uws_res_t *res, void *data, 263 | const char *sec_web_socket_key, 264 | size_t sec_web_socket_key_length, 265 | const char *sec_web_socket_protocol, 266 | size_t sec_web_socket_protocol_length, 267 | const char *sec_web_socket_extensions, 268 | size_t sec_web_socket_extensions_length, 269 | uws_socket_context_t *ws); 270 | 271 | // Request 272 | bool uws_req_is_ancient(uws_req_t *res); 273 | bool uws_req_get_yield(uws_req_t *res); 274 | void uws_req_set_field(uws_req_t *res, bool yield); 275 | size_t uws_req_get_url(uws_req_t *res, const char **dest); 276 | size_t uws_req_get_method(uws_req_t *res, const char **dest); 277 | size_t uws_req_get_header(uws_req_t *res, const char *lower_case_header, 278 | size_t lower_case_header_length, const char **dest); 279 | size_t uws_req_get_query(uws_req_t *res, const char *key, size_t key_length, 280 | const char **dest); 281 | size_t uws_req_get_parameter(uws_req_t *res, unsigned short index, 282 | const char **dest); 283 | 284 | struct us_loop_t *uws_get_loop(); 285 | 286 | void uws_loop_addPostHandler(us_loop_t *loop, void *ctx_, 287 | void (*cb)(void *ctx, us_loop_t *loop)); 288 | void uws_loop_removePostHandler(us_loop_t *loop, void *key); 289 | void uws_loop_addPreHandler(us_loop_t *loop, void *key, 290 | void (*cb)(void *ctx, us_loop_t *loop)); 291 | void uws_loop_removePreHandler(us_loop_t *loop, void *ctx_); 292 | void uws_loop_defer(us_loop_t *loop, void *ctx, void (*cb)(void *ctx)); 293 | 294 | void uws_res_write_headers(int ssl, uws_res_t *res, const StringPointer *names, 295 | const StringPointer *values, size_t count, 296 | const char *buf); 297 | 298 | void *uws_res_get_native_handle(int ssl, uws_res_t *res); 299 | void uws_res_uncork(int ssl, uws_res_t *res); 300 | void uws_res_set_write_offset(int ssl, uws_res_t *res, size_t off); 301 | void us_socket_mark_needs_more_not_ssl(uws_res_t *res); 302 | bool uws_res_try_end(int ssl, uws_res_t *res, const char *bytes, size_t len, 303 | size_t total_len); 304 | 305 | void uws_res_prepare_for_sendfile(int ssl, uws_res_t *res); 306 | #ifdef __cplusplus 307 | } 308 | #endif 309 | 310 | #endif -------------------------------------------------------------------------------- /deps/base64/chromiumbase64.c: -------------------------------------------------------------------------------- 1 | #include "chromiumbase64.h" 2 | 3 | // from node: 4 | static const int8_t unbase64_table[256] = { 5 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1, -1, -2, -1, -1, -1, -1, -1, 6 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1, -1, -1, -1, -1, 7 | -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 8 | 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9 | 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 10 | 63, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 11 | 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 13 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 14 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 17 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 18 | -1, -1, -1, -1, -1, -1, -1, -1, -1}; 19 | 20 | #define CHAR62 '+' 21 | #define CHAR63 '/' 22 | #define CHARPAD '=' 23 | static const char e0[256] = { 24 | 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', 'C', 'C', 'D', 'D', 'D', 25 | 'D', 'E', 'E', 'E', 'E', 'F', 'F', 'F', 'F', 'G', 'G', 'G', 'G', 'H', 'H', 26 | 'H', 'H', 'I', 'I', 'I', 'I', 'J', 'J', 'J', 'J', 'K', 'K', 'K', 'K', 'L', 27 | 'L', 'L', 'L', 'M', 'M', 'M', 'M', 'N', 'N', 'N', 'N', 'O', 'O', 'O', 'O', 28 | 'P', 'P', 'P', 'P', 'Q', 'Q', 'Q', 'Q', 'R', 'R', 'R', 'R', 'S', 'S', 'S', 29 | 'S', 'T', 'T', 'T', 'T', 'U', 'U', 'U', 'U', 'V', 'V', 'V', 'V', 'W', 'W', 30 | 'W', 'W', 'X', 'X', 'X', 'X', 'Y', 'Y', 'Y', 'Y', 'Z', 'Z', 'Z', 'Z', 'a', 31 | 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'c', 'd', 'd', 'd', 'd', 32 | 'e', 'e', 'e', 'e', 'f', 'f', 'f', 'f', 'g', 'g', 'g', 'g', 'h', 'h', 'h', 33 | 'h', 'i', 'i', 'i', 'i', 'j', 'j', 'j', 'j', 'k', 'k', 'k', 'k', 'l', 'l', 34 | 'l', 'l', 'm', 'm', 'm', 'm', 'n', 'n', 'n', 'n', 'o', 'o', 'o', 'o', 'p', 35 | 'p', 'p', 'p', 'q', 'q', 'q', 'q', 'r', 'r', 'r', 'r', 's', 's', 's', 's', 36 | 't', 't', 't', 't', 'u', 'u', 'u', 'u', 'v', 'v', 'v', 'v', 'w', 'w', 'w', 37 | 'w', 'x', 'x', 'x', 'x', 'y', 'y', 'y', 'y', 'z', 'z', 'z', 'z', '0', '0', 38 | '0', '0', '1', '1', '1', '1', '2', '2', '2', '2', '3', '3', '3', '3', '4', 39 | '4', '4', '4', '5', '5', '5', '5', '6', '6', '6', '6', '7', '7', '7', '7', 40 | '8', '8', '8', '8', '9', '9', '9', '9', '+', '+', '+', '+', '/', '/', '/', 41 | '/'}; 42 | 43 | static const char e1[256] = { 44 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 45 | 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 46 | 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 47 | 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', 48 | '8', '9', '+', '/', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 49 | 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 50 | 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 51 | 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', 52 | '4', '5', '6', '7', '8', '9', '+', '/', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 53 | 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 54 | 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 55 | 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 56 | '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', 'A', 'B', 'C', 57 | 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 58 | 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 59 | 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 60 | 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', 61 | '/'}; 62 | 63 | static const char e2[256] = { 64 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 65 | 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 66 | 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 67 | 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', 68 | '8', '9', '+', '/', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 69 | 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 70 | 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 71 | 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', 72 | '4', '5', '6', '7', '8', '9', '+', '/', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 73 | 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 74 | 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 75 | 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 76 | '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', 'A', 'B', 'C', 77 | 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 78 | 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 79 | 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 80 | 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', 81 | '/'}; 82 | 83 | /* SPECIAL DECODE TABLES FOR LITTLE ENDIAN (INTEL) CPUS */ 84 | 85 | static const uint32_t d0[256] = { 86 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 87 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 88 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 89 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 90 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 91 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 92 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 93 | 0x01ffffff, 0x000000f8, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x000000fc, 94 | 0x000000d0, 0x000000d4, 0x000000d8, 0x000000dc, 0x000000e0, 0x000000e4, 95 | 0x000000e8, 0x000000ec, 0x000000f0, 0x000000f4, 0x01ffffff, 0x01ffffff, 96 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, 97 | 0x00000004, 0x00000008, 0x0000000c, 0x00000010, 0x00000014, 0x00000018, 98 | 0x0000001c, 0x00000020, 0x00000024, 0x00000028, 0x0000002c, 0x00000030, 99 | 0x00000034, 0x00000038, 0x0000003c, 0x00000040, 0x00000044, 0x00000048, 100 | 0x0000004c, 0x00000050, 0x00000054, 0x00000058, 0x0000005c, 0x00000060, 101 | 0x00000064, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 102 | 0x01ffffff, 0x00000068, 0x0000006c, 0x00000070, 0x00000074, 0x00000078, 103 | 0x0000007c, 0x00000080, 0x00000084, 0x00000088, 0x0000008c, 0x00000090, 104 | 0x00000094, 0x00000098, 0x0000009c, 0x000000a0, 0x000000a4, 0x000000a8, 105 | 0x000000ac, 0x000000b0, 0x000000b4, 0x000000b8, 0x000000bc, 0x000000c0, 106 | 0x000000c4, 0x000000c8, 0x000000cc, 0x01ffffff, 0x01ffffff, 0x01ffffff, 107 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 108 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 109 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 110 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 111 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 112 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 113 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 114 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 115 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 116 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 117 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 118 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 119 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 120 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 121 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 122 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 123 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 124 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 125 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 126 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 127 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 128 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff}; 129 | 130 | static const uint32_t d1[256] = { 131 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 132 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 133 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 134 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 135 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 136 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 137 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 138 | 0x01ffffff, 0x0000e003, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x0000f003, 139 | 0x00004003, 0x00005003, 0x00006003, 0x00007003, 0x00008003, 0x00009003, 140 | 0x0000a003, 0x0000b003, 0x0000c003, 0x0000d003, 0x01ffffff, 0x01ffffff, 141 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, 142 | 0x00001000, 0x00002000, 0x00003000, 0x00004000, 0x00005000, 0x00006000, 143 | 0x00007000, 0x00008000, 0x00009000, 0x0000a000, 0x0000b000, 0x0000c000, 144 | 0x0000d000, 0x0000e000, 0x0000f000, 0x00000001, 0x00001001, 0x00002001, 145 | 0x00003001, 0x00004001, 0x00005001, 0x00006001, 0x00007001, 0x00008001, 146 | 0x00009001, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 147 | 0x01ffffff, 0x0000a001, 0x0000b001, 0x0000c001, 0x0000d001, 0x0000e001, 148 | 0x0000f001, 0x00000002, 0x00001002, 0x00002002, 0x00003002, 0x00004002, 149 | 0x00005002, 0x00006002, 0x00007002, 0x00008002, 0x00009002, 0x0000a002, 150 | 0x0000b002, 0x0000c002, 0x0000d002, 0x0000e002, 0x0000f002, 0x00000003, 151 | 0x00001003, 0x00002003, 0x00003003, 0x01ffffff, 0x01ffffff, 0x01ffffff, 152 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 153 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 154 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 155 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 156 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 157 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 158 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 159 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 160 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 161 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 162 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 163 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 164 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 165 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 166 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 167 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 168 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 169 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 170 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 171 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 172 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 173 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff}; 174 | 175 | static const uint32_t d2[256] = { 176 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 177 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 178 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 179 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 180 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 181 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 182 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 183 | 0x01ffffff, 0x00800f00, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00c00f00, 184 | 0x00000d00, 0x00400d00, 0x00800d00, 0x00c00d00, 0x00000e00, 0x00400e00, 185 | 0x00800e00, 0x00c00e00, 0x00000f00, 0x00400f00, 0x01ffffff, 0x01ffffff, 186 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, 187 | 0x00400000, 0x00800000, 0x00c00000, 0x00000100, 0x00400100, 0x00800100, 188 | 0x00c00100, 0x00000200, 0x00400200, 0x00800200, 0x00c00200, 0x00000300, 189 | 0x00400300, 0x00800300, 0x00c00300, 0x00000400, 0x00400400, 0x00800400, 190 | 0x00c00400, 0x00000500, 0x00400500, 0x00800500, 0x00c00500, 0x00000600, 191 | 0x00400600, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 192 | 0x01ffffff, 0x00800600, 0x00c00600, 0x00000700, 0x00400700, 0x00800700, 193 | 0x00c00700, 0x00000800, 0x00400800, 0x00800800, 0x00c00800, 0x00000900, 194 | 0x00400900, 0x00800900, 0x00c00900, 0x00000a00, 0x00400a00, 0x00800a00, 195 | 0x00c00a00, 0x00000b00, 0x00400b00, 0x00800b00, 0x00c00b00, 0x00000c00, 196 | 0x00400c00, 0x00800c00, 0x00c00c00, 0x01ffffff, 0x01ffffff, 0x01ffffff, 197 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 198 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 199 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 200 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 201 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 202 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 203 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 204 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 205 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 206 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 207 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 208 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 209 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 210 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 211 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 212 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 213 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 214 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 215 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 216 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 217 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 218 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff}; 219 | 220 | static const uint32_t d3[256] = { 221 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 222 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 223 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 224 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 225 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 226 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 227 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 228 | 0x01ffffff, 0x003e0000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x003f0000, 229 | 0x00340000, 0x00350000, 0x00360000, 0x00370000, 0x00380000, 0x00390000, 230 | 0x003a0000, 0x003b0000, 0x003c0000, 0x003d0000, 0x01ffffff, 0x01ffffff, 231 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x00000000, 232 | 0x00010000, 0x00020000, 0x00030000, 0x00040000, 0x00050000, 0x00060000, 233 | 0x00070000, 0x00080000, 0x00090000, 0x000a0000, 0x000b0000, 0x000c0000, 234 | 0x000d0000, 0x000e0000, 0x000f0000, 0x00100000, 0x00110000, 0x00120000, 235 | 0x00130000, 0x00140000, 0x00150000, 0x00160000, 0x00170000, 0x00180000, 236 | 0x00190000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 237 | 0x01ffffff, 0x001a0000, 0x001b0000, 0x001c0000, 0x001d0000, 0x001e0000, 238 | 0x001f0000, 0x00200000, 0x00210000, 0x00220000, 0x00230000, 0x00240000, 239 | 0x00250000, 0x00260000, 0x00270000, 0x00280000, 0x00290000, 0x002a0000, 240 | 0x002b0000, 0x002c0000, 0x002d0000, 0x002e0000, 0x002f0000, 0x00300000, 241 | 0x00310000, 0x00320000, 0x00330000, 0x01ffffff, 0x01ffffff, 0x01ffffff, 242 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 243 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 244 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 245 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 246 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 247 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 248 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 249 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 250 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 251 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 252 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 253 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 254 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 255 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 256 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 257 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 258 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 259 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 260 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 261 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 262 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 263 | 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff}; 264 | 265 | #define BADCHAR 0x01FFFFFF 266 | 267 | /** 268 | * you can control if we use padding by commenting out this 269 | * next line. However, I highly recommend you use padding and not 270 | * using it should only be for compatability with a 3rd party. 271 | * Also, 'no padding' is not tested! 272 | */ 273 | // #define DOPAD 1 274 | 275 | /* 276 | * if we aren't doing padding 277 | * set the pad character to NULL 278 | */ 279 | #ifndef DOPAD 280 | #undef CHARPAD 281 | #define CHARPAD '\0' 282 | #endif 283 | 284 | size_t chromium_base64_encode(char *dest, const char *str, size_t len) { 285 | size_t i = 0; 286 | uint8_t *p = (uint8_t *)dest; 287 | 288 | /* unsigned here is important! */ 289 | uint8_t t1, t2, t3; 290 | 291 | if (len > 2) { 292 | for (; i < len - 2; i += 3) { 293 | t1 = str[i]; 294 | t2 = str[i + 1]; 295 | t3 = str[i + 2]; 296 | *p++ = e0[t1]; 297 | *p++ = e1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)]; 298 | *p++ = e1[((t2 & 0x0F) << 2) | ((t3 >> 6) & 0x03)]; 299 | *p++ = e2[t3]; 300 | } 301 | } 302 | 303 | switch (len - i) { 304 | case 0: 305 | break; 306 | case 1: 307 | t1 = str[i]; 308 | *p++ = e0[t1]; 309 | *p++ = e1[(t1 & 0x03) << 4]; 310 | // *p++ = CHARPAD; 311 | // *p++ = CHARPAD; 312 | break; 313 | default: /* case 2 */ 314 | t1 = str[i]; 315 | t2 = str[i + 1]; 316 | *p++ = e0[t1]; 317 | *p++ = e1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)]; 318 | *p++ = e2[(t2 & 0x0F) << 2]; 319 | // *p++ = CHARPAD; 320 | } 321 | 322 | // Commented out because it already returns the length 323 | // *p = '\0'; 324 | return p - (uint8_t *)dest; 325 | } 326 | 327 | size_t chromium_base64_decode(char *dest, const char *src, size_t len, 328 | size_t *out_len) { 329 | if (len == 0) { 330 | *out_len = 0; 331 | return 0; 332 | } 333 | 334 | #ifdef DOPAD 335 | /* 336 | * if padding is used, then the message must be at least 337 | * 4 chars and be a multiple of 4 338 | */ 339 | if (len < 4 || (len % 4 != 0)) { 340 | *out_len = 0; 341 | return MODP_B64_ERROR; /* error */ 342 | } 343 | /* there can be at most 2 pad chars at the end */ 344 | if (src[len - 1] == CHARPAD) { 345 | len--; 346 | if (src[len - 1] == CHARPAD) { 347 | len--; 348 | } 349 | } 350 | #endif 351 | 352 | size_t i; 353 | int leftover = len % 4; 354 | size_t chunks = (leftover == 0) ? len / 4 - 1 : len / 4; 355 | 356 | uint8_t *p = (uint8_t *)dest; 357 | uint32_t x = 0; 358 | const uint8_t *y = (uint8_t *)src; 359 | for (i = 0; i < chunks;) { 360 | x = d0[y[0]] | d1[y[1]] | d2[y[2]] | d3[y[3]]; 361 | if (x >= BADCHAR) { 362 | // skip whitespace 363 | // this is change bun added 364 | if (y[0] < 64) { 365 | y++; 366 | continue; 367 | } 368 | 369 | *out_len = p - (uint8_t *)dest; 370 | return MODP_B64_ERROR; 371 | } 372 | 373 | *p++ = ((uint8_t *)(&x))[0]; 374 | *p++ = ((uint8_t *)(&x))[1]; 375 | *p++ = ((uint8_t *)(&x))[2]; 376 | y += 4; 377 | ++i; 378 | } 379 | 380 | switch (leftover) { 381 | case 0: 382 | x = d0[y[0]] | d1[y[1]] | d2[y[2]] | d3[y[3]]; 383 | 384 | if (x >= BADCHAR) { 385 | *out_len = p - (uint8_t *)dest + 1; 386 | return MODP_B64_ERROR; 387 | } 388 | 389 | *p++ = ((uint8_t *)(&x))[0]; 390 | *p++ = ((uint8_t *)(&x))[1]; 391 | *p = ((uint8_t *)(&x))[2]; 392 | return (chunks + 1) * 3; 393 | break; 394 | case 1: /* with padding this is an impossible case */ 395 | x = d0[y[0]]; 396 | *p = *((uint8_t *)(&x)); // i.e. first char/byte in int 397 | break; 398 | case 2: // * case 2, 1 output byte */ 399 | x = d0[y[0]] | d1[y[1]]; 400 | *p = *((uint8_t *)(&x)); // i.e. first char 401 | break; 402 | default: /* case 3, 2 output bytes */ 403 | x = d0[y[0]] | d1[y[1]] | d2[y[2]]; /* 0x3c */ 404 | *p++ = ((uint8_t *)(&x))[0]; 405 | *p = ((uint8_t *)(&x))[1]; 406 | break; 407 | } 408 | 409 | *out_len = 3 * chunks + (6 * leftover) / 8; 410 | 411 | if (x >= BADCHAR) 412 | return MODP_B64_ERROR; 413 | 414 | return 3 * chunks + (6 * leftover) / 8; 415 | } -------------------------------------------------------------------------------- /pkg/include/picohttpparser.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2014 Kazuho Oku, Tokuhiro Matsuno, Daisuke Murase, 3 | * Shigeo Mitsunari 4 | * 5 | * The software is licensed under either the MIT License (below) or the Perl 6 | * license. 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to 10 | * deal in the Software without restriction, including without limitation the 11 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 12 | * sell copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 24 | * IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | #ifdef __SSE4_2__ 31 | #ifdef _MSC_VER 32 | #include 33 | #else 34 | #include 35 | #endif 36 | #endif 37 | #include "picohttpparser.h" 38 | 39 | #if __GNUC__ >= 3 40 | #define likely(x) __builtin_expect(!!(x), 1) 41 | #define unlikely(x) __builtin_expect(!!(x), 0) 42 | #else 43 | #define likely(x) (x) 44 | #define unlikely(x) (x) 45 | #endif 46 | 47 | #ifdef _MSC_VER 48 | #define ALIGNED(n) _declspec(align(n)) 49 | #else 50 | #define ALIGNED(n) __attribute__((aligned(n))) 51 | #endif 52 | 53 | #define IS_PRINTABLE_ASCII(c) ((unsigned char)(c)-040u < 0137u) 54 | 55 | #define CHECK_EOF() \ 56 | if (buf == buf_end) { \ 57 | *ret = -2; \ 58 | return NULL; \ 59 | } 60 | 61 | #define EXPECT_CHAR_NO_CHECK(ch) \ 62 | if (*buf++ != ch) { \ 63 | *ret = -1; \ 64 | return NULL; \ 65 | } 66 | 67 | #define EXPECT_CHAR(ch) \ 68 | CHECK_EOF(); \ 69 | EXPECT_CHAR_NO_CHECK(ch); 70 | 71 | #define ADVANCE_TOKEN(tok, toklen) \ 72 | do { \ 73 | const char *tok_start = buf; \ 74 | static const char ALIGNED(16) ranges2[16] = "\000\040\177\177"; \ 75 | int found2; \ 76 | buf = findchar_fast(buf, buf_end, ranges2, 4, &found2); \ 77 | if (!found2) { \ 78 | CHECK_EOF(); \ 79 | } \ 80 | while (1) { \ 81 | if (*buf == ' ') { \ 82 | break; \ 83 | } else if (unlikely(!IS_PRINTABLE_ASCII(*buf))) { \ 84 | if ((unsigned char)*buf < '\040' || *buf == '\177') { \ 85 | *ret = -1; \ 86 | return NULL; \ 87 | } \ 88 | } \ 89 | ++buf; \ 90 | CHECK_EOF(); \ 91 | } \ 92 | tok = tok_start; \ 93 | toklen = buf - tok_start; \ 94 | } while (0) 95 | 96 | static const char *token_char_map = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" 97 | "\0\1\0\1\1\1\1\1\0\0\1\1\0\1\1\0\1\1\1\1\1\1\1\1\1\1\0\0\0\0\0\0" 98 | "\0\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\0\0\0\1\1" 99 | "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\0\1\0\1\0" 100 | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" 101 | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" 102 | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" 103 | "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; 104 | 105 | static const char *findchar_fast(const char *buf, const char *buf_end, const char *ranges, size_t ranges_size, int *found) 106 | { 107 | *found = 0; 108 | #if __SSE4_2__ 109 | if (likely(buf_end - buf >= 16)) { 110 | __m128i ranges16 = _mm_loadu_si128((const __m128i *)ranges); 111 | 112 | size_t left = (buf_end - buf) & ~15; 113 | do { 114 | __m128i b16 = _mm_loadu_si128((const __m128i *)buf); 115 | int r = _mm_cmpestri(ranges16, ranges_size, b16, 16, _SIDD_LEAST_SIGNIFICANT | _SIDD_CMP_RANGES | _SIDD_UBYTE_OPS); 116 | if (unlikely(r != 16)) { 117 | buf += r; 118 | *found = 1; 119 | break; 120 | } 121 | buf += 16; 122 | left -= 16; 123 | } while (likely(left != 0)); 124 | } 125 | #else 126 | /* suppress unused parameter warning */ 127 | (void)buf_end; 128 | (void)ranges; 129 | (void)ranges_size; 130 | #endif 131 | return buf; 132 | } 133 | 134 | static const char *get_token_to_eol(const char *buf, const char *buf_end, const char **token, size_t *token_len, int *ret) 135 | { 136 | const char *token_start = buf; 137 | 138 | #ifdef __SSE4_2__ 139 | static const char ALIGNED(16) ranges1[16] = "\0\010" /* allow HT */ 140 | "\012\037" /* allow SP and up to but not including DEL */ 141 | "\177\177"; /* allow chars w. MSB set */ 142 | int found; 143 | buf = findchar_fast(buf, buf_end, ranges1, 6, &found); 144 | if (found) 145 | goto FOUND_CTL; 146 | #else 147 | /* find non-printable char within the next 8 bytes, this is the hottest code; manually inlined */ 148 | while (likely(buf_end - buf >= 8)) { 149 | #define DOIT() \ 150 | do { \ 151 | if (unlikely(!IS_PRINTABLE_ASCII(*buf))) \ 152 | goto NonPrintable; \ 153 | ++buf; \ 154 | } while (0) 155 | DOIT(); 156 | DOIT(); 157 | DOIT(); 158 | DOIT(); 159 | DOIT(); 160 | DOIT(); 161 | DOIT(); 162 | DOIT(); 163 | #undef DOIT 164 | continue; 165 | NonPrintable: 166 | if ((likely((unsigned char)*buf < '\040') && likely(*buf != '\011')) || unlikely(*buf == '\177')) { 167 | goto FOUND_CTL; 168 | } 169 | ++buf; 170 | } 171 | #endif 172 | for (;; ++buf) { 173 | CHECK_EOF(); 174 | if (unlikely(!IS_PRINTABLE_ASCII(*buf))) { 175 | if ((likely((unsigned char)*buf < '\040') && likely(*buf != '\011')) || unlikely(*buf == '\177')) { 176 | goto FOUND_CTL; 177 | } 178 | } 179 | } 180 | FOUND_CTL: 181 | if (likely(*buf == '\015')) { 182 | ++buf; 183 | EXPECT_CHAR('\012'); 184 | *token_len = buf - 2 - token_start; 185 | } else if (*buf == '\012') { 186 | *token_len = buf - token_start; 187 | ++buf; 188 | } else { 189 | *ret = -1; 190 | return NULL; 191 | } 192 | *token = token_start; 193 | 194 | return buf; 195 | } 196 | 197 | static const char *is_complete(const char *buf, const char *buf_end, size_t last_len, int *ret) 198 | { 199 | int ret_cnt = 0; 200 | buf = last_len < 3 ? buf : buf + last_len - 3; 201 | 202 | while (1) { 203 | CHECK_EOF(); 204 | if (*buf == '\015') { 205 | ++buf; 206 | CHECK_EOF(); 207 | EXPECT_CHAR('\012'); 208 | ++ret_cnt; 209 | } else if (*buf == '\012') { 210 | ++buf; 211 | ++ret_cnt; 212 | } else { 213 | ++buf; 214 | ret_cnt = 0; 215 | } 216 | if (ret_cnt == 2) { 217 | return buf; 218 | } 219 | } 220 | 221 | *ret = -2; 222 | return NULL; 223 | } 224 | 225 | #define PARSE_INT(valp_, mul_) \ 226 | if (*buf < '0' || '9' < *buf) { \ 227 | buf++; \ 228 | *ret = -1; \ 229 | return NULL; \ 230 | } \ 231 | *(valp_) = (mul_) * (*buf++ - '0'); 232 | 233 | #define PARSE_INT_3(valp_) \ 234 | do { \ 235 | int res_ = 0; \ 236 | PARSE_INT(&res_, 100) \ 237 | *valp_ = res_; \ 238 | PARSE_INT(&res_, 10) \ 239 | *valp_ += res_; \ 240 | PARSE_INT(&res_, 1) \ 241 | *valp_ += res_; \ 242 | } while (0) 243 | 244 | /* returned pointer is always within [buf, buf_end), or null */ 245 | static const char *parse_token(const char *buf, const char *buf_end, const char **token, size_t *token_len, char next_char, 246 | int *ret) 247 | { 248 | /* We use pcmpestri to detect non-token characters. This instruction can take no more than eight character ranges (8*2*8=128 249 | * bits that is the size of a SSE register). Due to this restriction, characters `|` and `~` are handled in the slow loop. */ 250 | static const char ALIGNED(16) ranges[] = "\x00 " /* control chars and up to SP */ 251 | "\"\"" /* 0x22 */ 252 | "()" /* 0x28,0x29 */ 253 | ",," /* 0x2c */ 254 | "//" /* 0x2f */ 255 | ":@" /* 0x3a-0x40 */ 256 | "[]" /* 0x5b-0x5d */ 257 | "{\xff"; /* 0x7b-0xff */ 258 | const char *buf_start = buf; 259 | int found; 260 | buf = findchar_fast(buf, buf_end, ranges, sizeof(ranges) - 1, &found); 261 | if (!found) { 262 | CHECK_EOF(); 263 | } 264 | while (1) { 265 | if (*buf == next_char) { 266 | break; 267 | } else if (!token_char_map[(unsigned char)*buf]) { 268 | *ret = -1; 269 | return NULL; 270 | } 271 | ++buf; 272 | CHECK_EOF(); 273 | } 274 | *token = buf_start; 275 | *token_len = buf - buf_start; 276 | return buf; 277 | } 278 | 279 | /* returned pointer is always within [buf, buf_end), or null */ 280 | static const char *parse_http_version(const char *buf, const char *buf_end, int *minor_version, int *ret) 281 | { 282 | /* we want at least [HTTP/1.] to try to parse */ 283 | if (buf_end - buf < 9) { 284 | *ret = -2; 285 | return NULL; 286 | } 287 | EXPECT_CHAR_NO_CHECK('H'); 288 | EXPECT_CHAR_NO_CHECK('T'); 289 | EXPECT_CHAR_NO_CHECK('T'); 290 | EXPECT_CHAR_NO_CHECK('P'); 291 | EXPECT_CHAR_NO_CHECK('/'); 292 | EXPECT_CHAR_NO_CHECK('1'); 293 | EXPECT_CHAR_NO_CHECK('.'); 294 | PARSE_INT(minor_version, 1); 295 | return buf; 296 | } 297 | 298 | static const char *parse_headers(const char *buf, const char *buf_end, struct phr_header *headers, size_t *num_headers, 299 | size_t max_headers, int *ret) 300 | { 301 | for (;; ++*num_headers) { 302 | CHECK_EOF(); 303 | if (*buf == '\015') { 304 | ++buf; 305 | EXPECT_CHAR('\012'); 306 | break; 307 | } else if (*buf == '\012') { 308 | ++buf; 309 | break; 310 | } 311 | if (*num_headers == max_headers) { 312 | *ret = -1; 313 | return NULL; 314 | } 315 | if (!(*num_headers != 0 && (*buf == ' ' || *buf == '\t'))) { 316 | /* parsing name, but do not discard SP before colon, see 317 | * http://www.mozilla.org/security/announce/2006/mfsa2006-33.html */ 318 | if ((buf = parse_token(buf, buf_end, &headers[*num_headers].name, &headers[*num_headers].name_len, ':', ret)) == NULL) { 319 | return NULL; 320 | } 321 | if (headers[*num_headers].name_len == 0) { 322 | *ret = -1; 323 | return NULL; 324 | } 325 | ++buf; 326 | for (;; ++buf) { 327 | CHECK_EOF(); 328 | if (!(*buf == ' ' || *buf == '\t')) { 329 | break; 330 | } 331 | } 332 | } else { 333 | headers[*num_headers].name = NULL; 334 | headers[*num_headers].name_len = 0; 335 | } 336 | const char *value; 337 | size_t value_len; 338 | if ((buf = get_token_to_eol(buf, buf_end, &value, &value_len, ret)) == NULL) { 339 | return NULL; 340 | } 341 | /* remove trailing SPs and HTABs */ 342 | const char *value_end = value + value_len; 343 | for (; value_end != value; --value_end) { 344 | const char c = *(value_end - 1); 345 | if (!(c == ' ' || c == '\t')) { 346 | break; 347 | } 348 | } 349 | headers[*num_headers].value = value; 350 | headers[*num_headers].value_len = value_end - value; 351 | } 352 | return buf; 353 | } 354 | 355 | static const char *parse_request(const char *buf, const char *buf_end, const char **method, size_t *method_len, const char **path, 356 | size_t *path_len, int *minor_version, struct phr_header *headers, size_t *num_headers, 357 | size_t max_headers, int *ret) 358 | { 359 | /* skip first empty line (some clients add CRLF after POST content) */ 360 | CHECK_EOF(); 361 | if (*buf == '\015') { 362 | ++buf; 363 | EXPECT_CHAR('\012'); 364 | } else if (*buf == '\012') { 365 | ++buf; 366 | } 367 | 368 | /* parse request line */ 369 | if ((buf = parse_token(buf, buf_end, method, method_len, ' ', ret)) == NULL) { 370 | return NULL; 371 | } 372 | do { 373 | ++buf; 374 | CHECK_EOF(); 375 | } while (*buf == ' '); 376 | ADVANCE_TOKEN(*path, *path_len); 377 | do { 378 | ++buf; 379 | CHECK_EOF(); 380 | } while (*buf == ' '); 381 | if (*method_len == 0 || *path_len == 0) { 382 | *ret = -1; 383 | return NULL; 384 | } 385 | if ((buf = parse_http_version(buf, buf_end, minor_version, ret)) == NULL) { 386 | return NULL; 387 | } 388 | if (*buf == '\015') { 389 | ++buf; 390 | EXPECT_CHAR('\012'); 391 | } else if (*buf == '\012') { 392 | ++buf; 393 | } else { 394 | *ret = -1; 395 | return NULL; 396 | } 397 | 398 | return parse_headers(buf, buf_end, headers, num_headers, max_headers, ret); 399 | } 400 | 401 | int phr_parse_request(const char *buf_start, size_t len, const char **method, size_t *method_len, const char **path, 402 | size_t *path_len, int *minor_version, struct phr_header *headers, size_t *num_headers, size_t last_len) 403 | { 404 | const char *buf = buf_start, *buf_end = buf_start + len; 405 | size_t max_headers = *num_headers; 406 | int r; 407 | 408 | *method = NULL; 409 | *method_len = 0; 410 | *path = NULL; 411 | *path_len = 0; 412 | *minor_version = -1; 413 | *num_headers = 0; 414 | 415 | /* if last_len != 0, check if the request is complete (a fast countermeasure 416 | againt slowloris */ 417 | if (last_len != 0 && is_complete(buf, buf_end, last_len, &r) == NULL) { 418 | return r; 419 | } 420 | 421 | if ((buf = parse_request(buf, buf_end, method, method_len, path, path_len, minor_version, headers, num_headers, max_headers, 422 | &r)) == NULL) { 423 | return r; 424 | } 425 | 426 | return (int)(buf - buf_start); 427 | } 428 | 429 | static const char *parse_response(const char *buf, const char *buf_end, int *minor_version, int *status, const char **msg, 430 | size_t *msg_len, struct phr_header *headers, size_t *num_headers, size_t max_headers, int *ret) 431 | { 432 | /* parse "HTTP/1.x" */ 433 | if ((buf = parse_http_version(buf, buf_end, minor_version, ret)) == NULL) { 434 | return NULL; 435 | } 436 | /* skip space */ 437 | if (*buf != ' ') { 438 | *ret = -1; 439 | return NULL; 440 | } 441 | do { 442 | ++buf; 443 | CHECK_EOF(); 444 | } while (*buf == ' '); 445 | /* parse status code, we want at least [:digit:][:digit:][:digit:] to try to parse */ 446 | if (buf_end - buf < 4) { 447 | *ret = -2; 448 | return NULL; 449 | } 450 | PARSE_INT_3(status); 451 | 452 | /* get message including preceding space */ 453 | if ((buf = get_token_to_eol(buf, buf_end, msg, msg_len, ret)) == NULL) { 454 | return NULL; 455 | } 456 | if (*msg_len == 0) { 457 | /* ok */ 458 | } else if (**msg == ' ') { 459 | /* Remove preceding space. Successful return from `get_token_to_eol` guarantees that we would hit something other than SP 460 | * before running past the end of the given buffer. */ 461 | do { 462 | ++*msg; 463 | --*msg_len; 464 | } while (**msg == ' '); 465 | } else { 466 | /* garbage found after status code */ 467 | *ret = -1; 468 | return NULL; 469 | } 470 | 471 | return parse_headers(buf, buf_end, headers, num_headers, max_headers, ret); 472 | } 473 | 474 | int phr_parse_response(const char *buf_start, size_t len, int *minor_version, int *status, const char **msg, size_t *msg_len, 475 | struct phr_header *headers, size_t *num_headers, size_t last_len) 476 | { 477 | const char *buf = buf_start, *buf_end = buf + len; 478 | size_t max_headers = *num_headers; 479 | int r; 480 | 481 | *minor_version = -1; 482 | *status = 0; 483 | *msg = NULL; 484 | *msg_len = 0; 485 | *num_headers = 0; 486 | 487 | /* if last_len != 0, check if the response is complete (a fast countermeasure 488 | against slowloris */ 489 | if (last_len != 0 && is_complete(buf, buf_end, last_len, &r) == NULL) { 490 | return r; 491 | } 492 | 493 | if ((buf = parse_response(buf, buf_end, minor_version, status, msg, msg_len, headers, num_headers, max_headers, &r)) == NULL) { 494 | return r; 495 | } 496 | 497 | return (int)(buf - buf_start); 498 | } 499 | 500 | int phr_parse_headers(const char *buf_start, size_t len, struct phr_header *headers, size_t *num_headers, size_t last_len) 501 | { 502 | const char *buf = buf_start, *buf_end = buf + len; 503 | size_t max_headers = *num_headers; 504 | int r; 505 | 506 | *num_headers = 0; 507 | 508 | /* if last_len != 0, check if the response is complete (a fast countermeasure 509 | against slowloris */ 510 | if (last_len != 0 && is_complete(buf, buf_end, last_len, &r) == NULL) { 511 | return r; 512 | } 513 | 514 | if ((buf = parse_headers(buf, buf_end, headers, num_headers, max_headers, &r)) == NULL) { 515 | return r; 516 | } 517 | 518 | return (int)(buf - buf_start); 519 | } 520 | 521 | enum { 522 | CHUNKED_IN_CHUNK_SIZE, 523 | CHUNKED_IN_CHUNK_EXT, 524 | CHUNKED_IN_CHUNK_DATA, 525 | CHUNKED_IN_CHUNK_CRLF, 526 | CHUNKED_IN_TRAILERS_LINE_HEAD, 527 | CHUNKED_IN_TRAILERS_LINE_MIDDLE 528 | }; 529 | 530 | static int decode_hex(int ch) 531 | { 532 | if ('0' <= ch && ch <= '9') { 533 | return ch - '0'; 534 | } else if ('A' <= ch && ch <= 'F') { 535 | return ch - 'A' + 0xa; 536 | } else if ('a' <= ch && ch <= 'f') { 537 | return ch - 'a' + 0xa; 538 | } else { 539 | return -1; 540 | } 541 | } 542 | 543 | ssize_t phr_decode_chunked(struct phr_chunked_decoder *decoder, char *buf, size_t *_bufsz) 544 | { 545 | size_t dst = 0, src = 0, bufsz = *_bufsz; 546 | ssize_t ret = -2; /* incomplete */ 547 | 548 | while (1) { 549 | switch (decoder->_state) { 550 | case CHUNKED_IN_CHUNK_SIZE: 551 | for (;; ++src) { 552 | int v; 553 | if (src == bufsz) 554 | goto Exit; 555 | if ((v = decode_hex(buf[src])) == -1) { 556 | if (decoder->_hex_count == 0) { 557 | ret = -1; 558 | goto Exit; 559 | } 560 | break; 561 | } 562 | if (decoder->_hex_count == sizeof(size_t) * 2) { 563 | ret = -1; 564 | goto Exit; 565 | } 566 | decoder->bytes_left_in_chunk = decoder->bytes_left_in_chunk * 16 + v; 567 | ++decoder->_hex_count; 568 | } 569 | decoder->_hex_count = 0; 570 | decoder->_state = CHUNKED_IN_CHUNK_EXT; 571 | /* fallthru */ 572 | case CHUNKED_IN_CHUNK_EXT: 573 | /* RFC 7230 A.2 "Line folding in chunk extensions is disallowed" */ 574 | for (;; ++src) { 575 | if (src == bufsz) 576 | goto Exit; 577 | if (buf[src] == '\012') 578 | break; 579 | } 580 | ++src; 581 | if (decoder->bytes_left_in_chunk == 0) { 582 | if (decoder->consume_trailer) { 583 | decoder->_state = CHUNKED_IN_TRAILERS_LINE_HEAD; 584 | break; 585 | } else { 586 | goto Complete; 587 | } 588 | } 589 | decoder->_state = CHUNKED_IN_CHUNK_DATA; 590 | /* fallthru */ 591 | case CHUNKED_IN_CHUNK_DATA: { 592 | size_t avail = bufsz - src; 593 | if (avail < decoder->bytes_left_in_chunk) { 594 | if (dst != src) 595 | memmove(buf + dst, buf + src, avail); 596 | src += avail; 597 | dst += avail; 598 | decoder->bytes_left_in_chunk -= avail; 599 | goto Exit; 600 | } 601 | if (dst != src) 602 | memmove(buf + dst, buf + src, decoder->bytes_left_in_chunk); 603 | src += decoder->bytes_left_in_chunk; 604 | dst += decoder->bytes_left_in_chunk; 605 | decoder->bytes_left_in_chunk = 0; 606 | decoder->_state = CHUNKED_IN_CHUNK_CRLF; 607 | } 608 | /* fallthru */ 609 | case CHUNKED_IN_CHUNK_CRLF: 610 | for (;; ++src) { 611 | if (src == bufsz) 612 | goto Exit; 613 | if (buf[src] != '\015') 614 | break; 615 | } 616 | if (buf[src] != '\012') { 617 | ret = -1; 618 | goto Exit; 619 | } 620 | ++src; 621 | decoder->_state = CHUNKED_IN_CHUNK_SIZE; 622 | break; 623 | case CHUNKED_IN_TRAILERS_LINE_HEAD: 624 | for (;; ++src) { 625 | if (src == bufsz) 626 | goto Exit; 627 | if (buf[src] != '\015') 628 | break; 629 | } 630 | if (buf[src++] == '\012') 631 | goto Complete; 632 | decoder->_state = CHUNKED_IN_TRAILERS_LINE_MIDDLE; 633 | /* fallthru */ 634 | case CHUNKED_IN_TRAILERS_LINE_MIDDLE: 635 | for (;; ++src) { 636 | if (src == bufsz) 637 | goto Exit; 638 | if (buf[src] == '\012') 639 | break; 640 | } 641 | ++src; 642 | decoder->_state = CHUNKED_IN_TRAILERS_LINE_HEAD; 643 | break; 644 | default: 645 | assert(!"decoder is corrupt"); 646 | } 647 | } 648 | 649 | Complete: 650 | ret = bufsz - src; 651 | Exit: 652 | if (dst != src) 653 | memmove(buf + dst, buf + src, bufsz - src); 654 | *_bufsz = dst; 655 | return ret; 656 | } 657 | 658 | int phr_decode_chunked_is_in_data(struct phr_chunked_decoder *decoder) 659 | { 660 | return decoder->_state == CHUNKED_IN_CHUNK_DATA; 661 | } 662 | 663 | #undef CHECK_EOF 664 | #undef EXPECT_CHAR 665 | #undef ADVANCE_TOKEN -------------------------------------------------------------------------------- /pkg/include/libuwsockets.cpp: -------------------------------------------------------------------------------- 1 | #include "_libusockets.h" 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | extern "C" { 10 | 11 | uws_app_t *uws_create_app(int ssl, struct us_socket_context_options_t options) { 12 | if (ssl) { 13 | uWS::SocketContextOptions socket_context_options; 14 | memcpy(&socket_context_options, &options, 15 | sizeof(uWS::SocketContextOptions)); 16 | return (uws_app_t *)new uWS::SSLApp(socket_context_options); 17 | } 18 | 19 | return (uws_app_t *)new uWS::App(); 20 | } 21 | 22 | void uws_app_get(int ssl, uws_app_t *app, const char *pattern, 23 | uws_method_handler handler, void *user_data) { 24 | if (ssl) { 25 | uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; 26 | uwsApp->get(pattern, [handler, user_data](auto *res, auto *req) { 27 | handler((uws_res_t *)res, (uws_req_t *)req, user_data); 28 | }); 29 | } else { 30 | uWS::App *uwsApp = (uWS::App *)app; 31 | uwsApp->get(pattern, [handler, user_data](auto *res, auto *req) { 32 | handler((uws_res_t *)res, (uws_req_t *)req, user_data); 33 | }); 34 | } 35 | } 36 | void uws_app_post(int ssl, uws_app_t *app, const char *pattern, 37 | uws_method_handler handler, void *user_data) { 38 | 39 | if (ssl) { 40 | uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; 41 | uwsApp->post(pattern, [handler, user_data](auto *res, auto *req) { 42 | handler((uws_res_t *)res, (uws_req_t *)req, user_data); 43 | }); 44 | } else { 45 | uWS::App *uwsApp = (uWS::App *)app; 46 | uwsApp->post(pattern, [handler, user_data](auto *res, auto *req) { 47 | handler((uws_res_t *)res, (uws_req_t *)req, user_data); 48 | }); 49 | } 50 | } 51 | void uws_app_options(int ssl, uws_app_t *app, const char *pattern, 52 | uws_method_handler handler, void *user_data) { 53 | if (ssl) { 54 | uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; 55 | uwsApp->options(pattern, [handler, user_data](auto *res, auto *req) { 56 | handler((uws_res_t *)res, (uws_req_t *)req, user_data); 57 | }); 58 | } else { 59 | uWS::App *uwsApp = (uWS::App *)app; 60 | uwsApp->options(pattern, [handler, user_data](auto *res, auto *req) { 61 | handler((uws_res_t *)res, (uws_req_t *)req, user_data); 62 | }); 63 | } 64 | } 65 | void uws_app_delete(int ssl, uws_app_t *app, const char *pattern, 66 | uws_method_handler handler, void *user_data) { 67 | if (ssl) { 68 | uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; 69 | uwsApp->del(pattern, [handler, user_data](auto *res, auto *req) { 70 | handler((uws_res_t *)res, (uws_req_t *)req, user_data); 71 | }); 72 | } else { 73 | uWS::App *uwsApp = (uWS::App *)app; 74 | uwsApp->del(pattern, [handler, user_data](auto *res, auto *req) { 75 | handler((uws_res_t *)res, (uws_req_t *)req, user_data); 76 | }); 77 | } 78 | } 79 | void uws_app_patch(int ssl, uws_app_t *app, const char *pattern, 80 | uws_method_handler handler, void *user_data) { 81 | if (ssl) { 82 | uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; 83 | uwsApp->patch(pattern, [handler, user_data](auto *res, auto *req) { 84 | handler((uws_res_t *)res, (uws_req_t *)req, user_data); 85 | }); 86 | } else { 87 | uWS::App *uwsApp = (uWS::App *)app; 88 | uwsApp->patch(pattern, [handler, user_data](auto *res, auto *req) { 89 | handler((uws_res_t *)res, (uws_req_t *)req, user_data); 90 | }); 91 | } 92 | } 93 | void uws_app_put(int ssl, uws_app_t *app, const char *pattern, 94 | uws_method_handler handler, void *user_data) { 95 | if (ssl) { 96 | uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; 97 | uwsApp->put(pattern, [handler, user_data](auto *res, auto *req) { 98 | handler((uws_res_t *)res, (uws_req_t *)req, user_data); 99 | }); 100 | } else { 101 | uWS::App *uwsApp = (uWS::App *)app; 102 | uwsApp->put(pattern, [handler, user_data](auto *res, auto *req) { 103 | handler((uws_res_t *)res, (uws_req_t *)req, user_data); 104 | }); 105 | } 106 | } 107 | void uws_app_head(int ssl, uws_app_t *app, const char *pattern, 108 | uws_method_handler handler, void *user_data) { 109 | if (ssl) { 110 | uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; 111 | uwsApp->head(pattern, [handler, user_data](auto *res, auto *req) { 112 | handler((uws_res_t *)res, (uws_req_t *)req, user_data); 113 | }); 114 | } else { 115 | uWS::App *uwsApp = (uWS::App *)app; 116 | uwsApp->head(pattern, [handler, user_data](auto *res, auto *req) { 117 | handler((uws_res_t *)res, (uws_req_t *)req, user_data); 118 | }); 119 | } 120 | } 121 | void uws_app_connect(int ssl, uws_app_t *app, const char *pattern, 122 | uws_method_handler handler, void *user_data) { 123 | if (ssl) { 124 | uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; 125 | uwsApp->connect(pattern, [handler, user_data](auto *res, auto *req) { 126 | handler((uws_res_t *)res, (uws_req_t *)req, user_data); 127 | }); 128 | } else { 129 | uWS::App *uwsApp = (uWS::App *)app; 130 | uwsApp->connect(pattern, [handler, user_data](auto *res, auto *req) { 131 | handler((uws_res_t *)res, (uws_req_t *)req, user_data); 132 | }); 133 | } 134 | } 135 | 136 | void uws_app_trace(int ssl, uws_app_t *app, const char *pattern, 137 | uws_method_handler handler, void *user_data) { 138 | if (ssl) { 139 | uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; 140 | uwsApp->trace(pattern, [handler, user_data](auto *res, auto *req) { 141 | handler((uws_res_t *)res, (uws_req_t *)req, user_data); 142 | }); 143 | } else { 144 | uWS::App *uwsApp = (uWS::App *)app; 145 | uwsApp->trace(pattern, [handler, user_data](auto *res, auto *req) { 146 | handler((uws_res_t *)res, (uws_req_t *)req, user_data); 147 | }); 148 | } 149 | } 150 | void uws_app_any(int ssl, uws_app_t *app, const char *pattern, 151 | uws_method_handler handler, void *user_data) { 152 | if (ssl) { 153 | uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; 154 | uwsApp->any(pattern, [handler, user_data](auto *res, auto *req) { 155 | handler((uws_res_t *)res, (uws_req_t *)req, user_data); 156 | }); 157 | } else { 158 | uWS::App *uwsApp = (uWS::App *)app; 159 | uwsApp->any(pattern, [handler, user_data](auto *res, auto *req) { 160 | handler((uws_res_t *)res, (uws_req_t *)req, user_data); 161 | }); 162 | } 163 | } 164 | 165 | void uws_app_run(int ssl, uws_app_t *app) { 166 | if (ssl) { 167 | uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; 168 | uwsApp->run(); 169 | } else { 170 | uWS::App *uwsApp = (uWS::App *)app; 171 | uwsApp->run(); 172 | } 173 | } 174 | 175 | void uws_app_listen(int ssl, uws_app_t *app, int port, 176 | uws_listen_handler handler, void *user_data) { 177 | uws_app_listen_config_t config; 178 | config.port = port; 179 | config.host = nullptr; 180 | config.options = 0; 181 | 182 | if (ssl) { 183 | uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; 184 | uwsApp->listen(port, [handler, config, 185 | user_data](struct us_listen_socket_t *listen_socket) { 186 | handler((struct us_listen_socket_t *)listen_socket, config, user_data); 187 | }); 188 | } else { 189 | uWS::App *uwsApp = (uWS::App *)app; 190 | 191 | uwsApp->listen(port, [handler, config, 192 | user_data](struct us_listen_socket_t *listen_socket) { 193 | handler((struct us_listen_socket_t *)listen_socket, config, user_data); 194 | }); 195 | } 196 | } 197 | 198 | void uws_app_listen_with_config(int ssl, uws_app_t *app, 199 | uws_app_listen_config_t config, 200 | uws_listen_handler handler, void *user_data) { 201 | if (ssl) { 202 | uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; 203 | uwsApp->listen( 204 | config.host, config.port, config.options, 205 | [handler, config, user_data](struct us_listen_socket_t *listen_socket) { 206 | handler((struct us_listen_socket_t *)listen_socket, config, 207 | user_data); 208 | }); 209 | } else { 210 | uWS::App *uwsApp = (uWS::App *)app; 211 | uwsApp->listen( 212 | config.host, config.port, config.options, 213 | [handler, config, user_data](struct us_listen_socket_t *listen_socket) { 214 | handler((struct us_listen_socket_t *)listen_socket, config, 215 | user_data); 216 | }); 217 | } 218 | } 219 | 220 | void uws_app_destroy(int ssl, uws_app_t *app) { 221 | if (ssl) { 222 | uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; 223 | delete uwsApp; 224 | } else { 225 | 226 | uWS::App *uwsApp = (uWS::App *)app; 227 | delete uwsApp; 228 | } 229 | } 230 | 231 | bool uws_constructor_failed(int ssl, uws_app_t *app) { 232 | if (ssl) { 233 | uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; 234 | if (!uwsApp) 235 | return true; 236 | return uwsApp->constructorFailed(); 237 | } 238 | uWS::App *uwsApp = (uWS::App *)app; 239 | if (!uwsApp) 240 | return true; 241 | return uwsApp->constructorFailed(); 242 | } 243 | 244 | unsigned int uws_num_subscribers(int ssl, uws_app_t *app, const char *topic) { 245 | if (ssl) { 246 | uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; 247 | return uwsApp->numSubscribers(topic); 248 | } 249 | uWS::App *uwsApp = (uWS::App *)app; 250 | return uwsApp->numSubscribers(topic); 251 | } 252 | bool uws_publish(int ssl, uws_app_t *app, const char *topic, 253 | size_t topic_length, const char *message, 254 | size_t message_length, uws_opcode_t opcode, bool compress) { 255 | if (ssl) { 256 | uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; 257 | return uwsApp->publish(std::string_view(topic, topic_length), 258 | std::string_view(message, message_length), 259 | (unsigned char)opcode, compress); 260 | } 261 | uWS::App *uwsApp = (uWS::App *)app; 262 | return uwsApp->publish(std::string_view(topic, topic_length), 263 | std::string_view(message, message_length), 264 | (unsigned char)opcode, compress); 265 | } 266 | void *uws_get_native_handle(int ssl, uws_app_t *app) { 267 | if (ssl) { 268 | uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; 269 | return uwsApp->getNativeHandle(); 270 | } 271 | uWS::App *uwsApp = (uWS::App *)app; 272 | return uwsApp->getNativeHandle(); 273 | } 274 | void uws_remove_server_name(int ssl, uws_app_t *app, 275 | const char *hostname_pattern) { 276 | if (ssl) { 277 | uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; 278 | uwsApp->removeServerName(hostname_pattern); 279 | } else { 280 | uWS::App *uwsApp = (uWS::App *)app; 281 | uwsApp->removeServerName(hostname_pattern); 282 | } 283 | } 284 | void uws_add_server_name(int ssl, uws_app_t *app, 285 | const char *hostname_pattern) { 286 | if (ssl) { 287 | uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; 288 | uwsApp->addServerName(hostname_pattern); 289 | } else { 290 | uWS::App *uwsApp = (uWS::App *)app; 291 | uwsApp->addServerName(hostname_pattern); 292 | } 293 | } 294 | void uws_add_server_name_with_options( 295 | int ssl, uws_app_t *app, const char *hostname_pattern, 296 | struct us_socket_context_options_t options) { 297 | uWS::SocketContextOptions sco; 298 | sco.ca_file_name = options.ca_file_name; 299 | sco.cert_file_name = options.cert_file_name; 300 | sco.dh_params_file_name = options.dh_params_file_name; 301 | sco.key_file_name = options.key_file_name; 302 | sco.passphrase = options.passphrase; 303 | sco.ssl_prefer_low_memory_usage = options.ssl_prefer_low_memory_usage; 304 | 305 | if (ssl) { 306 | uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; 307 | uwsApp->addServerName(hostname_pattern, sco); 308 | } else { 309 | uWS::App *uwsApp = (uWS::App *)app; 310 | uwsApp->addServerName(hostname_pattern, sco); 311 | } 312 | } 313 | 314 | void uws_missing_server_name(int ssl, uws_app_t *app, 315 | uws_missing_server_handler handler, 316 | void *user_data) { 317 | if (ssl) { 318 | uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; 319 | uwsApp->missingServerName( 320 | [handler, user_data](auto hostname) { handler(hostname, user_data); }); 321 | } else { 322 | uWS::App *uwsApp = (uWS::App *)app; 323 | uwsApp->missingServerName( 324 | [handler, user_data](auto hostname) { handler(hostname, user_data); }); 325 | } 326 | } 327 | void uws_filter(int ssl, uws_app_t *app, uws_filter_handler handler, 328 | void *user_data) { 329 | if (ssl) { 330 | uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; 331 | uwsApp->filter([handler, user_data](auto res, auto i) { 332 | handler((uws_res_t *)res, i, user_data); 333 | }); 334 | } else { 335 | uWS::App *uwsApp = (uWS::App *)app; 336 | 337 | uwsApp->filter([handler, user_data](auto res, auto i) { 338 | handler((uws_res_t *)res, i, user_data); 339 | }); 340 | } 341 | } 342 | 343 | void uws_ws(int ssl, uws_app_t *app, const char *pattern, 344 | uws_socket_behavior_t behavior) { 345 | if (ssl) { 346 | auto generic_handler = uWS::SSLApp::WebSocketBehavior{ 347 | .compression = (uWS::CompressOptions)(uint64_t)behavior.compression, 348 | .maxPayloadLength = behavior.maxPayloadLength, 349 | .idleTimeout = behavior.idleTimeout, 350 | .maxBackpressure = behavior.maxBackpressure, 351 | .closeOnBackpressureLimit = behavior.closeOnBackpressureLimit, 352 | .resetIdleTimeoutOnSend = behavior.resetIdleTimeoutOnSend, 353 | .sendPingsAutomatically = behavior.sendPingsAutomatically, 354 | .maxLifetime = behavior.maxLifetime, 355 | }; 356 | 357 | if (behavior.upgrade) 358 | generic_handler.upgrade = [behavior](auto *res, auto *req, 359 | auto *context) { 360 | behavior.upgrade((uws_res_t *)res, (uws_req_t *)req, 361 | (uws_socket_context_t *)context); 362 | }; 363 | if (behavior.open) 364 | generic_handler.open = [behavior](auto *ws) { 365 | behavior.open((uws_websocket_t *)ws); 366 | }; 367 | if (behavior.message) 368 | generic_handler.message = [behavior](auto *ws, auto message, 369 | auto opcode) { 370 | behavior.message((uws_websocket_t *)ws, message.data(), 371 | message.length(), (uws_opcode_t)opcode); 372 | }; 373 | if (behavior.drain) 374 | generic_handler.drain = [behavior](auto *ws) { 375 | behavior.drain((uws_websocket_t *)ws); 376 | }; 377 | if (behavior.ping) 378 | generic_handler.ping = [behavior](auto *ws, auto message) { 379 | behavior.ping((uws_websocket_t *)ws, message.data(), message.length()); 380 | }; 381 | if (behavior.pong) 382 | generic_handler.pong = [behavior](auto *ws, auto message) { 383 | behavior.pong((uws_websocket_t *)ws, message.data(), message.length()); 384 | }; 385 | if (behavior.close) 386 | generic_handler.close = [behavior](auto *ws, int code, auto message) { 387 | behavior.close((uws_websocket_t *)ws, code, message.data(), 388 | message.length()); 389 | }; 390 | uWS::SSLApp *uwsApp = (uWS::SSLApp *)app; 391 | 392 | uwsApp->ws(pattern, std::move(generic_handler)); 393 | } else { 394 | auto generic_handler = uWS::App::WebSocketBehavior{ 395 | .compression = (uWS::CompressOptions)(uint64_t)behavior.compression, 396 | .maxPayloadLength = behavior.maxPayloadLength, 397 | .idleTimeout = behavior.idleTimeout, 398 | .maxBackpressure = behavior.maxBackpressure, 399 | .closeOnBackpressureLimit = behavior.closeOnBackpressureLimit, 400 | .resetIdleTimeoutOnSend = behavior.resetIdleTimeoutOnSend, 401 | .sendPingsAutomatically = behavior.sendPingsAutomatically, 402 | .maxLifetime = behavior.maxLifetime, 403 | }; 404 | 405 | if (behavior.upgrade) 406 | generic_handler.upgrade = [behavior](auto *res, auto *req, 407 | auto *context) { 408 | behavior.upgrade((uws_res_t *)res, (uws_req_t *)req, 409 | (uws_socket_context_t *)context); 410 | }; 411 | if (behavior.open) 412 | generic_handler.open = [behavior](auto *ws) { 413 | behavior.open((uws_websocket_t *)ws); 414 | }; 415 | if (behavior.message) 416 | generic_handler.message = [behavior](auto *ws, auto message, 417 | auto opcode) { 418 | behavior.message((uws_websocket_t *)ws, message.data(), 419 | message.length(), (uws_opcode_t)opcode); 420 | }; 421 | if (behavior.drain) 422 | generic_handler.drain = [behavior](auto *ws) { 423 | behavior.drain((uws_websocket_t *)ws); 424 | }; 425 | if (behavior.ping) 426 | generic_handler.ping = [behavior](auto *ws, auto message) { 427 | behavior.ping((uws_websocket_t *)ws, message.data(), message.length()); 428 | }; 429 | if (behavior.pong) 430 | generic_handler.pong = [behavior](auto *ws, auto message) { 431 | behavior.pong((uws_websocket_t *)ws, message.data(), message.length()); 432 | }; 433 | if (behavior.close) 434 | generic_handler.close = [behavior](auto *ws, int code, auto message) { 435 | behavior.close((uws_websocket_t *)ws, code, message.data(), 436 | message.length()); 437 | }; 438 | uWS::App *uwsApp = (uWS::App *)app; 439 | uwsApp->ws(pattern, std::move(generic_handler)); 440 | } 441 | } 442 | 443 | void *uws_ws_get_user_data(int ssl, uws_websocket_t *ws) { 444 | if (ssl) { 445 | uWS::WebSocket *uws = 446 | (uWS::WebSocket *)ws; 447 | return *uws->getUserData(); 448 | } 449 | uWS::WebSocket *uws = 450 | (uWS::WebSocket *)ws; 451 | return *uws->getUserData(); 452 | } 453 | 454 | void uws_ws_close(int ssl, uws_websocket_t *ws) { 455 | if (ssl) { 456 | uWS::WebSocket *uws = 457 | (uWS::WebSocket *)ws; 458 | uws->close(); 459 | } else { 460 | uWS::WebSocket *uws = 461 | (uWS::WebSocket *)ws; 462 | uws->close(); 463 | } 464 | } 465 | 466 | uws_sendstatus_t uws_ws_send(int ssl, uws_websocket_t *ws, const char *message, 467 | size_t length, uws_opcode_t opcode) { 468 | if (ssl) { 469 | uWS::WebSocket *uws = 470 | (uWS::WebSocket *)ws; 471 | return (uws_sendstatus_t)uws->send(std::string_view(message, length), 472 | (uWS::OpCode)(unsigned char)opcode); 473 | } 474 | uWS::WebSocket *uws = 475 | (uWS::WebSocket *)ws; 476 | return (uws_sendstatus_t)uws->send(std::string_view(message, length), 477 | (uWS::OpCode)(unsigned char)opcode); 478 | } 479 | 480 | uws_sendstatus_t uws_ws_send_with_options(int ssl, uws_websocket_t *ws, 481 | const char *message, size_t length, 482 | uws_opcode_t opcode, bool compress, 483 | bool fin) { 484 | if (ssl) { 485 | uWS::WebSocket *uws = 486 | (uWS::WebSocket *)ws; 487 | return (uws_sendstatus_t)uws->send(std::string_view(message), 488 | (uWS::OpCode)(unsigned char)opcode, 489 | compress, fin); 490 | } 491 | uWS::WebSocket *uws = 492 | (uWS::WebSocket *)ws; 493 | return (uws_sendstatus_t)uws->send(std::string_view(message), 494 | (uWS::OpCode)(unsigned char)opcode, 495 | compress, fin); 496 | } 497 | 498 | uws_sendstatus_t uws_ws_send_fragment(int ssl, uws_websocket_t *ws, 499 | const char *message, size_t length, 500 | bool compress) { 501 | if (ssl) { 502 | uWS::WebSocket *uws = 503 | (uWS::WebSocket *)ws; 504 | return (uws_sendstatus_t)uws->sendFragment( 505 | std::string_view(message, length), compress); 506 | } 507 | uWS::WebSocket *uws = 508 | (uWS::WebSocket *)ws; 509 | return (uws_sendstatus_t)uws->sendFragment(std::string_view(message, length), 510 | compress); 511 | } 512 | uws_sendstatus_t uws_ws_send_first_fragment(int ssl, uws_websocket_t *ws, 513 | const char *message, size_t length, 514 | bool compress) { 515 | if (ssl) { 516 | uWS::WebSocket *uws = 517 | (uWS::WebSocket *)ws; 518 | return (uws_sendstatus_t)uws->sendFirstFragment( 519 | std::string_view(message), uWS::OpCode::BINARY, compress); 520 | } 521 | uWS::WebSocket *uws = 522 | (uWS::WebSocket *)ws; 523 | return (uws_sendstatus_t)uws->sendFirstFragment( 524 | std::string_view(message), uWS::OpCode::BINARY, compress); 525 | } 526 | uws_sendstatus_t 527 | uws_ws_send_first_fragment_with_opcode(int ssl, uws_websocket_t *ws, 528 | const char *message, size_t length, 529 | uws_opcode_t opcode, bool compress) { 530 | if (ssl) { 531 | uWS::WebSocket *uws = 532 | (uWS::WebSocket *)ws; 533 | return (uws_sendstatus_t)uws->sendFirstFragment( 534 | std::string_view(message, length), (uWS::OpCode)(unsigned char)opcode, 535 | compress); 536 | } 537 | uWS::WebSocket *uws = 538 | (uWS::WebSocket *)ws; 539 | return (uws_sendstatus_t)uws->sendFirstFragment( 540 | std::string_view(message, length), (uWS::OpCode)(unsigned char)opcode, 541 | compress); 542 | } 543 | uws_sendstatus_t uws_ws_send_last_fragment(int ssl, uws_websocket_t *ws, 544 | const char *message, size_t length, 545 | bool compress) { 546 | if (ssl) { 547 | uWS::WebSocket *uws = 548 | (uWS::WebSocket *)ws; 549 | return (uws_sendstatus_t)uws->sendLastFragment( 550 | std::string_view(message, length), compress); 551 | } 552 | uWS::WebSocket *uws = 553 | (uWS::WebSocket *)ws; 554 | return (uws_sendstatus_t)uws->sendLastFragment( 555 | std::string_view(message, length), compress); 556 | } 557 | 558 | void uws_ws_end(int ssl, uws_websocket_t *ws, int code, const char *message, 559 | size_t length) { 560 | if (ssl) { 561 | uWS::WebSocket *uws = 562 | (uWS::WebSocket *)ws; 563 | uws->end(code, std::string_view(message, length)); 564 | } else { 565 | uWS::WebSocket *uws = 566 | (uWS::WebSocket *)ws; 567 | uws->end(code, std::string_view(message, length)); 568 | } 569 | } 570 | 571 | void uws_ws_cork(int ssl, uws_websocket_t *ws, void (*handler)(void *user_data), 572 | void *user_data) { 573 | if (ssl) { 574 | uWS::WebSocket *uws = 575 | (uWS::WebSocket *)ws; 576 | uws->cork([handler, user_data]() { handler(user_data); }); 577 | } else { 578 | uWS::WebSocket *uws = 579 | (uWS::WebSocket *)ws; 580 | 581 | uws->cork([handler, user_data]() { handler(user_data); }); 582 | } 583 | } 584 | bool uws_ws_subscribe(int ssl, uws_websocket_t *ws, const char *topic, 585 | size_t length) { 586 | if (ssl) { 587 | uWS::WebSocket *uws = 588 | (uWS::WebSocket *)ws; 589 | return uws->subscribe(std::string_view(topic, length)); 590 | } 591 | uWS::WebSocket *uws = 592 | (uWS::WebSocket *)ws; 593 | return uws->subscribe(std::string_view(topic, length)); 594 | } 595 | bool uws_ws_unsubscribe(int ssl, uws_websocket_t *ws, const char *topic, 596 | size_t length) { 597 | if (ssl) { 598 | uWS::WebSocket *uws = 599 | (uWS::WebSocket *)ws; 600 | return uws->unsubscribe(std::string_view(topic, length)); 601 | } 602 | uWS::WebSocket *uws = 603 | (uWS::WebSocket *)ws; 604 | return uws->unsubscribe(std::string_view(topic, length)); 605 | } 606 | 607 | bool uws_ws_is_subscribed(int ssl, uws_websocket_t *ws, const char *topic, 608 | size_t length) { 609 | if (ssl) { 610 | uWS::WebSocket *uws = 611 | (uWS::WebSocket *)ws; 612 | return uws->isSubscribed(std::string_view(topic, length)); 613 | } 614 | uWS::WebSocket *uws = 615 | (uWS::WebSocket *)ws; 616 | return uws->isSubscribed(std::string_view(topic, length)); 617 | } 618 | void uws_ws_iterate_topics(int ssl, uws_websocket_t *ws, 619 | void (*callback)(const char *topic, size_t length, 620 | void *user_data), 621 | void *user_data) { 622 | if (ssl) { 623 | uWS::WebSocket *uws = 624 | (uWS::WebSocket *)ws; 625 | uws->iterateTopics([callback, user_data](auto topic) { 626 | callback(topic.data(), topic.length(), user_data); 627 | }); 628 | } else { 629 | uWS::WebSocket *uws = 630 | (uWS::WebSocket *)ws; 631 | 632 | uws->iterateTopics([callback, user_data](auto topic) { 633 | callback(topic.data(), topic.length(), user_data); 634 | }); 635 | } 636 | } 637 | 638 | bool uws_ws_publish(int ssl, uws_websocket_t *ws, const char *topic, 639 | size_t topic_length, const char *message, 640 | size_t message_length) { 641 | if (ssl) { 642 | uWS::WebSocket *uws = 643 | (uWS::WebSocket *)ws; 644 | return uws->publish(std::string_view(topic, topic_length), 645 | std::string_view(message, message_length)); 646 | } 647 | uWS::WebSocket *uws = 648 | (uWS::WebSocket *)ws; 649 | return uws->publish(std::string_view(topic, topic_length), 650 | std::string_view(message, message_length)); 651 | } 652 | 653 | bool uws_ws_publish_with_options(int ssl, uws_websocket_t *ws, 654 | const char *topic, size_t topic_length, 655 | const char *message, size_t message_length, 656 | uws_opcode_t opcode, bool compress) { 657 | if (ssl) { 658 | uWS::WebSocket *uws = 659 | (uWS::WebSocket *)ws; 660 | return uws->publish(std::string_view(topic, topic_length), 661 | std::string_view(message, message_length), 662 | (uWS::OpCode)(unsigned char)opcode, compress); 663 | } 664 | uWS::WebSocket *uws = 665 | (uWS::WebSocket *)ws; 666 | return uws->publish(std::string_view(topic, topic_length), 667 | std::string_view(message, message_length), 668 | (uWS::OpCode)(unsigned char)opcode, compress); 669 | } 670 | 671 | unsigned int uws_ws_get_buffered_amount(int ssl, uws_websocket_t *ws) { 672 | if (ssl) { 673 | uWS::WebSocket *uws = 674 | (uWS::WebSocket *)ws; 675 | return uws->getBufferedAmount(); 676 | } 677 | uWS::WebSocket *uws = 678 | (uWS::WebSocket *)ws; 679 | return uws->getBufferedAmount(); 680 | } 681 | 682 | size_t uws_ws_get_remote_address(int ssl, uws_websocket_t *ws, 683 | const char **dest) { 684 | if (ssl) { 685 | uWS::WebSocket *uws = 686 | (uWS::WebSocket *)ws; 687 | std::string_view value = uws->getRemoteAddress(); 688 | *dest = value.data(); 689 | return value.length(); 690 | } 691 | uWS::WebSocket *uws = 692 | (uWS::WebSocket *)ws; 693 | 694 | std::string_view value = uws->getRemoteAddress(); 695 | *dest = value.data(); 696 | return value.length(); 697 | } 698 | 699 | size_t uws_ws_get_remote_address_as_text(int ssl, uws_websocket_t *ws, 700 | const char **dest) { 701 | if (ssl) { 702 | uWS::WebSocket *uws = 703 | (uWS::WebSocket *)ws; 704 | 705 | std::string_view value = uws->getRemoteAddressAsText(); 706 | *dest = value.data(); 707 | return value.length(); 708 | } 709 | uWS::WebSocket *uws = 710 | (uWS::WebSocket *)ws; 711 | 712 | std::string_view value = uws->getRemoteAddressAsText(); 713 | *dest = value.data(); 714 | return value.length(); 715 | } 716 | 717 | void uws_res_end(int ssl, uws_res_t *res, const char *data, size_t length, 718 | bool close_connection) { 719 | if (ssl) { 720 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 721 | uwsRes->end(std::string_view(data, length), close_connection); 722 | } else { 723 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 724 | uwsRes->end(std::string_view(data, length), close_connection); 725 | } 726 | } 727 | 728 | void uws_res_end_stream(int ssl, uws_res_t *res, bool close_connection) { 729 | if (ssl) { 730 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 731 | uwsRes->endWithoutBody(std::nullopt, close_connection); 732 | } else { 733 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 734 | uwsRes->endWithoutBody(std::nullopt, close_connection); 735 | } 736 | } 737 | 738 | void uws_res_pause(int ssl, uws_res_t *res) { 739 | if (ssl) { 740 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 741 | uwsRes->pause(); 742 | } else { 743 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 744 | uwsRes->pause(); 745 | } 746 | } 747 | 748 | void uws_res_resume(int ssl, uws_res_t *res) { 749 | if (ssl) { 750 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 751 | uwsRes->pause(); 752 | } else { 753 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 754 | uwsRes->pause(); 755 | } 756 | } 757 | 758 | void uws_res_write_continue(int ssl, uws_res_t *res) { 759 | if (ssl) { 760 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 761 | uwsRes->writeContinue(); 762 | } else { 763 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 764 | uwsRes->writeContinue(); 765 | } 766 | } 767 | 768 | void uws_res_write_status(int ssl, uws_res_t *res, const char *status, 769 | size_t length) { 770 | if (ssl) { 771 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 772 | uwsRes->writeStatus(std::string_view(status, length)); 773 | } else { 774 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 775 | uwsRes->writeStatus(std::string_view(status, length)); 776 | } 777 | } 778 | 779 | void uws_res_write_header(int ssl, uws_res_t *res, const char *key, 780 | size_t key_length, const char *value, 781 | size_t value_length) { 782 | if (ssl) { 783 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 784 | uwsRes->writeHeader(std::string_view(key, key_length), 785 | std::string_view(value, value_length)); 786 | } else { 787 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 788 | uwsRes->writeHeader(std::string_view(key, key_length), 789 | std::string_view(value, value_length)); 790 | } 791 | } 792 | void uws_res_write_header_int(int ssl, uws_res_t *res, const char *key, 793 | size_t key_length, uint64_t value) { 794 | if (ssl) { 795 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 796 | uwsRes->writeHeader(std::string_view(key, key_length), value); 797 | } else { 798 | 799 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 800 | uwsRes->writeHeader(std::string_view(key, key_length), value); 801 | } 802 | } 803 | 804 | void uws_res_end_without_body(int ssl, uws_res_t *res) { 805 | if (ssl) { 806 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 807 | uwsRes->getHttpResponseData()->state |= 808 | uWS::HttpResponseData::HTTP_END_CALLED; 809 | uwsRes->markDone(uwsRes->getHttpResponseData()); 810 | us_socket_timeout(true, (us_socket_t *)uwsRes, uWS::HTTP_TIMEOUT_S); 811 | } else { 812 | 813 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 814 | uwsRes->getHttpResponseData()->state |= 815 | uWS::HttpResponseData::HTTP_END_CALLED; 816 | uwsRes->markDone(uwsRes->getHttpResponseData()); 817 | us_socket_timeout(false, (us_socket_t *)uwsRes, uWS::HTTP_TIMEOUT_S); 818 | } 819 | } 820 | 821 | bool uws_res_write(int ssl, uws_res_t *res, const char *data, size_t length) { 822 | if (ssl) { 823 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 824 | return uwsRes->write(std::string_view(data, length)); 825 | } 826 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 827 | return uwsRes->write(std::string_view(data, length)); 828 | } 829 | uintmax_t uws_res_get_write_offset(int ssl, uws_res_t *res) { 830 | if (ssl) { 831 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 832 | return uwsRes->getWriteOffset(); 833 | } 834 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 835 | return uwsRes->getWriteOffset(); 836 | } 837 | 838 | bool uws_res_has_responded(int ssl, uws_res_t *res) { 839 | if (ssl) { 840 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 841 | return uwsRes->hasResponded(); 842 | } 843 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 844 | return uwsRes->hasResponded(); 845 | } 846 | 847 | void uws_res_on_writable(int ssl, uws_res_t *res, 848 | bool (*handler)(uws_res_t *res, uintmax_t, 849 | void *opcional_data), 850 | void *opcional_data) { 851 | if (ssl) { 852 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 853 | uwsRes->onWritable([handler, res, opcional_data](uintmax_t a) { 854 | return handler(res, a, opcional_data); 855 | }); 856 | } else { 857 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 858 | uwsRes->onWritable([handler, res, opcional_data](uintmax_t a) { 859 | return handler(res, a, opcional_data); 860 | }); 861 | } 862 | } 863 | 864 | void uws_res_on_aborted(int ssl, uws_res_t *res, 865 | void (*handler)(uws_res_t *res, void *opcional_data), 866 | void *opcional_data) { 867 | if (ssl) { 868 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 869 | if (handler) { 870 | uwsRes->onAborted( 871 | [handler, res, opcional_data] { handler(res, opcional_data); }); 872 | } else { 873 | uwsRes->onAborted(nullptr); 874 | } 875 | } else { 876 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 877 | if (handler) { 878 | uwsRes->onAborted( 879 | [handler, res, opcional_data] { handler(res, opcional_data); }); 880 | } else { 881 | uwsRes->onAborted(nullptr); 882 | } 883 | } 884 | } 885 | 886 | void uws_res_on_data(int ssl, uws_res_t *res, 887 | void (*handler)(uws_res_t *res, const char *chunk, 888 | size_t chunk_length, bool is_end, 889 | void *opcional_data), 890 | void *opcional_data) { 891 | if (ssl) { 892 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 893 | uwsRes->onData([handler, res, opcional_data](auto chunk, bool is_end) { 894 | handler(res, chunk.data(), chunk.length(), is_end, opcional_data); 895 | }); 896 | } else { 897 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 898 | uwsRes->onData([handler, res, opcional_data](auto chunk, bool is_end) { 899 | handler(res, chunk.data(), chunk.length(), is_end, opcional_data); 900 | }); 901 | } 902 | } 903 | 904 | bool uws_req_is_ancient(uws_req_t *res) { 905 | uWS::HttpRequest *uwsReq = (uWS::HttpRequest *)res; 906 | return uwsReq->isAncient(); 907 | } 908 | 909 | bool uws_req_get_yield(uws_req_t *res) { 910 | uWS::HttpRequest *uwsReq = (uWS::HttpRequest *)res; 911 | return uwsReq->getYield(); 912 | } 913 | 914 | void uws_req_set_field(uws_req_t *res, bool yield) { 915 | uWS::HttpRequest *uwsReq = (uWS::HttpRequest *)res; 916 | return uwsReq->setYield(yield); 917 | } 918 | 919 | size_t uws_req_get_url(uws_req_t *res, const char **dest) { 920 | uWS::HttpRequest *uwsReq = (uWS::HttpRequest *)res; 921 | std::string_view value = uwsReq->getFullUrl(); 922 | *dest = value.data(); 923 | return value.length(); 924 | } 925 | 926 | size_t uws_req_get_method(uws_req_t *res, const char **dest) { 927 | uWS::HttpRequest *uwsReq = (uWS::HttpRequest *)res; 928 | std::string_view value = uwsReq->getMethod(); 929 | *dest = value.data(); 930 | return value.length(); 931 | } 932 | 933 | size_t uws_req_get_header(uws_req_t *res, const char *lower_case_header, 934 | size_t lower_case_header_length, const char **dest) { 935 | uWS::HttpRequest *uwsReq = (uWS::HttpRequest *)res; 936 | 937 | std::string_view value = uwsReq->getHeader( 938 | std::string_view(lower_case_header, lower_case_header_length)); 939 | *dest = value.data(); 940 | return value.length(); 941 | } 942 | 943 | size_t uws_req_get_query(uws_req_t *res, const char *key, size_t key_length, 944 | const char **dest) { 945 | uWS::HttpRequest *uwsReq = (uWS::HttpRequest *)res; 946 | 947 | std::string_view value = uwsReq->getQuery(std::string_view(key, key_length)); 948 | *dest = value.data(); 949 | return value.length(); 950 | } 951 | 952 | size_t uws_req_get_parameter(uws_req_t *res, unsigned short index, 953 | const char **dest) { 954 | uWS::HttpRequest *uwsReq = (uWS::HttpRequest *)res; 955 | std::string_view value = uwsReq->getParameter(index); 956 | *dest = value.data(); 957 | return value.length(); 958 | } 959 | 960 | void uws_res_upgrade(int ssl, uws_res_t *res, void *data, 961 | const char *sec_web_socket_key, 962 | size_t sec_web_socket_key_length, 963 | const char *sec_web_socket_protocol, 964 | size_t sec_web_socket_protocol_length, 965 | const char *sec_web_socket_extensions, 966 | size_t sec_web_socket_extensions_length, 967 | uws_socket_context_t *ws) { 968 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 969 | 970 | uwsRes->template upgrade( 971 | data ? std::move(data) : NULL, 972 | std::string_view(sec_web_socket_key, sec_web_socket_key_length), 973 | std::string_view(sec_web_socket_protocol, sec_web_socket_protocol_length), 974 | std::string_view(sec_web_socket_extensions, 975 | sec_web_socket_extensions_length), 976 | (struct us_socket_context_t *)ws); 977 | } 978 | 979 | struct us_loop_t *uws_get_loop() { 980 | return (struct us_loop_t *)uWS::Loop::get(); 981 | } 982 | 983 | void uws_loop_addPostHandler(us_loop_t *loop, void *ctx_, 984 | void (*cb)(void *ctx, us_loop_t *loop)) { 985 | uWS::Loop *uwsLoop = (uWS::Loop *)loop; 986 | uwsLoop->addPostHandler(ctx_, [ctx_, cb](uWS::Loop *uwsLoop_) { 987 | cb(ctx_, (us_loop_t *)uwsLoop_); 988 | }); 989 | } 990 | void uws_loop_removePostHandler(us_loop_t *loop, void *key) { 991 | uWS::Loop *uwsLoop = (uWS::Loop *)loop; 992 | uwsLoop->removePostHandler(key); 993 | } 994 | void uws_loop_addPreHandler(us_loop_t *loop, void *ctx_, 995 | void (*cb)(void *ctx, us_loop_t *loop)) { 996 | uWS::Loop *uwsLoop = (uWS::Loop *)loop; 997 | uwsLoop->addPreHandler(ctx_, [ctx_, cb](uWS::Loop *uwsLoop_) { 998 | cb(ctx_, (us_loop_t *)uwsLoop_); 999 | }); 1000 | } 1001 | void uws_loop_removePreHandler(us_loop_t *loop, void *ctx_) { 1002 | uWS::Loop *uwsLoop = (uWS::Loop *)loop; 1003 | uwsLoop->removePreHandler(ctx_); 1004 | } 1005 | void uws_loop_defer(us_loop_t *loop, void *ctx, void (*cb)(void *ctx)) { 1006 | uWS::Loop *uwsLoop = (uWS::Loop *)loop; 1007 | uwsLoop->defer([ctx, cb]() { cb(ctx); }); 1008 | } 1009 | 1010 | void uws_res_write_headers(int ssl, uws_res_t *res, const StringPointer *names, 1011 | const StringPointer *values, size_t count, 1012 | const char *buf) { 1013 | if (ssl) { 1014 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 1015 | for (size_t i = 0; i < count; i++) { 1016 | uwsRes->writeHeader(std::string_view(&buf[names[i].off], names[i].len), 1017 | std::string_view(&buf[values[i].off], values[i].len)); 1018 | } 1019 | 1020 | } else { 1021 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 1022 | for (size_t i = 0; i < count; i++) { 1023 | uwsRes->writeHeader(std::string_view(&buf[names[i].off], names[i].len), 1024 | std::string_view(&buf[values[i].off], values[i].len)); 1025 | } 1026 | } 1027 | } 1028 | 1029 | void uws_res_uncork(int ssl, uws_res_t *res) { 1030 | if (ssl) { 1031 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 1032 | uwsRes->uncork(); 1033 | } else { 1034 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 1035 | uwsRes->uncork(); 1036 | } 1037 | } 1038 | 1039 | void us_socket_mark_needs_more_not_ssl(uws_res_t *res) { 1040 | us_socket_t *s = (us_socket_t *)res; 1041 | s->context->loop->data.last_write_failed = 1; 1042 | us_poll_change(&s->p, s->context->loop, 1043 | LIBUS_SOCKET_READABLE | LIBUS_SOCKET_WRITABLE); 1044 | } 1045 | 1046 | void uws_res_set_write_offset(int ssl, uws_res_t *res, size_t off) { 1047 | if (ssl) { 1048 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 1049 | uwsRes->setWriteOffset(off); 1050 | } else { 1051 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 1052 | uwsRes->setWriteOffset(off); 1053 | } 1054 | } 1055 | 1056 | void uws_res_cork(int ssl, uws_res_t *res, void *ctx, 1057 | void (*corker)(void *ctx)) { 1058 | if (ssl) { 1059 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 1060 | uwsRes->cork([ctx, corker]() { corker(ctx); }); 1061 | 1062 | } else { 1063 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 1064 | uwsRes->cork([ctx, corker]() { corker(ctx); }); 1065 | } 1066 | } 1067 | 1068 | void uws_res_prepare_for_sendfile(int ssl, uws_res_t *res) { 1069 | if (ssl) { 1070 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 1071 | auto pair = uwsRes->getSendBuffer(2); 1072 | char *ptr = pair.first; 1073 | ptr[0] = '\r'; 1074 | ptr[1] = '\n'; 1075 | uwsRes->uncork(); 1076 | } else { 1077 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 1078 | auto pair = uwsRes->getSendBuffer(2); 1079 | char *ptr = pair.first; 1080 | ptr[0] = '\r'; 1081 | ptr[1] = '\n'; 1082 | uwsRes->uncork(); 1083 | } 1084 | } 1085 | 1086 | bool uws_res_try_end(int ssl, uws_res_t *res, const char *bytes, size_t len, 1087 | size_t total_len) { 1088 | if (ssl) { 1089 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 1090 | return uwsRes->tryEnd(std::string_view(bytes, len), total_len).first; 1091 | } else { 1092 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 1093 | return uwsRes->tryEnd(std::string_view(bytes, len), total_len).first; 1094 | } 1095 | } 1096 | 1097 | void *uws_res_get_native_handle(int ssl, uws_res_t *res) { 1098 | if (ssl) { 1099 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 1100 | return uwsRes->getNativeHandle(); 1101 | } else { 1102 | uWS::HttpResponse *uwsRes = (uWS::HttpResponse *)res; 1103 | return uwsRes->getNativeHandle(); 1104 | } 1105 | } 1106 | } 1107 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SHELL := /bin/bash # Use bash syntax to be consistent 2 | 3 | OS_NAME := $(shell uname -s | tr '[:upper:]' '[:lower:]') 4 | ARCH_NAME_RAW := $(shell uname -m) 5 | BUN_AUTO_UPDATER_REPO = Jarred-Sumner/bun-releases-for-updater 6 | 7 | # On Linux ARM64, uname -m reports aarch64 8 | ifeq ($(ARCH_NAME_RAW),aarch64) 9 | ARCH_NAME_RAW = arm64 10 | endif 11 | #BREW_DEPS_DIR=SET BY GITHUB ACTIONS 12 | MARCH_NATIVE = -mtune=native 13 | ARCH_NAME := 14 | DOCKER_BUILDARCH = 15 | ifeq ($(ARCH_NAME_RAW),arm64) 16 | ARCH_NAME = aarch64 17 | DOCKER_BUILDARCH = arm64 18 | BREW_PREFIX_PATH = /opt/homebrew 19 | MIN_MACOS_VERSION ?= 11.0 20 | MARCH_NATIVE = -mtune=native 21 | else 22 | ARCH_NAME = x64 23 | DOCKER_BUILDARCH = amd64 24 | BREW_PREFIX_PATH = /usr/local 25 | MIN_MACOS_VERSION ?= 10.14 26 | MARCH_NATIVE = -march=native -mtune=native 27 | endif 28 | 29 | BUN_OR_NODE = $(shell which bun || which node) 30 | 31 | CXX_VERSION=c++2a 32 | TRIPLET = $(OS_NAME)-$(ARCH_NAME) 33 | PACKAGE_NAME = bun-$(TRIPLET) 34 | PACKAGES_REALPATH = $(realpath packages) 35 | PACKAGE_DIR = $(PACKAGES_REALPATH)/$(PACKAGE_NAME) 36 | DEBUG_PACKAGE_DIR = $(PACKAGES_REALPATH)/debug-$(PACKAGE_NAME) 37 | RELEASE_BUN = $(PACKAGE_DIR)/bun 38 | DEBUG_BIN = $(DEBUG_PACKAGE_DIR)/ 39 | DEBUG_BUN = $(DEBUG_BIN)/bun-debug 40 | BUILD_ID = $(shell cat ./build-id) 41 | PACKAGE_JSON_VERSION = 0.1.$(BUILD_ID) 42 | BUN_BUILD_TAG = bun-v$(PACKAGE_JSON_VERSION) 43 | BUN_RELEASE_BIN = $(PACKAGE_DIR)/bun 44 | PRETTIER ?= $(shell which prettier || echo "./node_modules/.bin/prettier") 45 | DSYMUTIL ?= $(shell which dsymutil || which dsymutil-13) 46 | WEBKIT_DIR ?= $(realpath deps/WebKit) 47 | WEBKIT_RELEASE_DIR ?= $(WEBKIT_DIR)/WebKitBuild/Release 48 | WEBKIT_DEBUG_DIR ?= $(WEBKIT_DIR)/WebKitBuild/Debug 49 | WEBKIT_RELEASE_DIR_LTO ?= $(WEBKIT_DIR)/WebKitBuild/ReleaseLTO 50 | 51 | NPM_CLIENT ?= $(shell which bun || which npm) 52 | ZIG ?= $(shell which zig || echo -e "error: Missing zig. Please make sure zig is in PATH. Or set ZIG=/path/to-zig-executable") 53 | 54 | ifeq ($(OS_NAME),darwin) 55 | LLVM_PREFIX ?= $(shell brew --prefix llvm) 56 | LDFLAGS += " -L$(LLVM_PREFIX)/lib" 57 | CPPFLAGS += " -I$(LLVM_PREFIX)/include" 58 | # CC = $(LLVM_PREFIX)/bin/clang-13 59 | # CXX = $(LLVM_PREFIX)/bin/clang-13++ 60 | CODESIGN_IDENTITY ?= $(shell security find-identity -v -p codesigning | awk '/Apple Development/ { print $$2 }') 61 | endif 62 | 63 | # macOS sed is different 64 | SED = $(shell which gsed || which sed) 65 | 66 | REPO_ROOT = $(shell pwd) 67 | BUN_DIR ?= $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) 68 | BUN_DEPS_DIR = $(REPO_ROOT)/deps 69 | BUN_DEPS_OUT_DIR ?= $(BUN_DEPS_DIR) 70 | 71 | ifeq ($(CPUS)$(OS_NAME),darwin) 72 | CPUS=$(sysctl -n hw.logicalcpu) 73 | endif 74 | 75 | ifeq ($(CPUS)$(OS_NAME),linux) 76 | CPUS=$(nproc) 77 | endif 78 | 79 | CPUS ?= $(shell nproc) 80 | USER ?= $(echo $USER) 81 | BUN_PKG?=$(REPO_ROOT)/pkg 82 | BUN_PKG_INCLUDE?=$(BUN_PKG)/include 83 | BUN_PKG_LIB?=$(BUN_PKG)/lib 84 | 85 | BUN_RELEASE_DIR ?= $(shell pwd)/../bun-release 86 | 87 | OPENSSL_VERSION = OpenSSL_1_1_1l 88 | LIBICONV_PATH ?= $(BREW_PREFIX_PATH)/opt/libiconv/lib/libiconv.a 89 | 90 | OPENSSL_LINUX_DIR = $(BUN_DEPS_DIR)/openssl/openssl-OpenSSL_1_1_1l 91 | 92 | CMAKE_FLAGS_WITHOUT_RELEASE = -DCMAKE_C_COMPILER=$(CC) -DCMAKE_CXX_COMPILER=$(CXX) -DCMAKE_OSX_DEPLOYMENT_TARGET=$(MIN_MACOS_VERSION) 93 | CMAKE_FLAGS = $(CMAKE_FLAGS_WITHOUT_RELEASE) -DCMAKE_BUILD_TYPE=Release 94 | 95 | # SQLite3 is dynamically linked on macOS 96 | # it is about 30% faster to use system SQLite3 on macOS (something something kernel page cache) 97 | # on Linux, it is statically linked 98 | SQLITE_OBJECT = 99 | 100 | 101 | BITCODE_OR_SECTIONS=-fdata-sections -ffunction-sections 102 | EMBED_OR_EMIT_BITCODE= 103 | LIBTOOL=libtoolize 104 | 105 | ifeq ($(OS_NAME),darwin) 106 | LIBTOOL=glibtoolize 107 | BITCODE_OR_SECTIONS=-fembed-bitcode 108 | endif 109 | 110 | LLVM_INCLUDE_DIRS=$(LLVM_PREFIX)/include 111 | CLANG_INCLUDE_DIRS=$(LLVM_PREFIX)/include 112 | LLD_INCLUDE_DIRS=$(LLVM_PREFIX)/include 113 | 114 | OPTIMIZATION_LEVEL=-O3 $(MARCH_NATIVE) 115 | CFLAGS = $(MACOS_MIN_FLAG) $(MARCH_NATIVE) $(BITCODE_OR_SECTIONS) $(OPTIMIZATION_LEVEL) -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidden 116 | BUN_CFLAGS = $(MACOS_MIN_FLAG) $(MARCH_NATIVE) $(EMBED_OR_EMIT_BITCODE) $(OPTIMIZATION_LEVEL) -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidden 117 | BUN_TMP_DIR := /tmp/make-bun 118 | BUN_DEPLOY_DIR = /tmp/bun-v$(PACKAGE_JSON_VERSION)/$(PACKAGE_NAME) 119 | 120 | 121 | DEFAULT_USE_BMALLOC := 1 122 | 123 | 124 | USE_BMALLOC ?= DEFAULT_USE_BMALLOC 125 | 126 | JSC_BASE_DIR ?= ${HOME}/webkit-build 127 | 128 | DEFAULT_JSC_LIB := 129 | DEFAULT_JSC_LIB_DEBUG := 130 | 131 | ifeq ($(OS_NAME),linux) 132 | DEFAULT_JSC_LIB = $(JSC_BASE_DIR)/lib 133 | DEFAULT_JSC_LIB_DEBUG = $(DEFAULT_JSC_LIB) 134 | endif 135 | 136 | ifeq ($(OS_NAME),darwin) 137 | DEFAULT_JSC_LIB = $(WEBKIT_RELEASE_DIR_LTO)/lib 138 | DEFAULT_JSC_LIB_DEBUG = $(WEBKIT_RELEASE_DIR)/lib 139 | endif 140 | 141 | JSC_LIB ?= $(DEFAULT_JSC_LIB) 142 | JSC_LIB_DEBUG ?= $(DEFAULT_JSC_LIB_DEBUG) 143 | 144 | JSC_INCLUDE_DIR ?= $(JSC_BASE_DIR)/include 145 | ZLIB_INCLUDE_DIR ?= $(BUN_DEPS_DIR)/zlib 146 | ZLIB_LIB_DIR ?= $(BUN_DEPS_DIR)/zlib 147 | 148 | JSC_FILES := $(JSC_LIB)/libJavaScriptCore.a $(JSC_LIB)/libWTF.a $(JSC_LIB)/libbmalloc.a $(JSC_LIB)/libLowLevelInterpreterLib.a 149 | JSC_FILES_DEBUG := $(JSC_LIB_DEBUG)/libJavaScriptCore.a $(JSC_LIB_DEBUG)/libWTF.a $(JSC_LIB_DEBUG)/libbmalloc.a $(JSC_LIB_DEBUG)/libLowLevelInterpreterLib.a 150 | 151 | ENABLE_MIMALLOC ?= 1 152 | 153 | # https://github.com/microsoft/mimalloc/issues/512 154 | # Linking mimalloc via object file on macOS x64 can cause heap corruption 155 | _MIMALLOC_FILE = libmimalloc.o 156 | _MIMALLOC_INPUT_PATH = CMakeFiles/mimalloc-obj.dir/src/static.c.o 157 | _MIMALLOC_DEBUG_FILE = libmimalloc-debug.a 158 | _MIMALLOC_OBJECT_FILE = 1 159 | _MIMALLOC_LINK = $(BUN_PKG_LIB)/$(MIMALLOC_FILE) 160 | DEFAULT_LINKER_FLAGS = 161 | 162 | JSC_BUILD_STEPS := 163 | ifeq ($(OS_NAME),linux) 164 | JSC_BUILD_STEPS += jsc-build-linux 165 | _MIMALLOC_LINK = $(BUN_PKG_LIB)/$(MIMALLOC_FILE) 166 | DEFAULT_LINKER_FLAGS= -pthread -ldl 167 | endif 168 | ifeq ($(OS_NAME),darwin) 169 | _MIMALLOC_OBJECT_FILE = 0 170 | JSC_BUILD_STEPS += jsc-build-mac jsc-copy-headers 171 | _MIMALLOC_FILE = libmimalloc.a 172 | _MIMALLOC_INPUT_PATH = libmimalloc.a 173 | _MIMALLOC_LINK = -lmimalloc 174 | endif 175 | 176 | MIMALLOC_FILE= 177 | MIMALLOC_INPUT_PATH= 178 | ifeq ($(ENABLE_MIMALLOC), 1) 179 | MIMALLOC_FILE=$(_MIMALLOC_FILE) 180 | MIMALLOC_INPUT_PATH=$(_MIMALLOC_INPUT_PATH) 181 | endif 182 | 183 | 184 | llvm-install: echo "$(HOME)/linuxbrew/.linuxbrew/opt/llvm@13/bin" >> $(GITHUB_PATH) 185 | 186 | 187 | 188 | MACOSX_DEPLOYMENT_TARGET=$(MIN_MACOS_VERSION) 189 | MACOS_MIN_FLAG= 190 | 191 | POSIX_PKG_MANAGER=sudo apt 192 | 193 | STRIP= 194 | 195 | ifeq ($(OS_NAME),darwin) 196 | STRIP=/usr/bin/strip 197 | endif 198 | 199 | ifeq ($(OS_NAME),linux) 200 | STRIP=$(which llvm-strip || which llvm-strip-13 || echo "Missing strip") 201 | endif 202 | 203 | 204 | HOMEBREW_PREFIX ?= $(BREW_PREFIX_PATH) 205 | 206 | 207 | SRC_DIR := src/bun.js/bindings 208 | OBJ_DIR := src/bun.js/bindings-obj 209 | SRC_PATH := $(realpath $(SRC_DIR)) 210 | SRC_FILES := $(wildcard $(SRC_DIR)/*.cpp) 211 | SRC_WEBCORE_FILES := $(wildcard $(SRC_DIR)/webcore/*.cpp) 212 | SRC_SQLITE_FILES := $(wildcard $(SRC_DIR)/sqlite/*.cpp) 213 | SRC_BUILTINS_FILES := $(wildcard src/bun.js/builtins/*.cpp) 214 | OBJ_FILES := $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRC_FILES)) 215 | WEBCORE_OBJ_FILES := $(patsubst $(SRC_DIR)/webcore/%.cpp,$(OBJ_DIR)/%.o,$(SRC_WEBCORE_FILES)) 216 | SQLITE_OBJ_FILES := $(patsubst $(SRC_DIR)/sqlite/%.cpp,$(OBJ_DIR)/%.o,$(SRC_SQLITE_FILES)) 217 | BUILTINS_OBJ_FILES := $(patsubst src/bun.js/builtins/%.cpp,$(OBJ_DIR)/%.o,$(SRC_BUILTINS_FILES)) 218 | BINDINGS_OBJ := $(OBJ_FILES) $(WEBCORE_OBJ_FILES) $(SQLITE_OBJ_FILES) $(BUILTINS_OBJ_FILES) 219 | MAC_INCLUDE_DIRS := -I$(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders \ 220 | -I$(WEBKIT_RELEASE_DIR)/WTF/Headers \ 221 | -I$(WEBKIT_RELEASE_DIR)/ICU/Headers \ 222 | -I$(WEBKIT_RELEASE_DIR)/ \ 223 | -Isrc/bun.js/bindings/ \ 224 | -Isrc/bun.js/builtins/ \ 225 | -Isrc/bun.js/bindings/webcore \ 226 | -Isrc/bun.js/bindings/sqlite \ 227 | -Isrc/bun.js/builtins/cpp \ 228 | -I$(WEBKIT_DIR)/Source/bmalloc \ 229 | -I$(WEBKIT_DIR)/Source 230 | 231 | LINUX_INCLUDE_DIRS := -I$(JSC_INCLUDE_DIR) \ 232 | -Isrc/bun.js/builtins/ \ 233 | -Isrc/bun.js/bindings/ \ 234 | -Isrc/bun.js/bindings/webcore \ 235 | -Isrc/bun.js/bindings/sqlite \ 236 | -Isrc/bun.js/builtins/cpp \ 237 | -I$(ZLIB_INCLUDE_DIR) 238 | 239 | 240 | UWS_INCLUDE_DIR := -I$(BUN_DEPS_DIR)/uws/uSockets/src -I$(BUN_DEPS_DIR)/uws/src -I$(BUN_DEPS_DIR) 241 | 242 | 243 | INCLUDE_DIRS := $(UWS_INCLUDE_DIR) -I$(BUN_DEPS_DIR)/mimalloc/include -Isrc/napi 244 | 245 | 246 | ifeq ($(OS_NAME),linux) 247 | INCLUDE_DIRS += $(LINUX_INCLUDE_DIRS) 248 | SQLITE_OBJECT = $(realpath $(BUN_PKG_LIB))/sqlite3.o 249 | endif 250 | 251 | ifeq ($(OS_NAME),darwin) 252 | MACOS_MIN_FLAG=-mmacosx-version-min=$(MIN_MACOS_VERSION) 253 | POSIX_PKG_MANAGER=brew 254 | INCLUDE_DIRS += $(MAC_INCLUDE_DIRS) 255 | endif 256 | 257 | 258 | 259 | MACOS_ICU_FILES = $(HOMEBREW_PREFIX)/opt/icu4c/lib/libicudata.a \ 260 | $(HOMEBREW_PREFIX)/opt/icu4c/lib/libicui18n.a \ 261 | $(HOMEBREW_PREFIX)/opt/icu4c/lib/libicuuc.a 262 | 263 | MACOS_ICU_INCLUDE = $(HOMEBREW_PREFIX)/opt/icu4c/include 264 | 265 | ICU_FLAGS ?= 266 | 267 | # TODO: find a way to make this more resilient 268 | # Ideally, we could just look up the linker search paths 269 | LIB_ICU_PATH ?= $(BUN_DEPS_DIR) 270 | 271 | ifeq ($(OS_NAME),linux) 272 | ICU_FLAGS += $(LIB_ICU_PATH)/libicuuc.a $(LIB_ICU_PATH)/libicudata.a $(LIB_ICU_PATH)/libicui18n.a 273 | endif 274 | 275 | ifeq ($(OS_NAME),darwin) 276 | ICU_FLAGS += -l icucore \ 277 | $(MACOS_ICU_FILES) \ 278 | -I$(MACOS_ICU_INCLUDE) 279 | endif 280 | 281 | 282 | BORINGSSL_PACKAGE = --pkg-begin boringssl $(BUN_DEPS_DIR)/boringssl.zig --pkg-end 283 | 284 | CLANG_FLAGS = $(INCLUDE_DIRS) \ 285 | -std=$(CXX_VERSION) \ 286 | -DSTATICALLY_LINKED_WITH_JavaScriptCore=1 \ 287 | -DSTATICALLY_LINKED_WITH_WTF=1 \ 288 | -DSTATICALLY_LINKED_WITH_BMALLOC=1 \ 289 | -DBUILDING_WITH_CMAKE=1 \ 290 | -DBUN_SINGLE_THREADED_PER_VM_ENTRY_SCOPE=1 \ 291 | -DNDEBUG=1 \ 292 | -DNOMINMAX \ 293 | -DIS_BUILD \ 294 | -DENABLE_INSPECTOR_ALTERNATE_DISPATCHERS=1 \ 295 | -DBUILDING_JSCONLY__ \ 296 | -DASSERT_ENABLED=0 \ 297 | -fvisibility=hidden \ 298 | -fvisibility-inlines-hidden 299 | 300 | PLATFORM_LINKER_FLAGS = 301 | 302 | SYMBOLS= 303 | 304 | # This flag is only added to webkit builds on Apple platforms 305 | # It has something to do with ICU 306 | ifeq ($(OS_NAME), darwin) 307 | SYMBOLS=-exported_symbols_list $(realpath src/symbols.txt) 308 | PLATFORM_LINKER_FLAGS += -DDU_DISABLE_RENAMING=1 \ 309 | -lstdc++ \ 310 | -fno-keep-static-consts 311 | endif 312 | 313 | ifeq ($(OS_NAME),linux) 314 | SYMBOLS=-Wl,--dynamic-list $(realpath src/symbols.dyn) 315 | endif 316 | 317 | SHARED_LIB_EXTENSION = .so 318 | 319 | JSC_BINDINGS = $(BINDINGS_OBJ) $(JSC_FILES) 320 | JSC_BINDINGS_DEBUG = $(BINDINGS_OBJ) $(JSC_FILES_DEBUG) 321 | 322 | RELEASE_FLAGS= 323 | DEBUG_FLAGS= 324 | 325 | ifeq ($(OS_NAME), darwin) 326 | RELEASE_FLAGS += -Wl,-dead_strip -Wl,-dead_strip_dylibs 327 | DEBUG_FLAGS += -Wl,-dead_strip -Wl,-dead_strip_dylibs 328 | SHARED_LIB_EXTENSION = .dylib 329 | endif 330 | 331 | ARCHIVE_FILES_WITHOUT_LIBCRYPTO = \ 332 | $(BUN_PKG_LIB)/picohttpparser.o \ 333 | -L$(BUN_PKG_LIB) \ 334 | -llolhtml \ 335 | -lz \ 336 | -larchive \ 337 | -lssl \ 338 | -lbase64 \ 339 | -ltcc \ 340 | $(_MIMALLOC_LINK) 341 | 342 | ARCHIVE_FILES = $(ARCHIVE_FILES_WITHOUT_LIBCRYPTO) -lcrypto 343 | 344 | ifeq ($(OS_NAME), darwin) 345 | ARCHIVE_FILES += $(wildcard $(BUN_DEPS_DIR)/uws/uSockets/*.bc) $(BUN_PKG_LIB)/libuwsockets.o 346 | else 347 | ARCHIVE_FILES += -lusockets $(BUN_PKG_LIB)/libuwsockets.o 348 | endif 349 | 350 | STATIC_MUSL_FLAG ?= 351 | 352 | ifeq ($(OS_NAME), linux) 353 | PLATFORM_LINKER_FLAGS = $(BUN_CFLAGS) \ 354 | -fuse-ld=lld \ 355 | -Wl,-z,now \ 356 | -Wl,--as-needed \ 357 | -Wl,--gc-sections \ 358 | -Wl,-z,stack-size=12800000 \ 359 | -static-libstdc++ \ 360 | -static-libgcc \ 361 | -fno-omit-frame-pointer \ 362 | -Wl,--compress-debug-sections,zlib \ 363 | ${STATIC_MUSL_FLAG} \ 364 | -Wl,-Bsymbolic-functions \ 365 | -fno-semantic-interposition \ 366 | -flto \ 367 | -Wl,--allow-multiple-definition \ 368 | -rdynamic 369 | 370 | ARCHIVE_FILES_WITHOUT_LIBCRYPTO += $(BUN_PKG_LIB)/libbacktrace.a 371 | endif 372 | 373 | 374 | BUN_LLD_FLAGS_WITHOUT_JSC = $(ARCHIVE_FILES) \ 375 | $(LIBICONV_PATH) \ 376 | $(CLANG_FLAGS) \ 377 | $(DEFAULT_LINKER_FLAGS) \ 378 | $(PLATFORM_LINKER_FLAGS) \ 379 | $(SQLITE_OBJECT) ${ICU_FLAGS} 380 | 381 | 382 | 383 | BUN_LLD_FLAGS = $(BUN_LLD_FLAGS_WITHOUT_JSC) $(JSC_FILES) $(BINDINGS_OBJ) 384 | BUN_LLD_FLAGS_FAST = $(BUN_LLD_FLAGS_WITHOUT_JSC) $(JSC_FILES_DEBUG) $(BINDINGS_OBJ) 385 | 386 | BUN_LLD_FLAGS_DEBUG = $(BUN_LLD_FLAGS_WITHOUT_JSC) $(JSC_FILES_DEBUG) $(BINDINGS_OBJ) 387 | 388 | CLANG_VERSION = $(shell $(CC) --version | awk '/version/ {for(i=1; i<=NF; i++){if($$i=="version"){split($$(i+1),v,".");print v[1]}}}') 389 | 390 | extract-webkit-linux-binaries: 391 | wget -c https://github.com/Jarred-Sumner/WebKit/releases/download/jul4/bun-webkit-linux-amd64.tar.gz -O - | tar -xz && \ 392 | make webkit-copy 393 | 394 | webkit-copy: 395 | cp bun-webkit/lib/* $(BUN_PKG_LIB) 396 | 397 | ZIG_FORK_SCRIPT= 398 | 399 | ifeq ($(OS_NAME), darwin) 400 | ZIG_FORK_SCRIPT=./scripts/build-zig-macos 401 | endif 402 | 403 | ifeq ($(OS_NAME), linux) 404 | ZIG_FORK_SCRIPT=404 405 | endif 406 | 407 | zig-fork: $(ZIG_FORK_SCRIPT) 408 | 409 | bun: 410 | 411 | BASE64_FLAGS=-march=x86-64-v3 412 | 413 | base64: 414 | cd $(BUN_DEPS_DIR)/base64 && \ 415 | $(CC) $(EMIT_LLVM_FOR_RELEASE) $(BUN_CFLAGS) $(OPTIMIZATION_LEVEL) $(BASE64_FLAGS) -g -fPIC -c *.c -I$(SRC_DIR)/base64 && \ 416 | $(CXX) $(EMIT_LLVM_FOR_RELEASE) $(CXXFLAGS) $(BUN_CFLAGS) $(BASE64_FLAGS) -c neonbase64.cc -g -fPIC && \ 417 | $(AR) rcvs $(BUN_PKG_LIB)/libbase64.a ./*.o 418 | 419 | # Prevent dependency on libtcc1 so it doesn't do filesystem lookups 420 | TINYCC_CFLAGS= -DTCC_LIBTCC1=\"\0\" 421 | 422 | tinycc: 423 | cd $(TINYCC_DIR) && \ 424 | sudo AR=$(AR) CC=$(CC) CFLAGS='$(CFLAGS) $(TINYCC_CFLAGS) $(MACOS_MIN_FLAG)' ./configure --enable-static --cc=$(CC) --ar=$(AR) --config-predefs=yes && \ 425 | make -j10 && \ 426 | cp $(TINYCC_DIR)/*.a $(BUN_PKG_LIB) 427 | 428 | generate-builtins: 429 | rm -f src/bun.js/bindings/*Builtin*.cpp src/bun.js/bindings/*Builtin*.h src/bun.js/bindings/*Builtin*.cpp 430 | rm -rf src/bun.js/builtins/cpp 431 | mkdir -p src/bun.js/builtins/cpp 432 | $(shell which python || which python2) $(realpath $(WEBKIT_DIR)/Source/JavaScriptCore/Scripts/generate-js-builtins.py) -i $(realpath src)/bun.js/builtins/js -o $(realpath src)/bun.js/builtins/cpp --framework WebCore --force 433 | $(shell which python || which python2) $(realpath $(WEBKIT_DIR)/Source/JavaScriptCore/Scripts/generate-js-builtins.py) -i $(realpath src)/bun.js/builtins/js -o $(realpath src)/bun.js/builtins/cpp --framework WebCore --wrappers-only 434 | rm -rf /tmp/1.h src/bun.js/builtins/cpp/WebCoreJSBuiltinInternals.h.1 435 | echo -e '// clang-format off\nnamespace Zig { class GlobalObject; }' >> /tmp/1.h 436 | cat /tmp/1.h src/bun.js/builtins/cpp/WebCoreJSBuiltinInternals.h > src/bun.js/builtins/cpp/WebCoreJSBuiltinInternals.h.1 437 | mv src/bun.js/builtins/cpp/WebCoreJSBuiltinInternals.h.1 src/bun.js/builtins/cpp/WebCoreJSBuiltinInternals.h 438 | $(SED) -i -e 's/class JSDOMGlobalObject/using JSDOMGlobalObject = Zig::GlobalObject/' src/bun.js/builtins/cpp/WebCoreJSBuiltinInternals.h 439 | # this is the one we actually build 440 | mv src/bun.js/builtins/cpp/*JSBuiltin*.cpp src/bun.js/builtins 441 | 442 | vendor-without-check: api analytics node-fallbacks runtime_js fallback_decoder bun_error mimalloc picohttp zlib boringssl libarchive libbacktrace lolhtml usockets uws base64 tinycc 443 | 444 | prepare-types: 445 | BUN_VERSION=$(PACKAGE_JSON_VERSION) $(BUN_RELEASE_BIN) types/bun/bundle.ts packages/bun-types 446 | echo "Generated types for $(PACKAGE_JSON_VERSION) in packages/bun-types" 447 | 448 | release-types: 449 | cd packages/bun-types && npm publish 450 | 451 | format: 452 | $(PRETTIER) --write test/bun.js/*.js 453 | $(PRETTIER) --write test/bun.js/solid-dom-fixtures/**/*.js 454 | 455 | lolhtml: 456 | cd $(BUN_DEPS_DIR)/lol-html/ && cd $(BUN_DEPS_DIR)/lol-html/c-api && cargo build --release && cp target/release/liblolhtml.a $(BUN_PKG_LIB) 457 | 458 | boringssl-build: 459 | cd $(BUN_DEPS_DIR)/boringssl && mkdir -p build && cd build && CFLAGS="$(CFLAGS)" cmake $(CMAKE_FLAGS) -GNinja .. && ninja 460 | 461 | boringssl-build-debug: 462 | cd $(BUN_DEPS_DIR)/boringssl && mkdir -p build && cd build && CFLAGS="$(CFLAGS)" cmake $(CMAKE_FLAGS_WITHOUT_RELEASE) -GNinja .. && ninja 463 | 464 | boringssl-copy: 465 | cp $(BUN_DEPS_DIR)/boringssl/build/ssl/libssl.a $(BUN_PKG_LIB)/libssl.a 466 | cp $(BUN_DEPS_DIR)/boringssl/build/crypto/libcrypto.a $(BUN_PKG_LIB)/libcrypto.a 467 | 468 | boringssl: boringssl-build boringssl-copy 469 | boringssl-debug: boringssl-build-debug boringssl-copy 470 | 471 | compile-ffi-test: 472 | clang $(OPTIMIZATION_LEVEL) -shared -undefined dynamic_lookup -o /tmp/bun-ffi-test.dylib -fPIC ./test/bun.js/ffi-test.c 473 | 474 | libbacktrace: 475 | cd $(BUN_DEPS_DIR)/libbacktrace && \ 476 | CFLAGS="$(CFLAGS)" CC=$(CC) ./configure --disable-shared --enable-static --with-pic && \ 477 | make -j$(CPUS) && \ 478 | cp ./.libs/libbacktrace.a $(BUN_PKG_LIB)/libbacktrace.a 479 | 480 | 481 | sqlite: 482 | 483 | 484 | libarchive: 485 | cd $(BUN_DEPS_DIR)/libarchive; \ 486 | (make clean || echo ""); \ 487 | (./build/clean.sh || echo ""); \ 488 | ./build/autogen.sh; \ 489 | CFLAGS="$(CFLAGS)" CC=$(CC) ./configure --disable-shared --enable-static --with-pic --disable-bsdtar --disable-bsdcat --disable-rpath --enable-posix-regex-lib --without-xml2 --without-expat --without-openssl --without-iconv --without-zlib; \ 490 | make -j${CPUS}; \ 491 | cp ./.libs/libarchive.a $(BUN_PKG_LIB)/libarchive.a; 492 | 493 | tgz: 494 | $(ZIG) build tgz-obj -Drelease-fast 495 | $(CXX) $(PACKAGE_DIR)/tgz.o -g -o ./misctools/tgz $(DEFAULT_LINKER_FLAGS) -lc $(ARCHIVE_FILES) 496 | rm -rf $(PACKAGE_DIR)/tgz.o 497 | 498 | tgz-debug: 499 | $(ZIG) build tgz-obj 500 | $(CXX) $(DEBUG_PACKAGE_DIR)/tgz.o -g -o ./misctools/tgz $(DEFAULT_LINKER_FLAGS) -lc $(ARCHIVE_FILES) 501 | rm -rf $(DEBUG_PACKAGE_DIR)/tgz.o 502 | 503 | vendor: require init-submodules vendor-without-check 504 | 505 | zlib: 506 | cd $(BUN_DEPS_DIR)/zlib; CFLAGS="$(CFLAGS)" cmake $(CMAKE_FLAGS) .; CFLAGS="$(CFLAGS)" make; 507 | cp $(BUN_DEPS_DIR)/zlib/libz.a $(BUN_PKG_LIB)/libz.a 508 | 509 | docker-login: 510 | docker login ghcr.io --username jarred@jarredsumner.com 511 | 512 | docker-push-base: 513 | BUILDKIT=1 docker build -f Dockerfile.base --build-arg GITHUB_WORKSPACE=/build --platform=linux/$(DOCKER_BUILDARCH) --tag bun-base --target base . 514 | BUILDKIT=1 docker build -f Dockerfile.base --build-arg GITHUB_WORKSPACE=/build --platform=linux/$(DOCKER_BUILDARCH) --tag bun-base-with-zig-and-webkit --target base-with-zig-and-webkit . 515 | BUILDKIT=1 docker build -f Dockerfile.base --build-arg GITHUB_WORKSPACE=/build --platform=linux/$(DOCKER_BUILDARCH) --tag bun-base-with-args --target base-with-args . 516 | 517 | docker tag bun-base ghcr.io/jarred-sumner/bun-base:latest 518 | docker push ghcr.io/jarred-sumner/bun-base:latest 519 | 520 | docker tag bun-base-with-zig-and-webkit ghcr.io/jarred-sumner/bun-base-with-zig-and-webkit:latest 521 | docker push ghcr.io/jarred-sumner/bun-base-with-zig-and-webkit:latest 522 | 523 | docker tag bun-base-with-args ghcr.io/jarred-sumner/bun-base-with-args:latest 524 | docker push ghcr.io/jarred-sumner/bun-base-with-args:latest 525 | 526 | require: 527 | @echo "Checking if the required utilities are available..." 528 | @if [ $(CLANG_VERSION) -lt "13" ]; then echo -e "ERROR: clang version >=13 required, found: $(CLANG_VERSION). Install with:\n\n $(POSIX_PKG_MANAGER) install llvm@13"; exit 1; fi 529 | @cmake --version >/dev/null 2>&1 || (echo -e "ERROR: cmake is required."; exit 1) 530 | @esbuild --version >/dev/null 2>&1 || (echo -e "ERROR: esbuild is required."; exit 1) 531 | @npm --version >/dev/null 2>&1 || (echo -e "ERROR: npm is required."; exit 1) 532 | @go version >/dev/null 2>&1 || (echo -e "ERROR: go is required."; exit 1) 533 | @which aclocal > /dev/null || (echo -e "ERROR: automake is required. Install with:\n\n $(POSIX_PKG_MANAGER) install automake"; exit 1) 534 | @which $(LIBTOOL) > /dev/null || (echo -e "ERROR: libtool is required. Install with:\n\n $(POSIX_PKG_MANAGER) install libtool"; exit 1) 535 | @which ninja > /dev/null || (echo -e "ERROR: Ninja is required. Install with:\n\n $(POSIX_PKG_MANAGER) install ninja"; exit 1) 536 | @echo "You have the dependencies installed! Woo" 537 | 538 | init-submodules: 539 | git submodule update --init --recursive --progress --depth=1 540 | 541 | build-obj: 542 | $(ZIG) build obj -Drelease-fast 543 | 544 | dev-build-obj-wasm: 545 | $(ZIG) build bun-wasm -Dtarget=wasm32-freestanding --prominent-compile-errors 546 | 547 | dev-wasm: dev-build-obj-wasm 548 | emcc -sEXPORTED_FUNCTIONS="['_bun_free', '_cycleStart', '_cycleEnd', '_bun_malloc', '_scan', '_transform', '_init']" \ 549 | -g -s ERROR_ON_UNDEFINED_SYMBOLS=0 -DNDEBUG \ 550 | $(BUN_DEPS_DIR)/libmimalloc.a.wasm \ 551 | packages/debug-bun-freestanding-wasm32/bun-wasm.o $(OPTIMIZATION_LEVEL) --no-entry --allow-undefined -s ASSERTIONS=0 -s ALLOW_MEMORY_GROWTH=1 -s WASM_BIGINT=1 \ 552 | -o packages/debug-bun-freestanding-wasm32/bun-wasm.wasm 553 | cp packages/debug-bun-freestanding-wasm32/bun-wasm.wasm src/api/demo/public/bun-wasm.wasm 554 | 555 | build-obj-wasm: 556 | $(ZIG) build bun-wasm -Drelease-fast -Dtarget=wasm32-freestanding --prominent-compile-errors 557 | emcc -sEXPORTED_FUNCTIONS="['_bun_free', '_cycleStart', '_cycleEnd', '_bun_malloc', '_scan', '_transform', '_init']" \ 558 | -g -s ERROR_ON_UNDEFINED_SYMBOLS=0 -DNDEBUG \ 559 | $(BUN_DEPS_DIR)/libmimalloc.a.wasm \ 560 | packages/bun-freestanding-wasm32/bun-wasm.o $(OPTIMIZATION_LEVEL) --no-entry --allow-undefined -s ASSERTIONS=0 -s ALLOW_MEMORY_GROWTH=1 -s WASM_BIGINT=1 \ 561 | -o packages/bun-freestanding-wasm32/bun-wasm.wasm 562 | cp packages/bun-freestanding-wasm32/bun-wasm.wasm src/api/demo/public/bun-wasm.wasm 563 | 564 | build-obj-wasm-small: 565 | $(ZIG) build bun-wasm -Drelease-small -Dtarget=wasm32-freestanding --prominent-compile-errors 566 | emcc -sEXPORTED_FUNCTIONS="['_bun_free', '_cycleStart', '_cycleEnd', '_bun_malloc', '_scan', '_transform', '_init']" \ 567 | -g -s ERROR_ON_UNDEFINED_SYMBOLS=0 -DNDEBUG \ 568 | $(BUN_DEPS_DIR)/libmimalloc.a.wasm \ 569 | packages/bun-freestanding-wasm32/bun-wasm.o -Oz --no-entry --allow-undefined -s ASSERTIONS=0 -s ALLOW_MEMORY_GROWTH=1 -s WASM_BIGINT=1 \ 570 | -o packages/bun-freestanding-wasm32/bun-wasm.wasm 571 | cp packages/bun-freestanding-wasm32/bun-wasm.wasm src/api/demo/public/bun-wasm.wasm 572 | 573 | wasm: api build-obj-wasm-small 574 | @rm -rf packages/bun-wasm/*.{d.ts,js,wasm,cjs,mjs,tsbuildinfo} 575 | @cp packages/bun-freestanding-wasm32/bun-wasm.wasm packages/bun-wasm/bun.wasm 576 | @cp src/api/schema.d.ts packages/bun-wasm/schema.d.ts 577 | @cp src/api/schema.js packages/bun-wasm/schema.js 578 | @cd packages/bun-wasm && $(NPM_CLIENT) run tsc -- -p . 579 | @esbuild --sourcemap=external --external:fs --define:process.env.NODE_ENV='"production"' --outdir=packages/bun-wasm --target=esnext --bundle packages/bun-wasm/index.ts --format=esm --minify 2> /dev/null 580 | @mv packages/bun-wasm/index.js packages/bun-wasm/index.mjs 581 | @mv packages/bun-wasm/index.js.map packages/bun-wasm/index.mjs.map 582 | @esbuild --sourcemap=external --external:fs --define:process.env.NODE_ENV='"production"' --outdir=packages/bun-wasm --target=esnext --bundle packages/bun-wasm/index.ts --format=cjs --minify --platform=node 2> /dev/null 583 | @mv packages/bun-wasm/index.js packages/bun-wasm/index.cjs 584 | @mv packages/bun-wasm/index.js.map packages/bun-wasm/index.cjs.map 585 | @rm -rf packages/bun-wasm/*.tsbuildinfo 586 | @wasm-opt -O4 --enable-mutable-globals packages/bun-wasm/bun.wasm -o /tmp/bun.wasm 587 | @mv /tmp/bun.wasm packages/bun-wasm/bun.wasm 588 | 589 | build-obj-safe: 590 | $(ZIG) build obj -Drelease-safe 591 | 592 | UWS_CC_FLAGS = -pthread -DLIBUS_USE_OPENSSL=1 -DUWS_HTTPRESPONSE_NO_WRITEMARK=1 -DLIBUS_USE_BORINGSSL=1 -DWITH_BORINGSSL=1 -Wpedantic -Wall -Wextra -Wsign-conversion -Wconversion $(UWS_INCLUDE) -DUWS_WITH_PROXY 593 | UWS_CXX_FLAGS = $(UWS_CC_FLAGS) -std=$(CXX_VERSION) -fno-exceptions 594 | UWS_LDFLAGS = -I$(BUN_DEPS_DIR)/boringssl/include -I$(ZLIB_INCLUDE_DIR) 595 | USOCKETS_DIR = $(BUN_DEPS_DIR)/uws/uSockets/ 596 | USOCKETS_SRC_DIR = $(BUN_DEPS_DIR)/uws/uSockets/src/ 597 | 598 | usockets: 599 | cd $(USOCKETS_DIR) && $(CC) -fno-builtin-malloc -fno-builtin-free -fno-builtin-realloc $(EMIT_LLVM_FOR_RELEASE) $(MACOS_MIN_FLAG) -fPIC $(CFLAGS) $(UWS_CC_FLAGS) -save-temps -I$(BUN_DEPS_DIR)/uws/uSockets/src $(UWS_LDFLAGS) -g $(DEFAULT_LINKER_FLAGS) $(PLATFORM_LINKER_FLAGS) $(OPTIMIZATION_LEVEL) -g -c $(wildcard $(USOCKETS_SRC_DIR)/*.c) $(wildcard $(USOCKETS_SRC_DIR)/**/*.c) 600 | cd $(USOCKETS_DIR) && $(CXX) -fno-builtin-malloc -fno-builtin-free -fno-builtin-realloc $(EMIT_LLVM_FOR_RELEASE) $(MACOS_MIN_FLAG) -fPIC $(CXXFLAGS) $(UWS_CXX_FLAGS) -save-temps -I$(BUN_DEPS_DIR)/uws/uSockets/src $(UWS_LDFLAGS) -g $(DEFAULT_LINKER_FLAGS) $(PLATFORM_LINKER_FLAGS) $(OPTIMIZATION_LEVEL) -g -c $(wildcard $(USOCKETS_SRC_DIR)/*.cpp) $(wildcard $(USOCKETS_SRC_DIR)/**/*.cpp) 601 | cd $(USOCKETS_DIR) && $(AR) rcvs $(BUN_PKG_LIB)/libusockets.a *.bc 602 | 603 | uws: 604 | cd $(USOCKETS_DIR) && $(CXX) $(BITCODE_OR_SECTIONS) $(EMIT_LLVM_FOR_RELEASE) -fPIC -I$(BUN_DEPS_DIR)/uws/uSockets/src $(CLANG_FLAGS) $(CFLAGS) $(UWS_CXX_FLAGS) $(UWS_LDFLAGS) $(PLATFORM_LINKER_FLAGS) -c -I$(BUN_PKG_INCLUDE) $(BUN_PKG_LIB)/libusockets.a $(BUN_PKG_INCLUDE)/libuwsockets.cpp -o $(BUN_PKG_LIB)/libuwsockets.o 605 | 606 | sign-macos-x64: 607 | gon sign.macos-x64.json 608 | 609 | sign-macos-aarch64: 610 | gon sign.macos-aarch64.json 611 | 612 | cls: 613 | @echo "\n\n---\n\n" 614 | 615 | release: all-js jsc-bindings-mac build-obj cls bun-link-lld-release bun-link-lld-release-dsym release-bin-entitlements 616 | release-safe: all-js jsc-bindings-mac build-obj-safe cls bun-link-lld-release bun-link-lld-release-dsym release-bin-entitlements 617 | 618 | jsc-check: 619 | @ls $(JSC_BASE_DIR) >/dev/null 2>&1 || (echo "Failed to access WebKit build. Please compile the WebKit submodule using the Dockerfile at $(shell pwd)/src/javascript/WebKit/Dockerfile and then copy from /output in the Docker container to $(JSC_BASE_DIR). You can override the directory via JSC_BASE_DIR. \n\n DOCKER_BUILDKIT=1 docker build -t bun-webkit $(shell pwd)/src/bun.js/WebKit -f $(shell pwd)/src/bun.js/WebKit/Dockerfile --progress=plain\n\n docker container create bun-webkit\n\n # Get the container ID\n docker container ls\n\n docker cp DOCKER_CONTAINER_ID_YOU_JUST_FOUND:/output $(JSC_BASE_DIR)" && exit 1) 620 | @ls $(JSC_INCLUDE_DIR) >/dev/null 2>&1 || (echo "Failed to access WebKit include directory at $(JSC_INCLUDE_DIR)." && exit 1) 621 | @ls $(JSC_LIB) >/dev/null 2>&1 || (echo "Failed to access WebKit lib directory at $(JSC_LIB)." && exit 1) 622 | 623 | all-js: runtime_js fallback_decoder bun_error node-fallbacks 624 | 625 | fmt-cpp: 626 | cd src/bun.js/bindings && clang-format *.cpp *.h -i 627 | 628 | fmt-zig: 629 | cd src && zig fmt **/*.zig 630 | 631 | fmt: fmt-cpp fmt-zig 632 | 633 | api: 634 | $(NPM_CLIENT) install 635 | ./node_modules/.bin/peechy --schema src/api/schema.peechy --esm src/api/schema.js --ts src/api/schema.d.ts --zig src/api/schema.zig 636 | $(ZIG) fmt src/api/schema.zig 637 | $(PRETTIER) --write src/api/schema.js 638 | $(PRETTIER) --write src/api/schema.d.ts 639 | 640 | node-fallbacks: 641 | @cd src/node-fallbacks; $(NPM_CLIENT) install; $(NPM_CLIENT) run --silent build 642 | 643 | fallback_decoder: 644 | @esbuild --target=esnext --bundle src/fallback.ts --format=iife --platform=browser --minify > src/fallback.out.js 645 | 646 | runtime_js: 647 | @NODE_ENV=production esbuild --define:process.env.NODE_ENV="production" --target=esnext --bundle src/runtime/index.ts --format=iife --platform=browser --global-name=BUN_RUNTIME --minify --external:/bun:* > src/runtime.out.js; cat src/runtime.footer.js >> src/runtime.out.js 648 | @NODE_ENV=production esbuild --define:process.env.NODE_ENV="production" --target=esnext --bundle src/runtime/index-with-refresh.ts --format=iife --platform=browser --global-name=BUN_RUNTIME --minify --external:/bun:* > src/runtime.out.refresh.js; cat src/runtime.footer.with-refresh.js >> src/runtime.out.refresh.js 649 | @NODE_ENV=production esbuild --define:process.env.NODE_ENV="production" --target=esnext --bundle src/runtime/index-without-hmr.ts --format=iife --platform=node --global-name=BUN_RUNTIME --minify --external:/bun:* > src/runtime.node.pre.out.js; cat src/runtime.node.pre.out.js src/runtime.footer.node.js > src/runtime.node.out.js 650 | @NODE_ENV=production esbuild --define:process.env.NODE_ENV="production" --target=esnext --bundle src/runtime/index-without-hmr.ts --format=iife --platform=node --global-name=BUN_RUNTIME --minify --external:/bun:* > src/runtime.bun.pre.out.js; cat src/runtime.bun.pre.out.js src/runtime.footer.bun.js > src/runtime.bun.out.js 651 | 652 | runtime_js_dev: 653 | @NODE_ENV=development esbuild --define:process.env.NODE_ENV="development" --target=esnext --bundle src/runtime/index.ts --format=iife --platform=browser --global-name=BUN_RUNTIME --external:/bun:* > src/runtime.out.js; cat src/runtime.footer.js >> src/runtime.out.js 654 | @NODE_ENV=development esbuild --define:process.env.NODE_ENV="development" --target=esnext --bundle src/runtime/index-with-refresh.ts --format=iife --platform=browser --global-name=BUN_RUNTIME --external:/bun:* > src/runtime.out.refresh.js; cat src/runtime.footer.with-refresh.js >> src/runtime.out.refresh.js 655 | @NODE_ENV=development esbuild --define:process.env.NODE_ENV="development" --target=esnext --bundle src/runtime/index-without-hmr.ts --format=iife --platform=node --global-name=BUN_RUNTIME --external:/bun:* > src/runtime.node.pre.out.js; cat src/runtime.node.pre.out.js src/runtime.footer.node.js > src/runtime.node.out.js 656 | @NODE_ENV=development esbuild --define:process.env.NODE_ENV="development" --target=esnext --bundle src/runtime/index-without-hmr.ts --format=iife --platform=node --global-name=BUN_RUNTIME --external:/bun:* > src/runtime.bun.pre.out.js; cat src/runtime.bun.pre.out.js src/runtime.footer.bun.js > src/runtime.bun.out.js 657 | 658 | bun_error: 659 | @cd packages/bun-error; $(NPM_CLIENT) install; $(NPM_CLIENT) run --silent build 660 | 661 | generate-install-script: 662 | @rm -f $(PACKAGES_REALPATH)/bun/install.js 663 | @esbuild --log-level=error --define:BUN_VERSION="\"$(PACKAGE_JSON_VERSION)\"" --define:process.env.NODE_ENV="\"production\"" --platform=node --format=cjs $(PACKAGES_REALPATH)/bun/install.ts > $(PACKAGES_REALPATH)/bun/install.js 664 | 665 | fetch: 666 | $(ZIG) build -Drelease-fast fetch-obj 667 | $(CXX) $(PACKAGE_DIR)/fetch.o -g $(OPTIMIZATION_LEVEL) -o ./misctools/fetch $(DEFAULT_LINKER_FLAGS) -lc $(ARCHIVE_FILES) 668 | rm -rf $(PACKAGE_DIR)/fetch.o 669 | 670 | sha: 671 | $(ZIG) build -Drelease-fast sha-bench-obj 672 | $(CXX) $(PACKAGE_DIR)/sha.o -g $(OPTIMIZATION_LEVEL) -o ./misctools/sha $(DEFAULT_LINKER_FLAGS) -lc $(ARCHIVE_FILES) 673 | rm -rf $(PACKAGE_DIR)/sha.o 674 | 675 | fetch-debug: 676 | $(ZIG) build fetch-obj 677 | $(CXX) $(DEBUG_PACKAGE_DIR)/fetch.o -g $(OPTIMIZATION_LEVEL) -o ./misctools/fetch $(DEFAULT_LINKER_FLAGS) -lc $(ARCHIVE_FILES) 678 | 679 | 680 | httpbench-debug: 681 | $(ZIG) build httpbench-obj 682 | $(CXX) $(DEBUG_PACKAGE_DIR)/httpbench.o -g -o ./misctools/http_bench $(DEFAULT_LINKER_FLAGS) -lc $(ARCHIVE_FILES) 683 | 684 | 685 | httpbench-release: 686 | $(ZIG) build -Drelease-fast httpbench-obj 687 | $(CXX) $(PACKAGE_DIR)/httpbench.o -g $(OPTIMIZATION_LEVEL) -o ./misctools/http_bench $(DEFAULT_LINKER_FLAGS) -lc $(ARCHIVE_FILES) 688 | rm -rf $(PACKAGE_DIR)/httpbench.o 689 | 690 | 691 | 692 | 693 | check-glibc-version-dependency: 694 | @objdump -T $(RELEASE_BUN) | ((grep -qe "GLIBC_2.3[0-9]") && { echo "Glibc 2.3X detected, this will break the binary"; exit 1; }) || true 695 | 696 | ifeq ($(OS_NAME),darwin) 697 | 698 | 699 | 700 | # Hardened runtime will not work with debugging 701 | bun-codesign-debug: 702 | codesign --entitlements $(realpath entitlements.plist) --force --timestamp --sign "$(CODESIGN_IDENTITY)" -vvvv --deep --strict $(DEBUG_BUN) 703 | 704 | bun-codesign-release-local: 705 | codesign --entitlements $(realpath entitlements.plist) --options runtime --force --timestamp --sign "$(CODESIGN_IDENTITY)" -vvvv --deep --strict $(RELEASE_BUN) 706 | codesign --entitlements $(realpath entitlements.plist) --options runtime --force --timestamp --sign "$(CODESIGN_IDENTITY)" -vvvv --deep --strict $(PACKAGE_DIR)/bun-profile 707 | 708 | bun-codesign-release-local-debug: 709 | codesign --entitlements $(realpath entitlements.debug.plist) --options runtime --force --timestamp --sign "$(CODESIGN_IDENTITY)" -vvvv --deep --strict $(RELEASE_BUN) 710 | codesign --entitlements $(realpath entitlements.debug.plist) --options runtime --force --timestamp --sign "$(CODESIGN_IDENTITY)" -vvvv --deep --strict $(PACKAGE_DIR)/bun-profile 711 | 712 | 713 | endif 714 | 715 | bun-codesign-debug: 716 | bun-codesign-release-local: 717 | bun-codesign-release-local-debug: 718 | 719 | 720 | 721 | jsc: jsc-build jsc-copy-headers jsc-bindings 722 | jsc-build: $(JSC_BUILD_STEPS) 723 | jsc-bindings: jsc-bindings-headers jsc-bindings-mac 724 | 725 | clone-submodules: 726 | git -c submodule."src/bun.js/WebKit".update=none submodule update --init --recursive --depth=1 --progress 727 | 728 | devcontainer: clone-submodules mimalloc zlib libarchive boringssl picohttp identifier-cache node-fallbacks jsc-bindings-headers api analytics bun_error fallback_decoder jsc-bindings-mac dev runtime_js_dev libarchive libbacktrace lolhtml usockets uws base64 tinycc 729 | 730 | CLANG_FORMAT := $(shell command -v clang-format 2> /dev/null) 731 | 732 | 733 | jsc-bindings-headers: 734 | rm -f /tmp/build-jsc-headers deps/bindings/headers.zig 735 | touch deps/bindings/headers.zig 736 | mkdir -p deps/bindings-obj/ 737 | $(ZIG) build headers-obj 738 | $(CXX) $(PLATFORM_LINKER_FLAGS) $(JSC_FILES_DEBUG) ${ICU_FLAGS} $(BUN_LLD_FLAGS_WITHOUT_JSC) -g $(DEBUG_BIN)/headers.o -W -o /tmp/build-jsc-headers -lc; 739 | /tmp/build-jsc-headers 740 | $(ZIG) translate-c deps/bindings/headers.h > deps/bindings/headers.zig 741 | $(BUN_OR_NODE) misctools/headers-cleaner.js 742 | $(ZIG) fmt deps/bindings/headers.zig 743 | 744 | 745 | MIMALLOC_OVERRIDE_FLAG ?= 746 | 747 | 748 | bump: 749 | expr 0.1.0 + 1 > build-id 750 | 751 | 752 | identifier-cache: 753 | $(ZIG) run src/js_lexer/identifier_data.zig 754 | 755 | tag: 756 | git tag $(BUN_BUILD_TAG) 757 | git push --tags 758 | cd ../bun-releases-for-updater && echo $(BUN_BUILD_TAG) > bumper && git add bumper && git commit -m "Update latest release" && git tag $(BUN_BUILD_TAG) && git push 759 | 760 | prepare-release: tag release-create 761 | 762 | release-create-auto-updater: 763 | 764 | release-create: 765 | gh release create --title "bun v$(PACKAGE_JSON_VERSION)" "$(BUN_BUILD_TAG)" 766 | gh release create --repo=$(BUN_AUTO_UPDATER_REPO) --title "bun v$(PACKAGE_JSON_VERSION)" "$(BUN_BUILD_TAG)" -n "See https://github.com/Jarred-Sumner/bun/releases/tag/$(BUN_BUILD_TAG) for release notes. Using the install script or bun upgrade is the recommended way to install bun. Join bun's Discord to get access https://bun.sh/discord" 767 | 768 | release-bin-entitlements: 769 | 770 | release-bin-generate-zip: 771 | release-bin-codesign: 772 | 773 | ifeq ($(OS_NAME),darwin) 774 | # Without this, JIT will fail on aarch64 775 | # strip will remove the entitlements.plist 776 | # which, in turn, will break JIT 777 | release-bin-entitlements: 778 | codesign --entitlements $(realpath entitlements.plist) --options runtime --force --timestamp --sign "$(CODESIGN_IDENTITY)" -vvvv --deep --strict $(PACKAGE_DIR)/bun 779 | codesign --entitlements $(realpath entitlements.plist) --options runtime --force --timestamp --sign "$(CODESIGN_IDENTITY)" -vvvv --deep --strict $(PACKAGE_DIR)/bun-profile 780 | 781 | 782 | # macOS expects a specific directory structure for the zip file 783 | # ditto lets us generate it similarly to right clicking "Compress" in Finder 784 | release-bin-generate-zip: 785 | dot_clean -vnm /tmp/bun-$(PACKAGE_JSON_VERSION)/bun-$(TRIPLET) 786 | cd /tmp/bun-$(PACKAGE_JSON_VERSION)/bun-$(TRIPLET) && \ 787 | codesign --entitlements $(realpath entitlements.plist) --options runtime --force --timestamp --sign "$(CODESIGN_IDENTITY)" -vvvv --deep --strict bun 788 | ditto -ck --rsrc --sequesterRsrc --keepParent /tmp/bun-$(PACKAGE_JSON_VERSION)/bun-$(TRIPLET) $(BUN_DEPLOY_ZIP) 789 | 790 | release-bin-codesign: 791 | xcrun notarytool submit --wait $(BUN_DEPLOY_ZIP) --keychain-profile "bun" 792 | 793 | else 794 | 795 | release-bin-generate-zip: 796 | cd /tmp/bun-$(PACKAGE_JSON_VERSION)/ && zip -r bun-$(TRIPLET).zip bun-$(TRIPLET) 797 | 798 | 799 | endif 800 | 801 | 802 | BUN_DEPLOY_ZIP = /tmp/bun-$(PACKAGE_JSON_VERSION)/bun-$(TRIPLET).zip 803 | BUN_DEPLOY_DSYM = /tmp/bun-$(PACKAGE_JSON_VERSION)/bun-$(TRIPLET).dSYM.tar.gz 804 | 805 | 806 | ifeq ($(OS_NAME),darwin) 807 | 808 | release-bin-generate-copy-dsym: 809 | cd $(shell dirname $(BUN_RELEASE_BIN)) && tar -czvf $(shell basename $(BUN_DEPLOY_DSYM)) $(shell basename $(BUN_RELEASE_BIN)).dSYM && \ 810 | mv $(shell basename $(BUN_DEPLOY_DSYM)) $(BUN_DEPLOY_DSYM) 811 | 812 | endif 813 | 814 | ifeq ($(OS_NAME),linux) 815 | release-bin-generate-copy-dsym: 816 | endif 817 | 818 | release-bin-generate-copy: 819 | rm -rf /tmp/bun-$(PACKAGE_JSON_VERSION)/bun-$(TRIPLET) $(BUN_DEPLOY_ZIP) 820 | mkdir -p /tmp/bun-$(PACKAGE_JSON_VERSION)/bun-$(TRIPLET) 821 | cp $(BUN_RELEASE_BIN) /tmp/bun-$(PACKAGE_JSON_VERSION)/bun-$(TRIPLET)/bun 822 | 823 | release-bin-generate: release-bin-generate-copy release-bin-generate-zip release-bin-generate-copy-dsym 824 | 825 | 826 | release-bin-check-version: 827 | test $(shell eval $(BUN_RELEASE_BIN) --version) = $(PACKAGE_JSON_VERSION) 828 | 829 | release-bin-check: release-bin-check-version 830 | 831 | ifeq ($(OS_NAME),linux) 832 | 833 | release-bin-check: release-bin-check-version 834 | # force it to run 835 | @make -B check-glibc-version-dependency 836 | endif 837 | 838 | 839 | release-bin-push-bin: 840 | gh release upload $(BUN_BUILD_TAG) --clobber $(BUN_DEPLOY_ZIP) 841 | gh release upload $(BUN_BUILD_TAG) --clobber $(BUN_DEPLOY_ZIP) --repo $(BUN_AUTO_UPDATER_REPO) 842 | 843 | 844 | ifeq ($(OS_NAME),darwin) 845 | release-bin-push-dsym: 846 | gh release upload $(BUN_BUILD_TAG) --clobber $(BUN_DEPLOY_DSYM) 847 | gh release upload $(BUN_BUILD_TAG) --clobber $(BUN_DEPLOY_DSYM) --repo $(BUN_AUTO_UPDATER_REPO) 848 | endif 849 | 850 | ifeq ($(OS_NAME),linux) 851 | release-bin-push-dsym: 852 | endif 853 | 854 | TINYCC_DIR ?= $(realpath $(BUN_DEPS_DIR)/tinycc) 855 | 856 | release-bin-push: release-bin-push-bin release-bin-push-dsym 857 | generate-release-bin-as-zip: release-bin-generate release-bin-codesign 858 | release-bin-without-push: test-all release-bin-check generate-release-bin-as-zip 859 | 860 | release-bin: release-bin-without-push release-bin-push 861 | 862 | 863 | 864 | release-bin-dir: 865 | echo $(PACKAGE_DIR) 866 | 867 | dev-obj: 868 | $(ZIG) build obj --prominent-compile-errors 869 | 870 | dev-obj-linux: 871 | $(ZIG) build obj -Dtarget=x86_64-linux-gnu 872 | 873 | dev: mkdir-dev dev-obj bun-link-lld-debug bun-codesign-debug 874 | 875 | mkdir-dev: 876 | mkdir -p $(DEBUG_PACKAGE_DIR)/bin 877 | 878 | test-install: 879 | cd test/scripts && $(NPM_CLIENT) install 880 | 881 | test-bun-dev: 882 | BUN_BIN=$(RELEASE_BUN) bash test/apps/bun-dev.sh 883 | BUN_BIN=$(RELEASE_BUN) bash test/apps/bun-dev-index-html.sh 884 | 885 | test-dev-bun-dev: 886 | BUN_BIN=$(DEBUG_BUN) bash test/apps/bun-dev.sh 887 | BUN_BIN=$(DEBUG_BUN) bash test/apps/bun-dev-index-html.sh 888 | 889 | test-all: test-install test-with-hmr test-no-hmr test-create-next test-create-react test-bun-run test-bun-install test-bun-dev 890 | 891 | copy-test-node-modules: 892 | rm -rf test/snippets/package-json-exports/node_modules || echo ""; 893 | cp -r test/snippets/package-json-exports/_node_modules_copy test/snippets/package-json-exports/node_modules || echo ""; 894 | kill-bun: 895 | -killall -9 bun bun-debug 896 | 897 | test-dev-create-next: 898 | BUN_BIN=$(DEBUG_BUN) bash test/apps/bun-create-next.sh 899 | 900 | test-dev-create-react: 901 | BUN_BIN=$(DEBUG_BUN) bash test/apps/bun-create-react.sh 902 | 903 | test-create-next: 904 | BUN_BIN=$(RELEASE_BUN) bash test/apps/bun-create-next.sh 905 | 906 | test-bun-run: 907 | cd test/apps && BUN_BIN=$(RELEASE_BUN) bash ./bun-run-check.sh 908 | 909 | test-bun-install: test-bun-install-git-status 910 | cd test/apps && JS_RUNTIME=$(RELEASE_BUN) NPM_CLIENT=$(RELEASE_BUN) bash ./bun-install.sh 911 | cd test/apps && BUN_BIN=$(RELEASE_BUN) bash ./bun-install-utf8.sh 912 | 913 | test-bun-install-git-status: 914 | cd test/apps && JS_RUNTIME=$(RELEASE_BUN) BUN_BIN=$(RELEASE_BUN) bash ./bun-install-lockfile-status.sh 915 | 916 | test-dev-bun-install: test-dev-bun-install-git-status 917 | cd test/apps && JS_RUNTIME=$(DEBUG_BUN) NPM_CLIENT=$(DEBUG_BUN) bash ./bun-install.sh 918 | cd test/apps && BUN_BIN=$(DEBUG_BUN) bash ./bun-install-utf8.sh 919 | 920 | test-dev-bun-install-git-status: 921 | cd test/apps && BUN_BIN=$(DEBUG_BUN) bash ./bun-install-lockfile-status.sh 922 | 923 | test-create-react: 924 | BUN_BIN=$(RELEASE_BUN) bash test/apps/bun-create-react.sh 925 | 926 | test-with-hmr: kill-bun copy-test-node-modules 927 | BUN_BIN=$(RELEASE_BUN) node test/scripts/browser.js 928 | 929 | test-no-hmr: kill-bun copy-test-node-modules 930 | -killall bun -9; 931 | DISABLE_HMR="DISABLE_HMR" BUN_BIN=$(RELEASE_BUN) node test/scripts/browser.js 932 | 933 | test-dev-with-hmr: copy-test-node-modules 934 | -killall bun-debug -9; 935 | BUN_BIN=$(DEBUG_BUN) node test/scripts/browser.js 936 | 937 | test-dev-no-hmr: copy-test-node-modules 938 | -killall bun-debug -9; 939 | DISABLE_HMR="DISABLE_HMR" BUN_BIN=$(DEBUG_BUN) node test/scripts/browser.js 940 | 941 | test-dev-bun-run: 942 | cd test/apps && BUN_BIN=$(DEBUG_BUN) bash bun-run-check.sh 943 | 944 | test-dev-all: test-dev-with-hmr test-dev-no-hmr test-dev-create-next test-dev-create-react test-dev-bun-run test-dev-bun-install test-dev-bun-dev 945 | test-dev-bunjs: 946 | 947 | test-dev: test-dev-with-hmr 948 | 949 | jsc-copy-headers: 950 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/heap/WeakHandleOwner.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/WeakHandleOwner.h 951 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/LazyClassStructureInlines.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/LazyClassStructureInlines.h 952 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/LazyPropertyInlines.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/LazyPropertyInlines.h 953 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/JSTypedArrayViewPrototype.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JSTypedArrayViewPrototype.h 954 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/JSTypedArrayPrototypes.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JSTypedArrayPrototypes.h 955 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/jit/JIT.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JIT.h 956 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/bytecode/StructureStubInfo.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/StructureStubInfo.h 957 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/bytecode/PolymorphicAccess.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/PolymorphicAccess.h 958 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/bytecode/AccessCase.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/AccessCase.h 959 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/ObjectPropertyConditionSet.h 960 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/bytecode/PolyProtoAccessChain.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/PolyProtoAccessChain.h 961 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/bytecode/PutKind.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/PutKind.h 962 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/StructureStubClearingWatchpoint.h 963 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/bytecode/AdaptiveInferredPropertyValueWatchpointBase.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/AdaptiveInferredPropertyValueWatchpointBase.h 964 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/bytecode/StubInfoSummary.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/StubInfoSummary.h 965 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/CommonSlowPaths.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/CommonSlowPaths.h 966 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/DirectArguments.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/DirectArguments.h 967 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/GenericArguments.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/GenericArguments.h 968 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/ScopedArguments.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/ScopedArguments.h 969 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/JSLexicalEnvironment.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JSLexicalEnvironment.h 970 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/jit/JITDisassembler.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JITDisassembler.h 971 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/jit/JITInlineCacheGenerator.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JITInlineCacheGenerator.h 972 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/jit/JITMathIC.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JITMathIC.h 973 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/jit/JITAddGenerator.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JITAddGenerator.h 974 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/jit/JITMathICInlineResult.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JITMathICInlineResult.h 975 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/jit/SnippetOperand.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/SnippetOperand.h 976 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/jit/JITMulGenerator.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JITMulGenerator.h 977 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/jit/JITNegGenerator.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JITNegGenerator.h 978 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/jit/JITSubGenerator.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JITSubGenerator.h 979 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/bytecode/Repatch.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/Repatch.h 980 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/jit/JITRightShiftGenerator.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JITRightShiftGenerator.h 981 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/jit/JITBitBinaryOpGenerator.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JITBitBinaryOpGenerator.h 982 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/jit/JSInterfaceJIT.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JSInterfaceJIT.h 983 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/llint/LLIntData.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/LLIntData.h 984 | cp $(WEBKIT_DIR)/Source/JavaScriptCore/bytecode/FunctionCodeBlock.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/FunctionCodeBlock.h 985 | find $(WEBKIT_RELEASE_DIR)/JavaScriptCore/Headers/JavaScriptCore/ -name "*.h" -exec cp {} $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/ \; 986 | 987 | # This is a workaround for a JSC bug that impacts aarch64 988 | # on macOS, it never requests JIT permissions 989 | jsc-force-fastjit: 990 | $(SED) -i "s/USE(PTHREAD_JIT_PERMISSIONS_API)/CPU(ARM64)/g" $(WEBKIT_DIR)/Source/JavaScriptCore/jit/ExecutableAllocator.h 991 | $(SED) -i "s/USE(PTHREAD_JIT_PERMISSIONS_API)/CPU(ARM64)/g" $(WEBKIT_DIR)/Source/JavaScriptCore/assembler/FastJITPermissions.h 992 | $(SED) -i "s/USE(PTHREAD_JIT_PERMISSIONS_API)/CPU(ARM64)/g" $(WEBKIT_DIR)/Source/JavaScriptCore/jit/ExecutableAllocator.cpp 993 | 994 | jsc-build-mac-compile: 995 | mkdir -p $(WEBKIT_RELEASE_DIR) $(WEBKIT_DIR); 996 | cd $(WEBKIT_RELEASE_DIR) && \ 997 | ICU_INCLUDE_DIRS="$(HOMEBREW_PREFIX)opt/icu4c/include" \ 998 | cmake \ 999 | -DPORT="JSCOnly" \ 1000 | -DENABLE_STATIC_JSC=ON \ 1001 | -DENABLE_SINGLE_THREADED_VM_ENTRY_SCOPE=ON \ 1002 | -DCMAKE_BUILD_TYPE=relwithdebuginfo \ 1003 | -DUSE_THIN_ARCHIVES=OFF \ 1004 | -DENABLE_FTL_JIT=ON \ 1005 | -G Ninja \ 1006 | $(CMAKE_FLAGS_WITHOUT_RELEASE) \ 1007 | -DPTHREAD_JIT_PERMISSIONS_API=1 \ 1008 | -DUSE_PTHREAD_JIT_PERMISSIONS_API=ON \ 1009 | -DENABLE_REMOTE_INSPECTOR=ON \ 1010 | $(WEBKIT_DIR) \ 1011 | $(WEBKIT_RELEASE_DIR) && \ 1012 | CFLAGS="$(CFLAGS) $(BITCODE_OR_SECTIONS) -ffat-lto-objects" CXXFLAGS="$(CXXFLAGS) $(BITCODE_OR_SECTIONS) -ffat-lto-objects" \ 1013 | cmake --build $(WEBKIT_RELEASE_DIR) --config Release --target jsc 1014 | 1015 | jsc-build-mac-compile-lto: 1016 | mkdir -p $(WEBKIT_RELEASE_DIR_LTO) $(WEBKIT_DIR); 1017 | cd $(WEBKIT_RELEASE_DIR_LTO) && \ 1018 | ICU_INCLUDE_DIRS="$(HOMEBREW_PREFIX)opt/icu4c/include" \ 1019 | cmake \ 1020 | -DPORT="JSCOnly" \ 1021 | -DENABLE_STATIC_JSC=ON \ 1022 | -DENABLE_SINGLE_THREADED_VM_ENTRY_SCOPE=ON \ 1023 | -DCMAKE_BUILD_TYPE=Release \ 1024 | -DUSE_THIN_ARCHIVES=OFF \ 1025 | -DCMAKE_C_FLAGS="-flto=full" \ 1026 | -DCMAKE_CXX_FLAGS="-flto=full" \ 1027 | -DENABLE_FTL_JIT=ON \ 1028 | -G Ninja \ 1029 | $(CMAKE_FLAGS_WITHOUT_RELEASE) \ 1030 | -DPTHREAD_JIT_PERMISSIONS_API=1 \ 1031 | -DUSE_PTHREAD_JIT_PERMISSIONS_API=ON \ 1032 | -DENABLE_REMOTE_INSPECTOR=ON \ 1033 | $(WEBKIT_DIR) \ 1034 | $(WEBKIT_RELEASE_DIR_LTO) && \ 1035 | CFLAGS="$(CFLAGS) -ffat-lto-objects" CXXFLAGS="$(CXXFLAGS) -ffat-lto-objects" \ 1036 | cmake --build $(WEBKIT_RELEASE_DIR_LTO) --config Release --target jsc 1037 | 1038 | jsc-build-mac-compile-debug: 1039 | mkdir -p $(WEBKIT_DEBUG_DIR) $(WEBKIT_DIR); 1040 | cd $(WEBKIT_DEBUG_DIR) && \ 1041 | ICU_INCLUDE_DIRS="$(HOMEBREW_PREFIX)opt/icu4c/include" \ 1042 | cmake \ 1043 | -DPORT="JSCOnly" \ 1044 | -DENABLE_STATIC_JSC=ON \ 1045 | -DCMAKE_BUILD_TYPE=Debug \ 1046 | -DUSE_THIN_ARCHIVES=OFF \ 1047 | -DENABLE_FTL_JIT=ON \ 1048 | -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ 1049 | -G Ninja \ 1050 | $(CMAKE_FLAGS_WITHOUT_RELEASE) \ 1051 | -DPTHREAD_JIT_PERMISSIONS_API=1 \ 1052 | -DUSE_PTHREAD_JIT_PERMISSIONS_API=ON \ 1053 | -DENABLE_REMOTE_INSPECTOR=ON \ 1054 | -DUSE_VISIBILITY_ATTRIBUTE=1 \ 1055 | $(WEBKIT_DIR) \ 1056 | $(WEBKIT_DEBUG_DIR) && \ 1057 | CFLAGS="$(CFLAGS) -ffat-lto-objects" CXXFLAGS="$(CXXFLAGS) -ffat-lto-objects" \ 1058 | cmake --build $(WEBKIT_DEBUG_DIR) --config Debug --target jsc 1059 | 1060 | jsc-build-linux-compile-config: 1061 | mkdir -p $(WEBKIT_RELEASE_DIR) 1062 | cd $(WEBKIT_RELEASE_DIR) && \ 1063 | cmake \ 1064 | -DPORT="JSCOnly" \ 1065 | -DENABLE_STATIC_JSC=ON \ 1066 | -DCMAKE_BUILD_TYPE=relwithdebuginfo \ 1067 | -DUSE_THIN_ARCHIVES=OFF \ 1068 | -DENABLE_FTL_JIT=ON \ 1069 | -DENABLE_REMOTE_INSPECTOR=ON \ 1070 | -DJSEXPORT_PRIVATE=WTF_EXPORT_DECLARATION \ 1071 | -USE_VISIBILITY_ATTRIBUTE=1 \ 1072 | -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ 1073 | -G Ninja \ 1074 | -DCMAKE_CXX_COMPILER=$(CXX) \ 1075 | -DCMAKE_C_COMPILER=$(CC) \ 1076 | $(WEBKIT_DIR) \ 1077 | $(WEBKIT_RELEASE_DIR) 1078 | 1079 | # If you get "Error: could not load cache" 1080 | # run rm -rf src/bun.js/WebKit/CMakeCache.txt 1081 | jsc-build-linux-compile-build: 1082 | mkdir -p $(WEBKIT_RELEASE_DIR) && \ 1083 | cd $(WEBKIT_RELEASE_DIR) && \ 1084 | CFLAGS="$(CFLAGS) -Wl,--whole-archive -ffat-lto-objects" CXXFLAGS="$(CXXFLAGS) -Wl,--whole-archive -ffat-lto-objects" \ 1085 | cmake --build $(WEBKIT_RELEASE_DIR) --config relwithdebuginfo --target jsc 1086 | 1087 | 1088 | jsc-build-mac: jsc-force-fastjit jsc-build-mac-compile jsc-build-mac-copy 1089 | 1090 | jsc-build-linux: jsc-build-linux-compile-config jsc-build-linux-compile-build jsc-build-mac-copy 1091 | 1092 | jsc-build-mac-copy: 1093 | cp $(WEBKIT_RELEASE_DIR)/lib/libJavaScriptCore.a $(BUN_PKG_LIB)/libJavaScriptCore.a 1094 | cp $(WEBKIT_RELEASE_DIR)/lib/libLowLevelInterpreterLib.a $(BUN_PKG_LIB)/libLowLevelInterpreterLib.a 1095 | cp $(WEBKIT_RELEASE_DIR)/lib/libWTF.a $(BUN_PKG_LIB)/libWTF.a 1096 | cp $(WEBKIT_RELEASE_DIR)/lib/libbmalloc.a $(BUN_PKG_LIB)/libbmalloc.a 1097 | 1098 | clean-jsc: 1099 | cd src/bun.js/WebKit && rm -rf **/CMakeCache.txt **/CMakeFiles && rm -rf src/bun.js/WebKit/WebKitBuild 1100 | clean-bindings: 1101 | rm -rf $(OBJ_DIR)/*.o 1102 | rm -rf $(OBJ_DIR)/webcore/*.o 1103 | rm -rf $(BINDINGS_OBJ) 1104 | 1105 | clean: clean-bindings 1106 | rm $(BUN_DEPS_DIR)/*.a $(BUN_DEPS_DIR)/*.o 1107 | (cd $(BUN_DEPS_DIR)/mimalloc && make clean) || echo ""; 1108 | (cd $(BUN_DEPS_DIR)/libarchive && make clean) || echo ""; 1109 | (cd $(BUN_DEPS_DIR)/boringssl && make clean) || echo ""; 1110 | (cd $(BUN_DEPS_DIR)/picohttp && make clean) || echo ""; 1111 | (cd $(BUN_DEPS_DIR)/zlib && make clean) || echo ""; 1112 | 1113 | jsc-bindings-mac: $(OBJ_FILES) $(WEBCORE_OBJ_FILES) $(SQLITE_OBJ_FILES) $(BUILTINS_OBJ_FILES) 1114 | 1115 | mimalloc-debug: 1116 | rm -rf $(BUN_DEPS_DIR)/mimalloc/CMakeCache* $(BUN_DEPS_DIR)/mimalloc/CMakeFiles 1117 | cd $(BUN_DEPS_DIR)/mimalloc; make clean || echo ""; \ 1118 | CFLAGS="$(CFLAGS)" cmake $(CMAKE_FLAGS_WITHOUT_RELEASE) ${MIMALLOC_OVERRIDE_FLAG} \ 1119 | -DCMAKE_BUILD_TYPE=Debug \ 1120 | -DMI_DEBUG_FULL=1 \ 1121 | -DMI_SKIP_COLLECT_ON_EXIT=1 \ 1122 | -DMI_BUILD_SHARED=OFF \ 1123 | -DMI_BUILD_STATIC=ON \ 1124 | -DMI_BUILD_TESTS=OFF \ 1125 | -DMI_OSX_ZONE=OFF \ 1126 | -DMI_OSX_INTERPOSE=OFF \ 1127 | -DMI_BUILD_OBJECT=ON \ 1128 | -DMI_USE_CXX=ON \ 1129 | -DMI_OVERRIDE=OFF \ 1130 | -DCMAKE_C_FLAGS="$(CFLAGS)" \ 1131 | -DCMAKE_CXX_FLAGS="$(CFLAGS)" \ 1132 | . \ 1133 | && make -j $(CPUS); 1134 | cp $(BUN_DEPS_DIR)/mimalloc/$(_MIMALLOC_DEBUG_FILE) $(BUN_PKG_LIB)/$(MIMALLOC_FILE) 1135 | 1136 | 1137 | # mimalloc is built as object files so that it can overload the system malloc on linux 1138 | # on macOS, OSX_INTERPOSE and OSX_ZONE do not work correctly. 1139 | # More precisely, they cause assertion failures and occasional segfaults 1140 | mimalloc: 1141 | rm -rf $(BUN_DEPS_DIR)/mimalloc/CMakeCache* $(BUN_DEPS_DIR)/mimalloc/CMakeFiles 1142 | cd $(BUN_DEPS_DIR)/mimalloc; \ 1143 | CFLAGS="$(CFLAGS)" cmake $(CMAKE_FLAGS) \ 1144 | -DMI_SKIP_COLLECT_ON_EXIT=1 \ 1145 | -DMI_BUILD_SHARED=OFF \ 1146 | -DMI_BUILD_STATIC=ON \ 1147 | -DMI_BUILD_TESTS=OFF \ 1148 | -DMI_OSX_ZONE=OFF \ 1149 | -DMI_OSX_INTERPOSE=OFF \ 1150 | -DMI_BUILD_OBJECT=ON \ 1151 | -DMI_USE_CXX=ON \ 1152 | -DMI_OVERRIDE=OFF \ 1153 | -DMI_OSX_ZONE=OFF \ 1154 | -DCMAKE_C_FLAGS="$(CFLAGS)" \ 1155 | .\ 1156 | && make -j $(CPUS); 1157 | cp $(BUN_DEPS_DIR)/mimalloc/$(MIMALLOC_INPUT_PATH) $(BUN_PKG_LIB)/$(MIMALLOC_FILE) 1158 | 1159 | 1160 | mimalloc-wasm: 1161 | cd $(BUN_DEPS_DIR)/mimalloc; emcmake cmake -DMI_BUILD_SHARED=OFF -DMI_BUILD_STATIC=ON -DMI_BUILD_TESTS=OFF -DMI_BUILD_OBJECT=ON ${MIMALLOC_OVERRIDE_FLAG} -DMI_USE_CXX=ON .; emmake make; 1162 | cp $(BUN_DEPS_DIR)/mimalloc/$(MIMALLOC_INPUT_PATH) $(BUN_PKG_LIB)/$(MIMALLOC_FILE).wasm 1163 | 1164 | bun-link-lld-debug: 1165 | $(CXX) $(BUN_LLD_FLAGS_DEBUG) $(DEBUG_FLAGS) $(SYMBOLS) \ 1166 | -g \ 1167 | $(DEBUG_BIN)/bun-debug.o \ 1168 | -W \ 1169 | -o $(DEBUG_BIN)/bun-debug 1170 | 1171 | bun-link-lld-debug-no-jsc: 1172 | $(CXX) $(BUN_LLD_FLAGS_WITHOUT_JSC) $(SYMBOLS) \ 1173 | -g \ 1174 | $(DEBUG_BIN)/bun-debug.o \ 1175 | -W \ 1176 | -o $(DEBUG_BIN)/bun-debug 1177 | 1178 | 1179 | bun-link-lld-release-no-jsc: 1180 | $(CXX) $(BUN_LLD_FLAGS_WITHOUT_JSC) $(SYMBOLS) \ 1181 | -g \ 1182 | $(BUN_RELEASE_BIN).o \ 1183 | -W \ 1184 | -o $(BUN_RELEASE_BIN) -Wl,-undefined,dynamic_lookup -Wl,-why_load 1185 | 1186 | bun-relink-copy: 1187 | cp /tmp/bun-$(PACKAGE_JSON_VERSION).o $(BUN_RELEASE_BIN).o 1188 | 1189 | 1190 | 1191 | bun-link-lld-release: 1192 | $(CXX) $(BUN_LLD_FLAGS) $(SYMBOLS) \ 1193 | $(BUN_RELEASE_BIN).o \ 1194 | -o $(BUN_RELEASE_BIN) \ 1195 | -W \ 1196 | $(OPTIMIZATION_LEVEL) $(RELEASE_FLAGS) 1197 | rm -rf $(BUN_RELEASE_BIN).dSYM 1198 | cp $(BUN_RELEASE_BIN) $(BUN_RELEASE_BIN)-profile 1199 | 1200 | bun-link-lld-release-no-lto: 1201 | $(CXX) $(BUN_LLD_FLAGS_FAST) $(SYMBOLS) \ 1202 | $(BUN_RELEASE_BIN).o \ 1203 | -o $(BUN_RELEASE_BIN) \ 1204 | -W \ 1205 | $(OPTIMIZATION_LEVEL) $(RELEASE_FLAGS) 1206 | rm -rf $(BUN_RELEASE_BIN).dSYM 1207 | cp $(BUN_RELEASE_BIN) $(BUN_RELEASE_BIN)-profile 1208 | 1209 | 1210 | ifeq ($(OS_NAME),darwin) 1211 | bun-link-lld-release-dsym: 1212 | $(DSYMUTIL) -o $(BUN_RELEASE_BIN).dSYM $(BUN_RELEASE_BIN) 1213 | -$(STRIP) $(BUN_RELEASE_BIN) 1214 | cp $(BUN_RELEASE_BIN).o /tmp/bun-$(PACKAGE_JSON_VERSION).o 1215 | 1216 | copy-to-bun-release-dir-dsym: 1217 | gzip --keep -c $(PACKAGE_DIR)/bun.dSYM > $(BUN_RELEASE_DIR)/bun.dSYM.gz 1218 | endif 1219 | 1220 | ifeq ($(OS_NAME),linux) 1221 | bun-link-lld-release-dsym: 1222 | mv $(BUN_RELEASE_BIN).o /tmp/bun-$(PACKAGE_JSON_VERSION).o 1223 | copy-to-bun-release-dir-dsym: 1224 | 1225 | endif 1226 | 1227 | 1228 | bun-relink: bun-relink-copy bun-link-lld-release bun-link-lld-release-dsym 1229 | bun-relink-fast: bun-relink-copy bun-link-lld-release-no-lto 1230 | 1231 | wasm-return1: 1232 | zig build-lib -OReleaseSmall test/bun.js/wasm-return-1-test.zig -femit-bin=test/bun.js/wasm-return-1-test.wasm -target wasm32-freestanding 1233 | 1234 | generate-sink: 1235 | bun src/bun.js/generate-jssink.js 1236 | $(WEBKIT_DIR)/Source/JavaScriptCore/create_hash_table src/bun.js/bindings/JSSink.cpp > src/bun.js/bindings/JSSinkLookupTable.h 1237 | $(SED) -i -e 's/#include "Lookup.h"//' src/bun.js/bindings/JSSinkLookupTable.h 1238 | $(SED) -i -e 's/namespace JSC {//' src/bun.js/bindings/JSSinkLookupTable.h 1239 | $(SED) -i -e 's/} \/\/ namespace JSC//' src/bun.js/bindings/JSSinkLookupTable.h 1240 | 1241 | EMIT_LLVM_FOR_RELEASE=-emit-llvm -flto="full" 1242 | EMIT_LLVM_FOR_DEBUG= 1243 | EMIT_LLVM=$(EMIT_LLVM_FOR_RELEASE) 1244 | 1245 | # We do this outside of build.zig for performance reasons 1246 | # The C compilation stuff with build.zig is really slow and we don't need to run this as often as the rest 1247 | $(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp 1248 | $(CXX) $(CLANG_FLAGS) $(UWS_INCLUDE) \ 1249 | $(MACOS_MIN_FLAG) \ 1250 | $(OPTIMIZATION_LEVEL) \ 1251 | -fno-exceptions \ 1252 | -fno-rtti \ 1253 | -ferror-limit=1000 \ 1254 | $(EMIT_LLVM) \ 1255 | -g3 -c -o $@ $< 1256 | 1257 | $(OBJ_DIR)/%.o: $(SRC_DIR)/webcore/%.cpp 1258 | $(CXX) $(CLANG_FLAGS) \ 1259 | $(MACOS_MIN_FLAG) \ 1260 | $(OPTIMIZATION_LEVEL) \ 1261 | -fno-exceptions \ 1262 | -fno-rtti \ 1263 | -ferror-limit=1000 \ 1264 | $(EMIT_LLVM) \ 1265 | -g3 -c -o $@ $< 1266 | 1267 | $(OBJ_DIR)/%.o: $(SRC_DIR)/sqlite/%.cpp 1268 | $(CXX) $(CLANG_FLAGS) \ 1269 | $(MACOS_MIN_FLAG) \ 1270 | $(OPTIMIZATION_LEVEL) \ 1271 | -fno-exceptions \ 1272 | -fno-rtti \ 1273 | -ferror-limit=1000 \ 1274 | $(EMIT_LLVM) \ 1275 | -g3 -c -o $@ $< 1276 | 1277 | $(OBJ_DIR)/%.o: src/bun.js/builtins/%.cpp 1278 | $(CXX) $(CLANG_FLAGS) \ 1279 | $(MACOS_MIN_FLAG) \ 1280 | $(OPTIMIZATION_LEVEL) \ 1281 | -fno-exceptions \ 1282 | -fno-rtti \ 1283 | -ferror-limit=1000 \ 1284 | $(EMIT_LLVM) \ 1285 | -g3 -c -o $@ $< 1286 | 1287 | sizegen: 1288 | $(CXX) src/bun.js/headergen/sizegen.cpp -o $(BUN_TMP_DIR)/sizegen $(CLANG_FLAGS) -O1 1289 | $(BUN_TMP_DIR)/sizegen > src/bun.js/bindings/sizes.zig 1290 | 1291 | 1292 | # Linux uses bundled SQLite3 1293 | ifeq ($(OS_NAME),linux) 1294 | sqlite: 1295 | $(CC) $(CFLAGS) $(INCLUDE_DIRS) -DSQLITE_ENABLE_COLUMN_METADATA= -DSQLITE_MAX_VARIABLE_NUMBER=250000 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS3_PARENTHESIS=1 -DSQLITE_ENABLE_JSON1=1 $(SRC_DIR)/sqlite/sqlite3.c -c -o $(SQLITE_OBJECT) 1296 | endif 1297 | 1298 | picohttp: 1299 | $(CC) $(CFLAGS) $(OPTIMIZATION_LEVEL) -g -fPIC -c $(BUN_DEPS_DIR)/picohttpparser/picohttpparser.c -I$(BUN_DEPS_DIR) -o $(BUN_PKG_LIB)/picohttpparser.o; cd ../../ 1300 | 1301 | analytics: 1302 | ./node_modules/.bin/peechy --schema src/analytics/schema.peechy --zig src/analytics/analytics_schema.zig 1303 | $(ZIG) fmt src/analytics/analytics_schema.zig 1304 | 1305 | analytics-features: 1306 | @cd misctools; $(ZIG) run --main-pkg-path ../ ./features.zig 1307 | 1308 | find-unused-zig-files: 1309 | @bash ./misctools/find-unused-zig.sh 1310 | 1311 | generate-unit-tests: 1312 | @bash ./misctools/generate-test-file.sh 1313 | 1314 | fmt-all: 1315 | find src -name "*.zig" -exec $(ZIG) fmt {} \; 1316 | 1317 | unit-tests: generate-unit-tests run-unit-tests 1318 | 1319 | ifeq (test, $(firstword $(MAKECMDGOALS))) 1320 | testpath := $(firstword $(wordlist 2, $(words $(MAKECMDGOALS)), $(MAKECMDGOALS))) 1321 | testfilter := $(wordlist 3, $(words $(MAKECMDGOALS)), $(MAKECMDGOALS)) 1322 | testbinpath := zig-out/bin/test 1323 | testbinpath := $(lastword $(testfilter)) 1324 | 1325 | ifeq ($(if $(patsubst /%,,$(testbinpath)),,yes),yes) 1326 | testfilterflag := --test-filter "$(filter-out $(testbinpath), $(testfilter))" 1327 | 1328 | endif 1329 | 1330 | ifneq ($(if $(patsubst /%,,$(testbinpath)),,yes),yes) 1331 | testbinpath := zig-out/bin/test 1332 | ifneq ($(strip $(testfilter)),) 1333 | testfilterflag := --test-filter "$(testfilter)" 1334 | endif 1335 | endif 1336 | 1337 | testname := $(shell basename $(testpath)) 1338 | 1339 | 1340 | $(eval $(testname):;@true) 1341 | 1342 | ifeq ($(words $(testfilter)), 0) 1343 | testfilterflag := --test-name-prefix "$(testname): " 1344 | endif 1345 | 1346 | ifeq ($(testfilterflag), undefined) 1347 | testfilterflag := --test-name-prefix "$(testname): " 1348 | endif 1349 | 1350 | 1351 | endif 1352 | 1353 | ifeq (build-unit, $(firstword $(MAKECMDGOALS))) 1354 | testpath := $(firstword $(wordlist 2, $(words $(MAKECMDGOALS)), $(MAKECMDGOALS))) 1355 | testfilter := $(wordlist 3, $(words $(MAKECMDGOALS)), $(MAKECMDGOALS)) 1356 | testbinpath := zig-out/bin/test 1357 | testbinpath := $(lastword $(testfilter)) 1358 | 1359 | ifeq ($(if $(patsubst /%,,$(testbinpath)),,yes),yes) 1360 | testfilterflag := --test-filter "$(filter-out $(testbinpath), $(testfilter))" 1361 | 1362 | endif 1363 | 1364 | ifneq ($(if $(patsubst /%,,$(testbinpath)),,yes),yes) 1365 | testbinpath := zig-out/bin/test 1366 | ifneq ($(strip $(testfilter)),) 1367 | testfilterflag := --test-filter "$(testfilter)" 1368 | endif 1369 | endif 1370 | 1371 | testname := $(shell basename $(testpath)) 1372 | 1373 | 1374 | $(eval $(testname):;@true) 1375 | $(eval $(testfilter):;@true) 1376 | $(eval $(testpath):;@true) 1377 | 1378 | ifeq ($(words $(testfilter)), 0) 1379 | testfilterflag := --test-name-prefix "$(testname): " 1380 | endif 1381 | 1382 | ifeq ($(testfilterflag), undefined) 1383 | testfilterflag := --test-name-prefix "$(testname): " 1384 | endif 1385 | 1386 | 1387 | 1388 | endif 1389 | 1390 | build-unit: 1391 | @rm -rf zig-out/bin/$(testname) 1392 | @mkdir -p zig-out/bin 1393 | zig test $(realpath $(testpath)) \ 1394 | $(testfilterflag) \ 1395 | $(PACKAGE_MAP) \ 1396 | --main-pkg-path $(BUN_DIR) \ 1397 | --test-no-exec \ 1398 | -fPIC \ 1399 | -femit-bin=zig-out/bin/$(testname) \ 1400 | -fcompiler-rt \ 1401 | -lc -lc++ \ 1402 | --cache-dir /tmp/zig-cache-bun-$(testname)-$(basename $(lastword $(testfilter))) \ 1403 | -fallow-shlib-undefined \ 1404 | && \ 1405 | cp zig-out/bin/$(testname) $(testbinpath) 1406 | 1407 | run-all-unit-tests: 1408 | @rm -rf zig-out/bin/__main_test 1409 | @mkdir -p zig-out/bin 1410 | zig test src/main.zig \ 1411 | $(PACKAGE_MAP) \ 1412 | --main-pkg-path $(BUN_DIR) \ 1413 | --test-no-exec \ 1414 | -fPIC \ 1415 | -femit-bin=zig-out/bin/__main_test \ 1416 | -fcompiler-rt \ 1417 | -lc -lc++ \ 1418 | --cache-dir /tmp/zig-cache-bun-__main_test \ 1419 | -fallow-shlib-undefined \ 1420 | $(ARCHIVE_FILES) $(ICU_FLAGS) $(JSC_FILES) $(JSC_BINDINGS) && \ 1421 | zig-out/bin/__main_test $(ZIG) 1422 | 1423 | run-unit: 1424 | @zig-out/bin/$(testname) $(ZIG) 1425 | 1426 | 1427 | 1428 | test: build-unit run-unit 1429 | 1430 | integration-test-dev: 1431 | USE_EXISTING_PROCESS=true TEST_SERVER_URL=http://localhost:3000 node test/scripts/browser.js 1432 | 1433 | copy-install: 1434 | cp src/cli/install.sh ../bun.sh/docs/install.html 1435 | 1436 | 1437 | 1438 | copy-to-bun-release-dir: copy-to-bun-release-dir-bin copy-to-bun-release-dir-dsym 1439 | 1440 | copy-to-bun-release-dir-bin: 1441 | cp -r $(PACKAGE_DIR)/bun $(BUN_RELEASE_DIR)/bun 1442 | cp -r $(PACKAGE_DIR)/bun-profile $(BUN_RELEASE_DIR)/bun-profile 1443 | 1444 | 1445 | PACKAGE_MAP = --pkg-begin thread_pool $(BUN_DIR)/src/thread_pool.zig --pkg-begin io $(BUN_DIR)/src/io/io_$(OS_NAME).zig --pkg-end --pkg-begin http $(BUN_DIR)/src/http_client_async.zig --pkg-begin strings $(BUN_DIR)/src/string_immutable.zig --pkg-end --pkg-begin picohttp $(BUN_DIR)/src/deps/picohttp.zig --pkg-end --pkg-begin io $(BUN_DIR)/src/io/io_darwin.zig --pkg-end --pkg-begin boringssl $(BUN_DIR)/src/boringssl.zig --pkg-end --pkg-begin thread_pool $(BUN_DIR)/src/thread_pool.zig --pkg-begin io $(BUN_DIR)/src/io/io_darwin.zig --pkg-end --pkg-begin http $(BUN_DIR)/src/http_client_async.zig --pkg-begin strings $(BUN_DIR)/src/string_immutable.zig --pkg-end --pkg-begin picohttp $(BUN_DIR)/src/deps/picohttp.zig --pkg-end --pkg-begin io $(BUN_DIR)/src/io/io_darwin.zig --pkg-end --pkg-begin boringssl $(BUN_DIR)/src/boringssl.zig --pkg-end --pkg-begin thread_pool $(BUN_DIR)/src/thread_pool.zig --pkg-end --pkg-end --pkg-end --pkg-end --pkg-end --pkg-begin picohttp $(BUN_DIR)/src/deps/picohttp.zig --pkg-end --pkg-begin io $(BUN_DIR)/src/io/io_darwin.zig --pkg-end --pkg-begin strings $(BUN_DIR)/src/string_immutable.zig --pkg-end --pkg-begin clap $(BUN_DIR)/src/deps/zig-clap/clap.zig --pkg-end --pkg-begin http $(BUN_DIR)/src/http_client_async.zig --pkg-begin strings $(BUN_DIR)/src/string_immutable.zig --pkg-end --pkg-begin picohttp $(BUN_DIR)/src/deps/picohttp.zig --pkg-end --pkg-begin io $(BUN_DIR)/src/io/io_darwin.zig --pkg-end --pkg-begin boringssl $(BUN_DIR)/src/boringssl.zig --pkg-end --pkg-begin thread_pool $(BUN_DIR)/src/thread_pool.zig --pkg-begin io $(BUN_DIR)/src/io/io_darwin.zig --pkg-end --pkg-begin http $(BUN_DIR)/src/http_client_async.zig --pkg-begin strings $(BUN_DIR)/src/string_immutable.zig --pkg-end --pkg-begin picohttp $(BUN_DIR)/src/deps/picohttp.zig --pkg-end --pkg-begin io $(BUN_DIR)/src/io/io_darwin.zig --pkg-end --pkg-begin boringssl $(BUN_DIR)/src/boringssl.zig --pkg-end --pkg-begin thread_pool $(BUN_DIR)/src/thread_pool.zig --pkg-end --pkg-end --pkg-end --pkg-end --pkg-begin boringssl $(BUN_DIR)/src/boringssl.zig --pkg-end --pkg-begin javascript_core $(BUN_DIR)/src/jsc.zig --pkg-begin http $(BUN_DIR)/src/http_client_async.zig --pkg-end --pkg-begin strings $(BUN_DIR)/src/string_immutable.zig --pkg-end --pkg-begin picohttp $(BUN_DIR)/src/deps/picohttp.zig --pkg-end --pkg-end 1446 | 1447 | 1448 | bun: vendor identifier-cache build-obj bun-link-lld-release bun-codesign-release-local 1449 | --------------------------------------------------------------------------------