├── docker ├── remap.config ├── plugin.config ├── ip_allow.config ├── init.sh └── trafficserver.yml ├── tests ├── kubernetes.config.invalid2 ├── kubernetes.config.invalid ├── plugin.config ├── e2e-kubernetes.config ├── kubernetes.config ├── e2e │ ├── 002-tls │ │ ├── resources │ │ │ ├── configmap.json │ │ │ ├── service.json │ │ │ ├── endpoints.json │ │ │ ├── ingress-default.json │ │ │ ├── ingress.json │ │ │ ├── ingress-tls10.json │ │ │ ├── ingress-tls11.json │ │ │ └── ingress-tls12.json │ │ └── run.sh │ ├── 007-domain-access-list │ │ ├── resources │ │ │ ├── configmap.json │ │ │ ├── service.json │ │ │ ├── endpoints.json │ │ │ ├── ingress-bad.json │ │ │ └── ingress.json │ │ └── run.sh │ ├── 001-basic │ │ ├── run.sh │ │ └── resources │ │ │ ├── service.json │ │ │ ├── endpoints.json │ │ │ └── ingress.json │ ├── 005-auth │ │ ├── resources │ │ │ ├── service.json │ │ │ ├── endpoints.json │ │ │ ├── secret.json │ │ │ ├── ingress.json │ │ │ ├── ingress-all-ipbad.json │ │ │ ├── ingress-all-ipok.json │ │ │ ├── ingress-any-ipbad.json │ │ │ └── ingress-any-ipok.json │ │ └── run.sh │ ├── 006-cors │ │ ├── resources │ │ │ ├── service.json │ │ │ ├── endpoints.json │ │ │ ├── ingress.json │ │ │ └── ingress-private.json │ │ └── run.sh │ ├── 003-caching │ │ └── resources │ │ │ ├── service.json │ │ │ ├── endpoints.json │ │ │ ├── ingress-url-ignore.json │ │ │ ├── ingress-url-whitelist.json │ │ │ └── ingress.json │ └── 004-compression │ │ ├── resources │ │ ├── service.json │ │ ├── endpoints.json │ │ └── ingress.json │ │ └── run.sh ├── kubeconfig ├── configmap.json ├── secret.json ├── test_support.cc ├── service2.json ├── endpoints2.json ├── service.json ├── service_external.json ├── test.h ├── ingress-no-host.json ├── secret-htauth.json ├── ingress-basic.json ├── fileserver.sh ├── ingress-class2.json ├── ingress-app-root.json ├── ingress-class1.json ├── ingress-cors1.json ├── ingress-force-tls.json ├── ingress-ignore-params.json ├── ingress-whitelist-params.json ├── endpoints.json ├── ingress-rewrite-target.json ├── ingress-secure-backends.json ├── ingress-auth-address.json ├── ingress-ignore-whitelist-params.json ├── ingress-auth-basic.json ├── ingress.json ├── test-cert.pem ├── generator.sh ├── ingress-auth-all.json ├── ingress-auth-any.json ├── test-key.pem ├── ts_mockapi.cc ├── records.config └── httpd.sh ├── .dockerignore ├── .gitattributes ├── contrib ├── brotli │ ├── common │ │ ├── dictionary.bin │ │ ├── version.h │ │ ├── dictionary.h │ │ └── constants.h │ ├── enc │ │ ├── dictionary_hash.h │ │ ├── bit_cost.c │ │ ├── literal_cost.h │ │ ├── utf8_util.h │ │ ├── cluster.h │ │ ├── block_encoder_inc.h │ │ ├── static_dict.h │ │ ├── backward_references.h │ │ ├── histogram_inc.h │ │ ├── cluster.c │ │ ├── block_splitter.h │ │ ├── memory.h │ │ ├── bit_cost.h │ │ ├── histogram.h │ │ ├── prefix.h │ │ ├── compress_fragment_two_pass.h │ │ ├── utf8_util.c │ │ ├── find_match_length.h │ │ ├── compress_fragment.h │ │ ├── write_bits.h │ │ └── histogram.c │ ├── Makefile.in │ └── include │ │ └── brotli │ │ └── types.h └── rax │ └── rax_malloc.h ├── test.htpasswd ├── .gitignore ├── docs ├── debugging.md ├── classes.md ├── domainaccess.md ├── source.md ├── annotations.md ├── docker.md ├── external.md └── serverpush.md ├── util ├── strmatch.h ├── base64.h ├── test_base64.cc └── base64.c ├── mkdocs.yml ├── example-rbac.yaml ├── tsapi ├── synth.h └── config.h ├── api ├── watcher.h ├── configmap.c └── namespace.c ├── auth └── auth.h ├── trafficserver-ds.yml ├── travis-build.sh ├── crypt └── ts_crypt.h ├── Dockerfile ├── gtest ├── src │ ├── gtest_main.cc │ └── gtest-all.cc └── include │ └── gtest │ ├── internal │ └── custom │ │ ├── gtest.h │ │ ├── gtest-printers.h │ │ └── gtest-port.h │ └── gtest_prod.h ├── Makefile.dist ├── kubernetes.config.example ├── configure.ac └── autoconf.h.in /docker/remap.config: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/kubernetes.config.invalid2: -------------------------------------------------------------------------------- 1 | tls: foo 2 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | *.so 3 | *.o 4 | *.a 5 | _test 6 | -------------------------------------------------------------------------------- /tests/kubernetes.config.invalid: -------------------------------------------------------------------------------- 1 | tls: true 2 | foo bar 3 | -------------------------------------------------------------------------------- /tests/plugin.config: -------------------------------------------------------------------------------- 1 | kubernetes.so kubernetes.config 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | /remap.pl text eol=lf 2 | /init.sh text eol=lf 3 | /*.config text eol=lf 4 | -------------------------------------------------------------------------------- /tests/e2e-kubernetes.config: -------------------------------------------------------------------------------- 1 | server: http://127.0.0.1:48888 2 | tls: true 3 | remap: true 4 | configmap: default/ts-config 5 | -------------------------------------------------------------------------------- /contrib/brotli/common/dictionary.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/torchbox/k8s-ts-ingress/HEAD/contrib/brotli/common/dictionary.bin -------------------------------------------------------------------------------- /tests/kubernetes.config: -------------------------------------------------------------------------------- 1 | # This is a comment. 2 | 3 | server: https://apiserver.mycluster.com:8443 4 | cafile: /path/to/kube-prod.ca 5 | certfile: /path/to/kube-prod.crt 6 | keyfile: /path/to/kube-prod.key 7 | token: ABCD1234 8 | tls: true 9 | remap: false 10 | -------------------------------------------------------------------------------- /tests/e2e/002-tls/resources/configmap.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "data": { 4 | "tls-certificates": "default.echoheaders.test:default/tls-test" 5 | }, 6 | "kind": "ConfigMap", 7 | "metadata": { 8 | "name": "ts-config", 9 | "namespace": "default" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/e2e/007-domain-access-list/resources/configmap.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "data": { 4 | "domain-access-list": "*echoheaders.test:default *.test:otherns" 5 | }, 6 | "kind": "ConfigMap", 7 | "metadata": { 8 | "name": "ts-config", 9 | "namespace": "default" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/kubeconfig: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Config 3 | preferences: {} 4 | current-context: test 5 | 6 | clusters: 7 | - name: test 8 | cluster: 9 | server: http://127.0.0.1:48888 10 | 11 | users: 12 | - name: test 13 | user: 14 | 15 | contexts: 16 | - name: test 17 | context: 18 | cluster: test 19 | user: test 20 | -------------------------------------------------------------------------------- /docker/plugin.config: -------------------------------------------------------------------------------- 1 | # Kubernetes Ingress support 2 | kubernetes.so 3 | 4 | # Support ESI. 5 | esi.so --first-byte-flush 6 | 7 | # Collapse multiple connections for the same resource. 8 | #disabled due to crashing 9 | #collapsed_connection.so 1 10 | 11 | # Serve stale content on origin errors. 12 | #disabled due to memory leak 13 | #stale_while_revalidate.so --force-stale-if-error 14 | -------------------------------------------------------------------------------- /test.htpasswd: -------------------------------------------------------------------------------- 1 | destest:7yJh5CCgDzVSc 2 | md5test:$1$abcd1234$4pRDZEdmg6jg3P7h0l3ir1 3 | bftest:$2a$04$1qy2iBd52qBMgjRDOUAYDONjVznoFv1ig/kQbcl17CTBx2eNvs4Dq 4 | sha256test:$5$abcd1234$2Yu3cjGGBlTD.mWF1bqkLWCS134RcRZ3q6WX/dCCLCA 5 | sha512test:$6$abcd1234$y5bVb7D7L.dReoN52g.d8gwzRkbrmymT0a8OjxsEAip9WRASVeJPU/yRTZc2P7qVwgDIVm8nEfUERFyMoIzb// 6 | shatest:{SHA}5tQ74+o9f/9M8qg2Ryb14BdaI7A= 7 | sshatest:{SSHA}8eweop0v7TNF+DE00ZsXByaL8bwiPC37 8 | plaintest:{PLAIN}plaintest 9 | -------------------------------------------------------------------------------- /tests/e2e/001-basic/run.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # vim:set sw=8 ts=8 noet: 3 | 4 | # Test basic functionality, i.e. that routing requests to an endpoint works. 5 | 6 | set -e 7 | output=$(curl -sS --resolve echoheaders.test:58080:127.0.0.1 http://echoheaders.test:58080/this-is-a-test) 8 | 9 | if echo "$output" | grep -q "Request path: /this-is-a-test"; then 10 | exit 0 11 | else 12 | echo "Failed: output did not include test string." 13 | echo "Test output: [$output]" 14 | exit 1 15 | fi 16 | -------------------------------------------------------------------------------- /tests/e2e/001-basic/resources/service.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "kind": "Service", 4 | "metadata": { 5 | "name": "echoheaders", 6 | "namespace": "default" 7 | }, 8 | "spec": { 9 | "ports": [ 10 | { 11 | "name": "http", 12 | "port": 80, 13 | "protocol": "TCP", 14 | "targetPort": 48080 15 | } 16 | ], 17 | "type": "ClusterIP" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/e2e/002-tls/resources/service.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "kind": "Service", 4 | "metadata": { 5 | "name": "echoheaders", 6 | "namespace": "default" 7 | }, 8 | "spec": { 9 | "ports": [ 10 | { 11 | "name": "http", 12 | "port": 80, 13 | "protocol": "TCP", 14 | "targetPort": 48080 15 | } 16 | ], 17 | "type": "ClusterIP" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/e2e/005-auth/resources/service.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "kind": "Service", 4 | "metadata": { 5 | "name": "echoheaders", 6 | "namespace": "default" 7 | }, 8 | "spec": { 9 | "ports": [ 10 | { 11 | "name": "http", 12 | "port": 80, 13 | "protocol": "TCP", 14 | "targetPort": 48080 15 | } 16 | ], 17 | "type": "ClusterIP" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/e2e/006-cors/resources/service.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "kind": "Service", 4 | "metadata": { 5 | "name": "echoheaders", 6 | "namespace": "default" 7 | }, 8 | "spec": { 9 | "ports": [ 10 | { 11 | "name": "http", 12 | "port": 80, 13 | "protocol": "TCP", 14 | "targetPort": 48080 15 | } 16 | ], 17 | "type": "ClusterIP" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/e2e/003-caching/resources/service.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "kind": "Service", 4 | "metadata": { 5 | "name": "echoheaders", 6 | "namespace": "default" 7 | }, 8 | "spec": { 9 | "ports": [ 10 | { 11 | "name": "http", 12 | "port": 80, 13 | "protocol": "TCP", 14 | "targetPort": 48080 15 | } 16 | ], 17 | "type": "ClusterIP" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/e2e/004-compression/resources/service.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "kind": "Service", 4 | "metadata": { 5 | "name": "echoheaders", 6 | "namespace": "default" 7 | }, 8 | "spec": { 9 | "ports": [ 10 | { 11 | "name": "http", 12 | "port": 80, 13 | "protocol": "TCP", 14 | "targetPort": 48080 15 | } 16 | ], 17 | "type": "ClusterIP" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/e2e/007-domain-access-list/resources/service.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "kind": "Service", 4 | "metadata": { 5 | "name": "echoheaders", 6 | "namespace": "default" 7 | }, 8 | "spec": { 9 | "ports": [ 10 | { 11 | "name": "http", 12 | "port": 80, 13 | "protocol": "TCP", 14 | "targetPort": 48080 15 | } 16 | ], 17 | "type": "ClusterIP" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/configmap.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "data": { 4 | "key1": "value 1", 5 | "key2": "other value" 6 | }, 7 | "kind": "ConfigMap", 8 | "metadata": { 9 | "creationTimestamp": "2017-06-20T22:35:43Z", 10 | "name": "testconfigmap", 11 | "namespace": "default", 12 | "resourceVersion": "118153", 13 | "selfLink": "/api/v1/namespaces/default/configmaps/testconfigmap", 14 | "uid": "cbb1bd3c-5608-11e7-8fbf-4201ac1fd00b" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/secret.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "data": { 4 | "key1": "c29tZSB2YWx1ZQ==", 5 | "key2": "b3RoZXIgdmFsdWU=" 6 | }, 7 | "kind": "Secret", 8 | "metadata": { 9 | "creationTimestamp": "2017-04-28T22:34:56Z", 10 | "name": "testsecret", 11 | "namespace": "default", 12 | "resourceVersion": "3337245", 13 | "selfLink": "/api/v1/namespaces/default/secrets/testsecret", 14 | "uid": "e79f091a-2c62-11e7-9ecd-4201ac1fd807" 15 | }, 16 | "type": "Opaque" 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Editor backup/auto-save files. 2 | *.sw? 3 | *~ 4 | \#*# 5 | 6 | # Build files 7 | *.o 8 | *.so 9 | *.a 10 | 11 | # autoconf generated files 12 | /Makefile 13 | /aclocal.m4 14 | /autom4te.cache 15 | /autoconf.h 16 | /config.log 17 | /config.status 18 | 19 | # clang-analyzer creates these 20 | *.plist 21 | 22 | # Files that might exist in development. 23 | .kube 24 | /kubernetes.config 25 | /release.tar.gz 26 | /k8s-ts-ingress-* 27 | /test 28 | /_test 29 | /configure 30 | /_docs 31 | /contrib/brotli/Makefile 32 | /dist.tar 33 | /cov-int* 34 | -------------------------------------------------------------------------------- /docker/ip_allow.config: -------------------------------------------------------------------------------- 1 | src_ip=127.0.0.1 action=ip_allow method=ALL 2 | src_ip=::1 action=ip_allow method=ALL 3 | src_ip=10.0.0.0-10.255.255.255 action=ip_allow method=ALL 4 | src_ip=172.16.0.0-172.31.255.255 action=ip_allow method=ALL 5 | src_ip=192.168.0.0-192.168.255.255 action=ip_allow method=ALL 6 | src_ip=0.0.0.0-255.255.255.255 action=ip_deny method=PUSH|PURGE 7 | src_ip=::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff action=ip_deny method=PUSH|PURGE 8 | -------------------------------------------------------------------------------- /docs/debugging.md: -------------------------------------------------------------------------------- 1 | # Debugging 2 | 3 | To enable debug logging on an Ingress, set the `ingress.torchbox.com/debug-log` 4 | annotation: 5 | 6 | ```yaml 7 | metadata: 8 | annotations: 9 | ingress.torchbox.com/debug-log: "true" 10 | ``` 11 | 12 | This will log the full set of requests and responses for every transaction on 13 | this Ingress to the Traffic Server `error.log`. This should not be enabled 14 | during normal operation, since it will generate a very large amount of log data, 15 | but it can be useful to diagnose HTTP-related issues or to investigate bugs in 16 | Traffic Server or the Ingress controller. 17 | -------------------------------------------------------------------------------- /tests/e2e/001-basic/resources/endpoints.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "kind": "Endpoints", 4 | "metadata": { 5 | "name": "echoheaders", 6 | "namespace": "default" 7 | }, 8 | "subsets": [ 9 | { 10 | "addresses": [ 11 | { 12 | "ip": "$TEST_IP_ADDRESS" 13 | } 14 | ], 15 | "ports": [ 16 | { 17 | "name": "http", 18 | "port": 48080, 19 | "protocol": "TCP" 20 | } 21 | ] 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /tests/e2e/002-tls/resources/endpoints.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "kind": "Endpoints", 4 | "metadata": { 5 | "name": "echoheaders", 6 | "namespace": "default" 7 | }, 8 | "subsets": [ 9 | { 10 | "addresses": [ 11 | { 12 | "ip": "$TEST_IP_ADDRESS" 13 | } 14 | ], 15 | "ports": [ 16 | { 17 | "name": "http", 18 | "port": 48080, 19 | "protocol": "TCP" 20 | } 21 | ] 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /tests/e2e/005-auth/resources/endpoints.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "kind": "Endpoints", 4 | "metadata": { 5 | "name": "echoheaders", 6 | "namespace": "default" 7 | }, 8 | "subsets": [ 9 | { 10 | "addresses": [ 11 | { 12 | "ip": "$TEST_IP_ADDRESS" 13 | } 14 | ], 15 | "ports": [ 16 | { 17 | "name": "http", 18 | "port": 48080, 19 | "protocol": "TCP" 20 | } 21 | ] 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /tests/e2e/006-cors/resources/endpoints.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "kind": "Endpoints", 4 | "metadata": { 5 | "name": "echoheaders", 6 | "namespace": "default" 7 | }, 8 | "subsets": [ 9 | { 10 | "addresses": [ 11 | { 12 | "ip": "$TEST_IP_ADDRESS" 13 | } 14 | ], 15 | "ports": [ 16 | { 17 | "name": "http", 18 | "port": 48080, 19 | "protocol": "TCP" 20 | } 21 | ] 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /tests/e2e/003-caching/resources/endpoints.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "kind": "Endpoints", 4 | "metadata": { 5 | "name": "echoheaders", 6 | "namespace": "default" 7 | }, 8 | "subsets": [ 9 | { 10 | "addresses": [ 11 | { 12 | "ip": "$TEST_IP_ADDRESS" 13 | } 14 | ], 15 | "ports": [ 16 | { 17 | "name": "http", 18 | "port": 48080, 19 | "protocol": "TCP" 20 | } 21 | ] 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /tests/e2e/004-compression/resources/endpoints.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "kind": "Endpoints", 4 | "metadata": { 5 | "name": "echoheaders", 6 | "namespace": "default" 7 | }, 8 | "subsets": [ 9 | { 10 | "addresses": [ 11 | { 12 | "ip": "$TEST_IP_ADDRESS" 13 | } 14 | ], 15 | "ports": [ 16 | { 17 | "name": "http", 18 | "port": 48080, 19 | "protocol": "TCP" 20 | } 21 | ] 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /tests/e2e/007-domain-access-list/resources/endpoints.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "kind": "Endpoints", 4 | "metadata": { 5 | "name": "echoheaders", 6 | "namespace": "default" 7 | }, 8 | "subsets": [ 9 | { 10 | "addresses": [ 11 | { 12 | "ip": "$TEST_IP_ADDRESS" 13 | } 14 | ], 15 | "ports": [ 16 | { 17 | "name": "http", 18 | "port": 48080, 19 | "protocol": "TCP" 20 | } 21 | ] 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /util/strmatch.h: -------------------------------------------------------------------------------- 1 | /* vim:set sw=8 ts=8 noet: */ 2 | /* 3 | * Copyright (c) 2016-2017 Torchbox Ltd. 4 | * 5 | * Permission is granted to anyone to use this software for any purpose, 6 | * including commercial applications, and to alter it and redistribute it 7 | * freely. This software is provided 'as-is', without any express or implied 8 | * warranty. 9 | */ 10 | 11 | #ifndef STRMATCH_H 12 | #define STRMATCH_H 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | int strmatch(const char *str, const char *strend, 19 | const char *pat, const char *patend); 20 | 21 | #ifdef __cplusplus 22 | } 23 | #endif 24 | 25 | #endif /* !STRMATCH_H */ 26 | -------------------------------------------------------------------------------- /contrib/brotli/common/version.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2016 Google Inc. All Rights Reserved. 2 | 3 | Distributed under MIT license. 4 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 5 | */ 6 | 7 | /* Version definition. */ 8 | 9 | #ifndef BROTLI_COMMON_VERSION_H_ 10 | #define BROTLI_COMMON_VERSION_H_ 11 | 12 | /* This macro should only be used when library is compiled together with client. 13 | If library is dynamically linked, use BrotliDecoderVersion and 14 | BrotliEncoderVersion methods. */ 15 | 16 | /* Semantic version, calculated as (MAJOR << 24) | (MINOR << 12) | PATCH */ 17 | #define BROTLI_VERSION 0x1000000 18 | 19 | #endif /* BROTLI_COMMON_VERSION_H_ */ 20 | -------------------------------------------------------------------------------- /contrib/brotli/enc/dictionary_hash.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2015 Google Inc. All Rights Reserved. 2 | 3 | Distributed under MIT license. 4 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 5 | */ 6 | 7 | /* Hash table on the 4-byte prefixes of static dictionary words. */ 8 | 9 | #ifndef BROTLI_ENC_DICTIONARY_HASH_H_ 10 | #define BROTLI_ENC_DICTIONARY_HASH_H_ 11 | 12 | #include 13 | 14 | #if defined(__cplusplus) || defined(c_plusplus) 15 | extern "C" { 16 | #endif 17 | 18 | extern const uint16_t kStaticDictionaryHash[32768]; 19 | 20 | #if defined(__cplusplus) || defined(c_plusplus) 21 | } /* extern "C" */ 22 | #endif 23 | 24 | #endif /* BROTLI_ENC_DICTIONARY_HASH_H_ */ 25 | -------------------------------------------------------------------------------- /tests/e2e/001-basic/resources/ingress.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "name": "echoheaders", 6 | "namespace": "default" 7 | }, 8 | "spec": { 9 | "rules": [ 10 | { 11 | "host": "echoheaders.test", 12 | "http": { 13 | "paths": [ 14 | { 15 | "backend": { 16 | "serviceName": "echoheaders", 17 | "servicePort": "http" 18 | } 19 | } 20 | ] 21 | } 22 | } 23 | ] 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/e2e/004-compression/resources/ingress.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "name": "echoheaders", 6 | "namespace": "default" 7 | }, 8 | "spec": { 9 | "rules": [ 10 | { 11 | "host": "echoheaders.test", 12 | "http": { 13 | "paths": [ 14 | { 15 | "backend": { 16 | "serviceName": "echoheaders", 17 | "servicePort": "http" 18 | } 19 | } 20 | ] 21 | } 22 | } 23 | ] 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/e2e/002-tls/resources/ingress-default.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "name": "echoheaders-default", 6 | "namespace": "default" 7 | }, 8 | "spec": { 9 | "rules": [ 10 | { 11 | "host": "default.echoheaders.test", 12 | "http": { 13 | "paths": [ 14 | { 15 | "backend": { 16 | "serviceName": "echoheaders", 17 | "servicePort": "http" 18 | } 19 | } 20 | ] 21 | } 22 | } 23 | ] 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/e2e/007-domain-access-list/resources/ingress-bad.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "name": "echoheaders2", 6 | "namespace": "default" 7 | }, 8 | "spec": { 9 | "rules": [ 10 | { 11 | "host": "notechoheaders.test", 12 | "http": { 13 | "paths": [ 14 | { 15 | "backend": { 16 | "serviceName": "echoheaders", 17 | "servicePort": "http" 18 | } 19 | } 20 | ] 21 | } 22 | } 23 | ] 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: TS Ingress Controller 2 | theme: readthedocs 3 | docs_dir: docs 4 | site_dir: _docs 5 | repo_name: GitHub 6 | repo_url: https://github.com/torchbox/k8s-ts-ingress 7 | copyright: Copyright (c) 2016-2017 Torchbox Ltd. 8 | strict: true 9 | pages: 10 | - Home: index.md 11 | - Installation: 12 | - Installing from source: source.md 13 | - Using the Docker Image: docker.md 14 | - Using multiple Ingress controllers: classes.md 15 | - Configuration: config.md 16 | - Domain access control: domainaccess.md 17 | - Usage: 18 | - Annotations: annotations.md 19 | - Caching: caching.md 20 | - Authentication: auth.md 21 | - External proxying: external.md 22 | - TLS: tls.md 23 | - CORS: cors.md 24 | - Compression: compression.md 25 | - Server Push: serverpush.md 26 | - Debugging: debugging.md 27 | -------------------------------------------------------------------------------- /example-rbac.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: trafficserver 5 | 6 | --- 7 | 8 | apiVersion: rbac.authorization.k8s.io/v1beta1 9 | kind: ClusterRole 10 | metadata: 11 | name: trafficserver 12 | rules: 13 | - apiGroups: 14 | - '*' 15 | resources: 16 | - ingresses 17 | - secrets 18 | - services 19 | - pods 20 | - namespaces 21 | - replicationcontrollers 22 | - endpoints 23 | - configmaps 24 | verbs: 25 | - get 26 | - list 27 | - watch 28 | 29 | --- 30 | 31 | apiVersion: rbac.authorization.k8s.io/v1beta1 32 | kind: ClusterRoleBinding 33 | metadata: 34 | name: trafficserver 35 | subjects: 36 | - kind: ServiceAccount 37 | name: default 38 | namespace: trafficserver 39 | roleRef: 40 | apiGroup: rbac.authorization.k8s.io 41 | kind: ClusterRole 42 | name: trafficserver 43 | -------------------------------------------------------------------------------- /tests/e2e/005-auth/resources/secret.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "data": { 4 | "auth": "ZGVzdGVzdDo3eUpoNUNDZ0R6VlNjCm1kNXRlc3Q6JDEkYWJjZDEyMzQkNHBSRFpFZG1nNmpnM1A3aDBsM2lyMQpiZnRlc3Q6JDJhJDA0JDFxeTJpQmQ1MnFCTWdqUkRPVUFZRE9OalZ6bm9GdjFpZy9rUWJjbDE3Q1RCeDJlTnZzNERxCnNoYTI1NnRlc3Q6JDUkYWJjZDEyMzQkMll1M2NqR0dCbFRELm1XRjFicWtMV0NTMTM0UmNSWjNxNldYL2RDQ0xDQQpzaGE1MTJ0ZXN0OiQ2JGFiY2QxMjM0JHk1YlZiN0Q3TC5kUmVvTjUyZy5kOGd3elJrYnJteW1UMGE4T2p4c0VBaXA5V1JBU1ZlSlBVL3lSVFpjMlA3cVZ3Z0RJVm04bkVmVUVSRnlNb0l6Yi8vCnNoYXRlc3Q6e1NIQX01dFE3NCtvOWYvOU04cWcyUnliMTRCZGFJN0E9CnNzaGF0ZXN0OntTU0hBfThld2VvcDB2N1RORitERTAwWnNYQnlhTDhid2lQQzM3CnBsYWludGVzdDp7UExBSU59cGxhaW50ZXN0Cg==" 5 | }, 6 | "kind": "Secret", 7 | "metadata": { 8 | "name": "authtest", 9 | "namespace": "default" 10 | }, 11 | "type": "Opaque" 12 | } 13 | -------------------------------------------------------------------------------- /tests/test_support.cc: -------------------------------------------------------------------------------- 1 | /* vim:set sw=8 ts=8 noet: */ 2 | /* 3 | * Copyright (c) 2016-2017 Torchbox Ltd. 4 | * 5 | * Permission is granted to anyone to use this software for any purpose, 6 | * including commercial applications, and to alter it and redistribute it 7 | * freely. This software is provided 'as-is', without any express or implied 8 | * warranty. 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | #include "tests/test.h" 19 | 20 | json_object * 21 | test_load_json(std::string const& fname) 22 | { 23 | std::ifstream inf(fname); 24 | 25 | if (!inf) 26 | return nullptr; 27 | 28 | std::string json_str(std::istreambuf_iterator{inf}, {}); 29 | json_object *obj = json_tokener_parse(json_str.c_str()); 30 | return obj; 31 | } 32 | -------------------------------------------------------------------------------- /util/base64.h: -------------------------------------------------------------------------------- 1 | /* vim:set sw=8 ts=8 noet: */ 2 | /* 3 | * Copyright (c) 2011, 2017 Felicity Tarnell. 4 | * 5 | * Permission is granted to anyone to use this software for any purpose, 6 | * including commercial applications, and to alter it and redistribute it 7 | * freely. This software is provided 'as-is', without any express or implied 8 | * warranty. 9 | */ 10 | 11 | #ifndef BASE64_H 12 | #define BASE64_H 13 | 14 | #include 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | #define base64_encode_len(n) (4 * ((n + 2) / 3)) 21 | #define base64_decode_len(n) (3 * ((n + 3) / 4)) 22 | 23 | void base64_encode(const unsigned char *inbuf, size_t inlen, char *outbuf); 24 | ssize_t base64_decode(char const *inbuf, size_t inlen, unsigned char *outbuf); 25 | 26 | #ifdef __cplusplus 27 | } 28 | #endif 29 | 30 | #endif /* !BASE64_H */ 31 | -------------------------------------------------------------------------------- /tests/service2.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "kind": "Service", 4 | "metadata": { 5 | "creationTimestamp": "2017-04-26T01:34:08Z", 6 | "name": "echoheaders", 7 | "namespace": "default", 8 | "resourceVersion": "2855647", 9 | "selfLink": "/api/v1/namespaces/default/services/echoheaders", 10 | "uid": "710952b2-2a20-11e7-a408-4201ac1fd809" 11 | }, 12 | "spec": { 13 | "clusterIP": "10.3.19.27", 14 | "ports": [ 15 | { 16 | "port": 80, 17 | "protocol": "TCP", 18 | "targetPort": 8080 19 | } 20 | ], 21 | "selector": { 22 | "app": "echoheaders" 23 | }, 24 | "sessionAffinity": "None", 25 | "type": "ClusterIP" 26 | }, 27 | "status": { 28 | "loadBalancer": {} 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/endpoints2.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "Endpoints", 3 | "apiVersion": "v1", 4 | "metadata": { 5 | "name":"kube-lego-nginx", 6 | "namespace": "kube-lego", 7 | "selfLink": "/api/v1/namespaces/kube-lego/endpoints/kube-lego-nginx", 8 | "uid": "ccc81a2c-1d7f-11e7-be11-4201ac1fd807", 9 | "resourceVersion": "9052867", 10 | "creationTimestamp": "2017-04-09T23:53:59Z" 11 | }, 12 | "subsets": [ 13 | { 14 | "notReadyAddresses": [ 15 | { 16 | "ip": "172.28.114.153", 17 | "nodeName":"worker-g8dj", 18 | "targetRef": { 19 | "kind": "Pod", 20 | "namespace": "kube-lego", 21 | "name": "kube-lego-2225583713-6z6th", 22 | "uid": "f94d4d7c-4687-11e7-a408-4201ac1fd809", 23 | "resourceVersion":"9052866" 24 | } 25 | } 26 | ], 27 | "ports": [ 28 | { 29 | "port":8080, 30 | "protocol":"TCP" 31 | } 32 | ] 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /tests/e2e/006-cors/resources/ingress.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "name": "echoheaders", 6 | "namespace": "default", 7 | "annotations": { 8 | "ingress.kubernetes.io/enable-cors": "true", 9 | "ingress.kubernetes.io/cors-max-age": "3600" 10 | } 11 | }, 12 | "spec": { 13 | "rules": [ 14 | { 15 | "host": "echoheaders.test", 16 | "http": { 17 | "paths": [ 18 | { 19 | "backend": { 20 | "serviceName": "echoheaders", 21 | "servicePort": "http" 22 | } 23 | } 24 | ] 25 | } 26 | } 27 | ] 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/service.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "kind": "Service", 4 | "metadata": { 5 | "creationTimestamp": "2017-04-26T01:34:08Z", 6 | "name": "echoheaders", 7 | "namespace": "default", 8 | "resourceVersion": "2855647", 9 | "selfLink": "/api/v1/namespaces/default/services/echoheaders", 10 | "uid": "710952b2-2a20-11e7-a408-4201ac1fd809" 11 | }, 12 | "spec": { 13 | "clusterIP": "10.3.19.27", 14 | "ports": [ 15 | { 16 | "name": "http", 17 | "port": 80, 18 | "protocol": "TCP", 19 | "targetPort": 8080 20 | } 21 | ], 22 | "selector": { 23 | "app": "echoheaders" 24 | }, 25 | "sessionAffinity": "None", 26 | "type": "ClusterIP" 27 | }, 28 | "status": { 29 | "loadBalancer": {} 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/e2e/002-tls/resources/ingress.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "name": "echoheaders", 6 | "namespace": "default" 7 | }, 8 | "spec": { 9 | "rules": [ 10 | { 11 | "host": "echoheaders.test", 12 | "http": { 13 | "paths": [ 14 | { 15 | "backend": { 16 | "serviceName": "echoheaders", 17 | "servicePort": "http" 18 | } 19 | } 20 | ] 21 | } 22 | } 23 | ], 24 | "tls": [ 25 | { 26 | "hosts": [ 27 | "echoheaders.test" 28 | ], 29 | "secretName": "tls-test" 30 | } 31 | ] 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /tests/e2e/003-caching/resources/ingress-url-ignore.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "name": "echoheaders-ignore", 6 | "namespace": "default", 7 | "annotations": { 8 | "ingress.kubernetes.io/cache-ignore-query-params": "badparam*", 9 | "ingress.kubernetes.io/cache-ignore-cookies": "badcookie*" 10 | } 11 | }, 12 | "spec": { 13 | "rules": [ 14 | { 15 | "host": "ignore.echoheaders.test", 16 | "http": { 17 | "paths": [ 18 | { 19 | "backend": { 20 | "serviceName": "echoheaders", 21 | "servicePort": "http" 22 | } 23 | } 24 | ] 25 | } 26 | } 27 | ] 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /contrib/brotli/enc/bit_cost.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Google Inc. All Rights Reserved. 2 | 3 | Distributed under MIT license. 4 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 5 | */ 6 | 7 | /* Functions to estimate the bit cost of Huffman trees. */ 8 | 9 | #include "./bit_cost.h" 10 | 11 | #include "../common/constants.h" 12 | #include 13 | #include "./fast_log.h" 14 | #include "./histogram.h" 15 | #include "./port.h" 16 | 17 | #if defined(__cplusplus) || defined(c_plusplus) 18 | extern "C" { 19 | #endif 20 | 21 | #define FN(X) X ## Literal 22 | #include "./bit_cost_inc.h" /* NOLINT(build/include) */ 23 | #undef FN 24 | 25 | #define FN(X) X ## Command 26 | #include "./bit_cost_inc.h" /* NOLINT(build/include) */ 27 | #undef FN 28 | 29 | #define FN(X) X ## Distance 30 | #include "./bit_cost_inc.h" /* NOLINT(build/include) */ 31 | #undef FN 32 | 33 | #if defined(__cplusplus) || defined(c_plusplus) 34 | } /* extern "C" */ 35 | #endif 36 | -------------------------------------------------------------------------------- /tests/e2e/005-auth/resources/ingress.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "name": "echoheaders", 6 | "namespace": "default", 7 | "annotations": { 8 | "ingress.kubernetes.io/auth-secret": "authtest", 9 | "ingress.kubernetes.io/auth-realm": "auth test", 10 | "ingress.kubernetes.io/auth-type": "basic" 11 | } 12 | }, 13 | "spec": { 14 | "rules": [ 15 | { 16 | "host": "echoheaders.test", 17 | "http": { 18 | "paths": [ 19 | { 20 | "backend": { 21 | "serviceName": "echoheaders", 22 | "servicePort": "http" 23 | } 24 | } 25 | ] 26 | } 27 | } 28 | ] 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/service_external.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "kind": "Service", 4 | "metadata": { 5 | "annotations": { 6 | "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"Service\",\"metadata\":{\"annotations\":{},\"name\":\"external-service\",\"namespace\":\"default\"},\"spec\":{\"externalName\":\"echoheaders.gce.t6x.uk\",\"type\":\"ExternalName\"}}\n" 7 | }, 8 | "creationTimestamp": "2017-04-26T16:27:19Z", 9 | "name": "external-service", 10 | "namespace": "default", 11 | "resourceVersion": "2960319", 12 | "selfLink": "/api/v1/namespaces/default/services/external-service", 13 | "uid": "37b3b5bb-2a9d-11e7-a408-4201ac1fd809" 14 | }, 15 | "spec": { 16 | "externalName": "echoheaders.gce.t6x.uk", 17 | "sessionAffinity": "None", 18 | "type": "ExternalName" 19 | }, 20 | "status": { 21 | "loadBalancer": {} 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/e2e/003-caching/resources/ingress-url-whitelist.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "name": "echoheaders-whitelist", 6 | "namespace": "default", 7 | "annotations": { 8 | "ingress.kubernetes.io/cache-whitelist-query-params": "goodparam*", 9 | "ingress.kubernetes.io/cache-whitelist-cookies": "goodcookie*" 10 | } 11 | }, 12 | "spec": { 13 | "rules": [ 14 | { 15 | "host": "whitelist.echoheaders.test", 16 | "http": { 17 | "paths": [ 18 | { 19 | "backend": { 20 | "serviceName": "echoheaders", 21 | "servicePort": "http" 22 | } 23 | } 24 | ] 25 | } 26 | } 27 | ] 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/test.h: -------------------------------------------------------------------------------- 1 | /* vim:set sw=8 ts=8 noet: */ 2 | /* 3 | * Copyright (c) 2016-2017 Torchbox Ltd. 4 | * 5 | * Permission is granted to anyone to use this software for any purpose, 6 | * including commercial applications, and to alter it and redistribute it 7 | * freely. This software is provided 'as-is', without any express or implied 8 | * warranty. 9 | */ 10 | 11 | #ifndef TEST_H 12 | #define TEST_H 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | extern int ts_api_errors; 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | 24 | #ifdef __cplusplus 25 | #include 26 | #include 27 | 28 | json_object *test_load_json(std::string const& fname); 29 | 30 | template 31 | struct scoped_c_ptr { 32 | typedef void (*free_fn_t) (T); 33 | 34 | scoped_c_ptr(T ptr, free_fn_t fn) : ptr(ptr), free_fn(fn) {} 35 | 36 | ~scoped_c_ptr() { 37 | free_fn(ptr); 38 | } 39 | 40 | T ptr; 41 | free_fn_t free_fn; 42 | }; 43 | #endif 44 | 45 | #endif /* !TEST_H */ 46 | -------------------------------------------------------------------------------- /tsapi/synth.h: -------------------------------------------------------------------------------- 1 | /* vim:set sw=8 ts=8 noet: */ 2 | /* 3 | * Copyright (c) 2016-2017 Torchbox Ltd. 4 | * 5 | * Permission is granted to anyone to use this software for any purpose, 6 | * including commercial applications, and to alter it and redistribute it 7 | * freely. This software is provided 'as-is', without any express or implied 8 | * warranty. 9 | */ 10 | 11 | #ifndef SYNTH_H 12 | #define SYNTH_H 13 | 14 | #include 15 | 16 | #include 17 | 18 | /* 19 | * Simple API for sending synthetic replies, used in various places. 20 | */ 21 | 22 | typedef struct synth synth_t; 23 | 24 | synth_t *synth_new(int status, const char *reason); 25 | void synth_free(synth_t *); 26 | void synth_add_header(synth_t *, const char *hdr, const char *fmt, ...); 27 | void synth_vadd_header(synth_t *, const char *hdr, 28 | const char *fmt, va_list); 29 | void synth_set_body(synth_t *, const char *body); 30 | void synth_intercept(synth_t *, TSHttpTxn); 31 | 32 | #endif /* !SYNTH_H */ 33 | -------------------------------------------------------------------------------- /api/watcher.h: -------------------------------------------------------------------------------- 1 | /* vim:set sw=8 ts=8 noet: */ 2 | /* 3 | * Copyright (c) 2016-2017 Torchbox Ltd. 4 | * 5 | * Permission is granted to anyone to use this software for any purpose, 6 | * including commercial applications, and to alter it and redistribute it 7 | * freely. This software is provided 'as-is', without any express or implied 8 | * warranty. 9 | */ 10 | 11 | #ifndef WATCHER_H 12 | #define WATCHER_H 13 | 14 | #include 15 | 16 | #include "api.h" 17 | 18 | struct k8s_config; 19 | typedef struct watcher watcher_t; 20 | 21 | watcher_t *watcher_create(struct k8s_config *, cluster_t *cluster); 22 | void watcher_free(watcher_t *); 23 | int watcher_run(watcher_t *); 24 | void watcher_set_callback(watcher_t *, cluster_callback_t, void *); 25 | int watcher_set_client_tls(watcher_t *, const char *keyfile, const char *certfile); 26 | int watcher_set_client_cafile(watcher_t *, const char *cafile); 27 | int watcher_set_client_token(watcher_t *, const char *token); 28 | 29 | #endif /* !WATCHER_H */ 30 | -------------------------------------------------------------------------------- /contrib/brotli/enc/literal_cost.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Google Inc. All Rights Reserved. 2 | 3 | Distributed under MIT license. 4 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 5 | */ 6 | 7 | /* Literal cost model to allow backward reference replacement to be efficient. 8 | */ 9 | 10 | #ifndef BROTLI_ENC_LITERAL_COST_H_ 11 | #define BROTLI_ENC_LITERAL_COST_H_ 12 | 13 | #include 14 | #include "./port.h" 15 | 16 | #if defined(__cplusplus) || defined(c_plusplus) 17 | extern "C" { 18 | #endif 19 | 20 | /* Estimates how many bits the literals in the interval [pos, pos + len) in the 21 | ring-buffer (data, mask) will take entropy coded and writes these estimates 22 | to the cost[0..len) array. */ 23 | BROTLI_INTERNAL void BrotliEstimateBitCostsForLiterals( 24 | size_t pos, size_t len, size_t mask, const uint8_t *data, float *cost); 25 | 26 | #if defined(__cplusplus) || defined(c_plusplus) 27 | } /* extern "C" */ 28 | #endif 29 | 30 | #endif /* BROTLI_ENC_LITERAL_COST_H_ */ 31 | -------------------------------------------------------------------------------- /tests/ingress-no-host.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "creationTimestamp": "2017-04-26T01:34:08Z", 6 | "generation": 3, 7 | "name": "echoheaders", 8 | "namespace": "default", 9 | "resourceVersion": "7475305", 10 | "selfLink": "/apis/extensions/v1beta1/namespaces/default/ingresses/echoheaders", 11 | "uid": "71152265-2a20-11e7-a408-4201ac1fd809" 12 | }, 13 | "spec": { 14 | "rules": [ 15 | { 16 | "http": { 17 | "paths": [ 18 | { 19 | "backend": { 20 | "serviceName": "echoheaders", 21 | "servicePort": "http" 22 | } 23 | } 24 | ] 25 | } 26 | } 27 | ] 28 | }, 29 | "status": { 30 | "loadBalancer": {} 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /contrib/brotli/enc/utf8_util.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Google Inc. All Rights Reserved. 2 | 3 | Distributed under MIT license. 4 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 5 | */ 6 | 7 | /* Heuristics for deciding about the UTF8-ness of strings. */ 8 | 9 | #ifndef BROTLI_ENC_UTF8_UTIL_H_ 10 | #define BROTLI_ENC_UTF8_UTIL_H_ 11 | 12 | #include 13 | #include "./port.h" 14 | 15 | #if defined(__cplusplus) || defined(c_plusplus) 16 | extern "C" { 17 | #endif 18 | 19 | static const double kMinUTF8Ratio = 0.75; 20 | 21 | /* Returns 1 if at least min_fraction of the bytes between pos and 22 | pos + length in the (data, mask) ring-buffer is UTF8-encoded, otherwise 23 | returns 0. */ 24 | BROTLI_INTERNAL BROTLI_BOOL BrotliIsMostlyUTF8( 25 | const uint8_t* data, const size_t pos, const size_t mask, 26 | const size_t length, const double min_fraction); 27 | 28 | #if defined(__cplusplus) || defined(c_plusplus) 29 | } /* extern "C" */ 30 | #endif 31 | 32 | #endif /* BROTLI_ENC_UTF8_UTIL_H_ */ 33 | -------------------------------------------------------------------------------- /tests/e2e/007-domain-access-list/run.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # vim:set sw=8 ts=8 noet: 3 | 4 | expect_output() { 5 | if echo "$output" | egrep -q "$@"; then 6 | return 0 7 | else 8 | echo "Failed: output did not include test string: [$*]" 9 | echo "Test output: [$output]" 10 | exit 1 11 | fi 12 | } 13 | 14 | # This request should be allowed. 15 | printf '.' 16 | output=$(curl 2>&1 -vsS --resolve echoheaders.test:58080:127.0.0.1 \ 17 | http://echoheaders.test:58080/this-is-a-test) 18 | expect_output "Request path: /this-is-a-test" 19 | expect_output 'HTTP/[012.]* 200' 20 | 21 | # And this one 22 | printf '.' 23 | output=$(curl 2>&1 -vsS --resolve www.echoheaders.test:58080:127.0.0.1 \ 24 | http://www.echoheaders.test:58080/this-is-a-test) 25 | expect_output "Request path: /this-is-a-test" 26 | expect_output 'HTTP/[012.]* 200' 27 | 28 | # But not this one 29 | printf '.' 30 | output=$(curl 2>&1 -vsS --resolve notechoheaders.test:58080:127.0.0.1 \ 31 | http://notechoheaders.test:58080/this-is-a-test) 32 | expect_output 'HTTP/[012.]* 404' 33 | -------------------------------------------------------------------------------- /tests/e2e/003-caching/resources/ingress.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "name": "echoheaders", 6 | "namespace": "default", 7 | "annotations": { 8 | "ingress.kubernetes.io/ssl-redirect": "false" 9 | } 10 | }, 11 | "spec": { 12 | "rules": [ 13 | { 14 | "host": "echoheaders.test", 15 | "http": { 16 | "paths": [ 17 | { 18 | "backend": { 19 | "serviceName": "echoheaders", 20 | "servicePort": "http" 21 | } 22 | } 23 | ] 24 | } 25 | } 26 | ], 27 | "tls": [ 28 | { 29 | "hosts": [ 30 | "echoheaders.test" 31 | ], 32 | "secretName": "tls-test" 33 | } 34 | ] 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/secret-htauth.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "data": { 4 | "auth": "ZGVzdGVzdDo3eUpoNUNDZ0R6VlNjCm1kNXRlc3Q6JDEkYWJjZDEyMzQkNHBSRFpFZG1nNmpnM1A3aDBsM2lyMQpiZnRlc3Q6JDJhJDA0JDFxeTJpQmQ1MnFCTWdqUkRPVUFZRE9OalZ6bm9GdjFpZy9rUWJjbDE3Q1RCeDJlTnZzNERxCnNoYTI1NnRlc3Q6JDUkYWJjZDEyMzQkMll1M2NqR0dCbFRELm1XRjFicWtMV0NTMTM0UmNSWjNxNldYL2RDQ0xDQQpzaGE1MTJ0ZXN0OiQ2JGFiY2QxMjM0JHk1YlZiN0Q3TC5kUmVvTjUyZy5kOGd3elJrYnJteW1UMGE4T2p4c0VBaXA5V1JBU1ZlSlBVL3lSVFpjMlA3cVZ3Z0RJVm04bkVmVUVSRnlNb0l6Yi8vCnNoYXRlc3Q6e1NIQX01dFE3NCtvOWYvOU04cWcyUnliMTRCZGFJN0E9CnNzaGF0ZXN0OntTU0hBfThld2VvcDB2N1RORitERTAwWnNYQnlhTDhid2lQQzM3CnBsYWludGVzdDp7UExBSU59cGxhaW50ZXN0Cg==" 5 | }, 6 | "kind": "Secret", 7 | "metadata": { 8 | "creationTimestamp": "2017-04-28T04:23:12Z", 9 | "name": "authtest", 10 | "namespace": "default", 11 | "resourceVersion": "3210241", 12 | "selfLink": "/api/v1/namespaces/default/secrets/authtest", 13 | "uid": "6494a9ac-2bca-11e7-aa46-4201ac1fd808" 14 | }, 15 | "type": "Opaque" 16 | } 17 | -------------------------------------------------------------------------------- /tests/e2e/002-tls/resources/ingress-tls10.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "name": "echoheaders-tls10", 6 | "namespace": "default", 7 | "annotations": { 8 | "ingress.kubernetes.io/tls-minimum-version": "1.0" 9 | } 10 | }, 11 | "spec": { 12 | "rules": [ 13 | { 14 | "host": "tls10.echoheaders.test", 15 | "http": { 16 | "paths": [ 17 | { 18 | "backend": { 19 | "serviceName": "echoheaders", 20 | "servicePort": "http" 21 | } 22 | } 23 | ] 24 | } 25 | } 26 | ], 27 | "tls": [ 28 | { 29 | "hosts": [ 30 | "tls10.echoheaders.test" 31 | ], 32 | "secretName": "tls-test" 33 | } 34 | ] 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/e2e/002-tls/resources/ingress-tls11.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "name": "echoheaders-tls11", 6 | "namespace": "default", 7 | "annotations": { 8 | "ingress.kubernetes.io/tls-minimum-version": "1.1" 9 | } 10 | }, 11 | "spec": { 12 | "rules": [ 13 | { 14 | "host": "tls11.echoheaders.test", 15 | "http": { 16 | "paths": [ 17 | { 18 | "backend": { 19 | "serviceName": "echoheaders", 20 | "servicePort": "http" 21 | } 22 | } 23 | ] 24 | } 25 | } 26 | ], 27 | "tls": [ 28 | { 29 | "hosts": [ 30 | "tls11.echoheaders.test" 31 | ], 32 | "secretName": "tls-test" 33 | } 34 | ] 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/e2e/002-tls/resources/ingress-tls12.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "name": "echoheaders-tls12", 6 | "namespace": "default", 7 | "annotations": { 8 | "ingress.kubernetes.io/tls-minimum-version": "1.2" 9 | } 10 | }, 11 | "spec": { 12 | "rules": [ 13 | { 14 | "host": "tls12.echoheaders.test", 15 | "http": { 16 | "paths": [ 17 | { 18 | "backend": { 19 | "serviceName": "echoheaders", 20 | "servicePort": "http" 21 | } 22 | } 23 | ] 24 | } 25 | } 26 | ], 27 | "tls": [ 28 | { 29 | "hosts": [ 30 | "tls12.echoheaders.test" 31 | ], 32 | "secretName": "tls-test" 33 | } 34 | ] 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /contrib/brotli/Makefile.in: -------------------------------------------------------------------------------- 1 | # vim:set sw=8 ts=8 noet: 2 | # 3 | # Copyright (c) 2016-2017 Torchbox Ltd. 4 | # 5 | # Permission is granted to anyone to use this software for any purpose, 6 | # including commercial applications, and to alter it and redistribute it 7 | # freely. This software is provided 'as-is', without any express or implied 8 | # warranty. 9 | 10 | VPATH= @top_srcdir@/contrib/brotli/common \ 11 | @top_srcdir@/contrib/brotli/enc 12 | SRCS= backward_references.c backward_references_hq.c bit_cost.c \ 13 | block_splitter.c brotli_bit_stream.c cluster.c \ 14 | compress_fragment.c compress_fragment_two_pass.c dictionary.c \ 15 | dictionary_hash.c encode.c entropy_encode.c histogram.c \ 16 | literal_cost.c memory.c metablock.c static_dict.c utf8_util.c 17 | OBJS= ${SRCS:.c=.o} 18 | 19 | CC= @CC@ 20 | CXX= @CXX@ 21 | CPPFLAGS= @CPPFLAGS@ -I@top_srcdir@/contrib/brotli/include 22 | CFLAGS= @TS_CFLAGS@ @CFLAGS@ 23 | 24 | libbrotli.a: ${OBJS} 25 | ar rcu libbrotli.a ${OBJS} 26 | 27 | %.o: %.c 28 | ${CC} ${CPPFLAGS} ${CFLAGS} -c $< 29 | 30 | clean: 31 | rm -f ${OBJS} libbrotli.a 32 | -------------------------------------------------------------------------------- /tests/ingress-basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "annotations": { 6 | }, 7 | "creationTimestamp": "2017-04-26T01:34:08Z", 8 | "generation": 3, 9 | "name": "echoheaders", 10 | "namespace": "default", 11 | "resourceVersion": "7475305", 12 | "selfLink": "/apis/extensions/v1beta1/namespaces/default/ingresses/echoheaders", 13 | "uid": "71152265-2a20-11e7-a408-4201ac1fd809" 14 | }, 15 | "spec": { 16 | "rules": [ 17 | { 18 | "host": "echoheaders.gce.t6x.uk", 19 | "http": { 20 | "paths": [ 21 | { 22 | "backend": { 23 | "serviceName": "echoheaders", 24 | "servicePort": "http" 25 | } 26 | } 27 | ] 28 | } 29 | } 30 | ] 31 | }, 32 | "status": { 33 | "loadBalancer": {} 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /auth/auth.h: -------------------------------------------------------------------------------- 1 | /* vim:set sw=8 ts=8 noet: */ 2 | /* 3 | * Copyright (c) 2016-2017 Torchbox Ltd. 4 | * 5 | * Permission is granted to anyone to use this software for any purpose, 6 | * including commercial applications, and to alter it and redistribute it 7 | * freely. This software is provided 'as-is', without any express or implied 8 | * warranty. 9 | */ 10 | 11 | #ifndef AUTH_H 12 | #define AUTH_H 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include "hash.h" 19 | #include "plugin.h" 20 | #include "remap.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | int auth_check_password(hash_t users, const char *usenam, const char *pass); 27 | int auth_check_basic(const char *hdr, const remap_path_t *); 28 | int auth_check_address(const struct sockaddr *addr, const remap_path_t *); 29 | 30 | int ipv4_in_network(in_addr_t ip, in_addr_t netw, int pfxlen); 31 | int ipv6_in_network(const struct in6_addr *ip, const struct in6_addr *net, 32 | int pfxlen); 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif 37 | 38 | #endif /* !AUTH_H */ 39 | -------------------------------------------------------------------------------- /tests/fileserver.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # vim:set sw=8 ts=8 noet: 3 | # 4 | # This is a trivial HTTP server for use in tests. It only supports GET requests 5 | # and makes no attempt to validate its input or conform to any HTTP 6 | # specification. 7 | 8 | # Travis-CI won't let us remove netcat-openbsd, so instead check for the 9 | # normal version explicitly. 10 | NETCAT=nc 11 | if [ -e /bin/nc.traditional ]; then 12 | NETCAT=/bin/nc.traditional 13 | fi 14 | 15 | if [ -z "$1" ]; then 16 | echo >&2 "usage: $0 " 17 | exit 1 18 | fi 19 | 20 | ncpid=0 21 | 22 | if [ "$1" = "handle" ]; then 23 | read method path version 24 | 25 | while :; do 26 | read line 27 | if echo "$line" | grep -q '^[[:space:]]*$'; then 28 | break 29 | fi 30 | done 31 | 32 | printf 'HTTP/1.0 200 OK\r\n' 33 | printf 'Connection: close\r\n' 34 | printf 'Content-Type: text/plain;charset=UTF-8\r\n' 35 | printf '\r\n' 36 | 37 | cat $2 38 | exit 0 39 | fi 40 | 41 | trap '[ $ncpid != 0 ] && kill $ncpid; exit 0' INT TERM EXIT 0 42 | 43 | while :; do 44 | $NETCAT -l -p 48080 -c "$0 handle $2" "$1" & ncpid=$! 45 | wait $ncpid 46 | ncpid=0 47 | done 48 | -------------------------------------------------------------------------------- /tests/e2e/005-auth/resources/ingress-all-ipbad.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "name": "echoheaders-all-ipbad", 6 | "namespace": "default", 7 | "annotations": { 8 | "ingress.kubernetes.io/auth-secret": "authtest", 9 | "ingress.kubernetes.io/auth-realm": "auth test", 10 | "ingress.kubernetes.io/auth-type": "basic", 11 | "ingress.kubernetes.io/whitelist-source-range": "8.8.8.0/24", 12 | "ingress.kubernetes.io/auth-satisfy": "all" 13 | } 14 | }, 15 | "spec": { 16 | "rules": [ 17 | { 18 | "host": "all-ipbad.echoheaders.test", 19 | "http": { 20 | "paths": [ 21 | { 22 | "backend": { 23 | "serviceName": "echoheaders", 24 | "servicePort": "http" 25 | } 26 | } 27 | ] 28 | } 29 | } 30 | ] 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/e2e/005-auth/resources/ingress-all-ipok.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "name": "echoheaders-all-ipok", 6 | "namespace": "default", 7 | "annotations": { 8 | "ingress.kubernetes.io/auth-secret": "authtest", 9 | "ingress.kubernetes.io/auth-realm": "auth test", 10 | "ingress.kubernetes.io/auth-type": "basic", 11 | "ingress.kubernetes.io/whitelist-source-range": "127.0.0.1/32", 12 | "ingress.kubernetes.io/auth-satisfy": "all" 13 | } 14 | }, 15 | "spec": { 16 | "rules": [ 17 | { 18 | "host": "all-ipok.echoheaders.test", 19 | "http": { 20 | "paths": [ 21 | { 22 | "backend": { 23 | "serviceName": "echoheaders", 24 | "servicePort": "http" 25 | } 26 | } 27 | ] 28 | } 29 | } 30 | ] 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/e2e/005-auth/resources/ingress-any-ipbad.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "name": "echoheaders-any-ipbad", 6 | "namespace": "default", 7 | "annotations": { 8 | "ingress.kubernetes.io/auth-secret": "authtest", 9 | "ingress.kubernetes.io/auth-realm": "auth test", 10 | "ingress.kubernetes.io/auth-type": "basic", 11 | "ingress.kubernetes.io/whitelist-source-range": "8.8.8.0/24", 12 | "ingress.kubernetes.io/auth-satisfy": "any" 13 | } 14 | }, 15 | "spec": { 16 | "rules": [ 17 | { 18 | "host": "any-ipbad.echoheaders.test", 19 | "http": { 20 | "paths": [ 21 | { 22 | "backend": { 23 | "serviceName": "echoheaders", 24 | "servicePort": "http" 25 | } 26 | } 27 | ] 28 | } 29 | } 30 | ] 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/e2e/005-auth/resources/ingress-any-ipok.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "name": "echoheaders-any-ipok", 6 | "namespace": "default", 7 | "annotations": { 8 | "ingress.kubernetes.io/auth-secret": "authtest", 9 | "ingress.kubernetes.io/auth-realm": "auth test", 10 | "ingress.kubernetes.io/auth-type": "basic", 11 | "ingress.kubernetes.io/whitelist-source-range": "127.0.0.1/32", 12 | "ingress.kubernetes.io/auth-satisfy": "any" 13 | } 14 | }, 15 | "spec": { 16 | "rules": [ 17 | { 18 | "host": "any-ipok.echoheaders.test", 19 | "http": { 20 | "paths": [ 21 | { 22 | "backend": { 23 | "serviceName": "echoheaders", 24 | "servicePort": "http" 25 | } 26 | } 27 | ] 28 | } 29 | } 30 | ] 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/e2e/006-cors/resources/ingress-private.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "name": "echoheaders-private", 6 | "namespace": "default", 7 | "annotations": { 8 | "ingress.kubernetes.io/enable-cors": "true", 9 | "ingress.kubernetes.io/cors-origins": "http://example.com", 10 | "ingress.kubernetes.io/cors-credentials": "true", 11 | "ingress.kubernetes.io/cors-headers": "X-CustomHeader", 12 | "ingress.kubernetes.io/cors-methods": "PUT, DELETE" 13 | } 14 | }, 15 | "spec": { 16 | "rules": [ 17 | { 18 | "host": "private.echoheaders.test", 19 | "http": { 20 | "paths": [ 21 | { 22 | "backend": { 23 | "serviceName": "echoheaders", 24 | "servicePort": "http" 25 | } 26 | } 27 | ] 28 | } 29 | } 30 | ] 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/ingress-class2.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "annotations": { 6 | "kubernetes.io/ingress.class": "nginx" 7 | }, 8 | "creationTimestamp": "2017-04-26T01:34:08Z", 9 | "generation": 3, 10 | "name": "echoheaders", 11 | "namespace": "default", 12 | "resourceVersion": "7475305", 13 | "selfLink": "/apis/extensions/v1beta1/namespaces/default/ingresses/echoheaders", 14 | "uid": "71152265-2a20-11e7-a408-4201ac1fd809" 15 | }, 16 | "spec": { 17 | "rules": [ 18 | { 19 | "host": "echoheaders.gce.t6x.uk", 20 | "http": { 21 | "paths": [ 22 | { 23 | "backend": { 24 | "serviceName": "echoheaders", 25 | "servicePort": "http" 26 | } 27 | } 28 | ] 29 | } 30 | } 31 | ] 32 | }, 33 | "status": { 34 | "loadBalancer": {} 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/ingress-app-root.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "annotations": { 6 | "ingress.kubernetes.io/app-root": "/app/" 7 | }, 8 | "creationTimestamp": "2017-04-26T01:34:08Z", 9 | "generation": 3, 10 | "name": "echoheaders", 11 | "namespace": "default", 12 | "resourceVersion": "7475305", 13 | "selfLink": "/apis/extensions/v1beta1/namespaces/default/ingresses/echoheaders", 14 | "uid": "71152265-2a20-11e7-a408-4201ac1fd809" 15 | }, 16 | "spec": { 17 | "rules": [ 18 | { 19 | "host": "echoheaders.gce.t6x.uk", 20 | "http": { 21 | "paths": [ 22 | { 23 | "backend": { 24 | "serviceName": "echoheaders", 25 | "servicePort": "http" 26 | } 27 | } 28 | ] 29 | } 30 | } 31 | ] 32 | }, 33 | "status": { 34 | "loadBalancer": {} 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/ingress-class1.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "annotations": { 6 | "kubernetes.io/ingress.class": "trafficserver" 7 | }, 8 | "creationTimestamp": "2017-04-26T01:34:08Z", 9 | "generation": 3, 10 | "name": "echoheaders", 11 | "namespace": "default", 12 | "resourceVersion": "7475305", 13 | "selfLink": "/apis/extensions/v1beta1/namespaces/default/ingresses/echoheaders", 14 | "uid": "71152265-2a20-11e7-a408-4201ac1fd809" 15 | }, 16 | "spec": { 17 | "rules": [ 18 | { 19 | "host": "echoheaders.gce.t6x.uk", 20 | "http": { 21 | "paths": [ 22 | { 23 | "backend": { 24 | "serviceName": "echoheaders", 25 | "servicePort": "http" 26 | } 27 | } 28 | ] 29 | } 30 | } 31 | ] 32 | }, 33 | "status": { 34 | "loadBalancer": {} 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/ingress-cors1.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "annotations": { 6 | "ingress.kubernetes.io/enable-cors": "true" 7 | }, 8 | "creationTimestamp": "2017-04-26T01:34:08Z", 9 | "generation": 3, 10 | "name": "echoheaders", 11 | "namespace": "default", 12 | "resourceVersion": "7475305", 13 | "selfLink": "/apis/extensions/v1beta1/namespaces/default/ingresses/echoheaders", 14 | "uid": "71152265-2a20-11e7-a408-4201ac1fd809" 15 | }, 16 | "spec": { 17 | "rules": [ 18 | { 19 | "host": "echoheaders.gce.t6x.uk", 20 | "http": { 21 | "paths": [ 22 | { 23 | "backend": { 24 | "serviceName": "echoheaders", 25 | "servicePort": "http" 26 | } 27 | } 28 | ] 29 | } 30 | } 31 | ] 32 | }, 33 | "status": { 34 | "loadBalancer": {} 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/ingress-force-tls.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "annotations": { 6 | "ingress.kubernetes.io/force-ssl-redirect": "true" 7 | }, 8 | "creationTimestamp": "2017-04-26T01:34:08Z", 9 | "generation": 3, 10 | "name": "echoheaders", 11 | "namespace": "default", 12 | "resourceVersion": "7475305", 13 | "selfLink": "/apis/extensions/v1beta1/namespaces/default/ingresses/echoheaders", 14 | "uid": "71152265-2a20-11e7-a408-4201ac1fd809" 15 | }, 16 | "spec": { 17 | "rules": [ 18 | { 19 | "host": "echoheaders.gce.t6x.uk", 20 | "http": { 21 | "paths": [ 22 | { 23 | "backend": { 24 | "serviceName": "echoheaders", 25 | "servicePort": "http" 26 | } 27 | } 28 | ] 29 | } 30 | } 31 | ] 32 | }, 33 | "status": { 34 | "loadBalancer": {} 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/ingress-ignore-params.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "annotations": { 6 | "ingress.kubernetes.io/cache-ignore-query-params": "foo b*" 7 | }, 8 | "creationTimestamp": "2017-04-26T01:34:08Z", 9 | "generation": 3, 10 | "name": "echoheaders", 11 | "namespace": "default", 12 | "resourceVersion": "7475305", 13 | "selfLink": "/apis/extensions/v1beta1/namespaces/default/ingresses/echoheaders", 14 | "uid": "71152265-2a20-11e7-a408-4201ac1fd809" 15 | }, 16 | "spec": { 17 | "rules": [ 18 | { 19 | "host": "echoheaders.gce.t6x.uk", 20 | "http": { 21 | "paths": [ 22 | { 23 | "backend": { 24 | "serviceName": "echoheaders", 25 | "servicePort": "http" 26 | } 27 | } 28 | ] 29 | } 30 | } 31 | ] 32 | }, 33 | "status": { 34 | "loadBalancer": {} 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/ingress-whitelist-params.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "annotations": { 6 | "ingress.kubernetes.io/cache-whitelist-query-params": "*x*" 7 | }, 8 | "creationTimestamp": "2017-04-26T01:34:08Z", 9 | "generation": 3, 10 | "name": "echoheaders", 11 | "namespace": "default", 12 | "resourceVersion": "7475305", 13 | "selfLink": "/apis/extensions/v1beta1/namespaces/default/ingresses/echoheaders", 14 | "uid": "71152265-2a20-11e7-a408-4201ac1fd809" 15 | }, 16 | "spec": { 17 | "rules": [ 18 | { 19 | "host": "echoheaders.gce.t6x.uk", 20 | "http": { 21 | "paths": [ 22 | { 23 | "backend": { 24 | "serviceName": "echoheaders", 25 | "servicePort": "http" 26 | } 27 | } 28 | ] 29 | } 30 | } 31 | ] 32 | }, 33 | "status": { 34 | "loadBalancer": {} 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/e2e/007-domain-access-list/resources/ingress.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "name": "echoheaders", 6 | "namespace": "default" 7 | }, 8 | "spec": { 9 | "rules": [ 10 | { 11 | "host": "echoheaders.test", 12 | "http": { 13 | "paths": [ 14 | { 15 | "backend": { 16 | "serviceName": "echoheaders", 17 | "servicePort": "http" 18 | } 19 | } 20 | ] 21 | } 22 | }, 23 | { 24 | "host": "www.echoheaders.test", 25 | "http": { 26 | "paths": [ 27 | { 28 | "backend": { 29 | "serviceName": "echoheaders", 30 | "servicePort": "http" 31 | } 32 | } 33 | ] 34 | } 35 | } 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tests/endpoints.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "v1", 3 | "kind": "Endpoints", 4 | "metadata": { 5 | "creationTimestamp": "2017-04-26T01:34:08Z", 6 | "name": "echoheaders", 7 | "namespace": "default", 8 | "resourceVersion": "3207778", 9 | "selfLink": "/api/v1/namespaces/default/endpoints/echoheaders", 10 | "uid": "710d248e-2a20-11e7-a408-4201ac1fd809" 11 | }, 12 | "subsets": [ 13 | { 14 | "addresses": [ 15 | { 16 | "ip": "172.28.35.130", 17 | "nodeName": "worker-bd78", 18 | "targetRef": { 19 | "kind": "Pod", 20 | "name": "echoheaders-2895977578-tvqx4", 21 | "namespace": "default", 22 | "resourceVersion": "3207776", 23 | "uid": "bcdf7abd-2b11-11e7-a408-4201ac1fd809" 24 | } 25 | } 26 | ], 27 | "ports": [ 28 | { 29 | "name": "http", 30 | "port": 8080, 31 | "protocol": "TCP" 32 | } 33 | ] 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /tests/ingress-rewrite-target.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "annotations": { 6 | "ingress.kubernetes.io/rewrite-target": "/app" 7 | }, 8 | "creationTimestamp": "2017-04-26T01:34:08Z", 9 | "generation": 3, 10 | "name": "echoheaders", 11 | "namespace": "default", 12 | "resourceVersion": "7475305", 13 | "selfLink": "/apis/extensions/v1beta1/namespaces/default/ingresses/echoheaders", 14 | "uid": "71152265-2a20-11e7-a408-4201ac1fd809" 15 | }, 16 | "spec": { 17 | "rules": [ 18 | { 19 | "host": "echoheaders.gce.t6x.uk", 20 | "http": { 21 | "paths": [ 22 | { 23 | "path": "/foo", 24 | "backend": { 25 | "serviceName": "echoheaders", 26 | "servicePort": "http" 27 | } 28 | } 29 | ] 30 | } 31 | } 32 | ] 33 | }, 34 | "status": { 35 | "loadBalancer": {} 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/ingress-secure-backends.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "annotations": { 6 | "ingress.kubernetes.io/secure-backends": "true" 7 | }, 8 | "creationTimestamp": "2017-04-26T01:34:08Z", 9 | "generation": 3, 10 | "name": "echoheaders", 11 | "namespace": "default", 12 | "resourceVersion": "7475305", 13 | "selfLink": "/apis/extensions/v1beta1/namespaces/default/ingresses/echoheaders", 14 | "uid": "71152265-2a20-11e7-a408-4201ac1fd809" 15 | }, 16 | "spec": { 17 | "rules": [ 18 | { 19 | "host": "echoheaders.gce.t6x.uk", 20 | "http": { 21 | "paths": [ 22 | { 23 | "path": "/foo", 24 | "backend": { 25 | "serviceName": "echoheaders", 26 | "servicePort": "http" 27 | } 28 | } 29 | ] 30 | } 31 | } 32 | ] 33 | }, 34 | "status": { 35 | "loadBalancer": {} 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /contrib/brotli/enc/cluster.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Google Inc. All Rights Reserved. 2 | 3 | Distributed under MIT license. 4 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 5 | */ 6 | 7 | /* Functions for clustering similar histograms together. */ 8 | 9 | #ifndef BROTLI_ENC_CLUSTER_H_ 10 | #define BROTLI_ENC_CLUSTER_H_ 11 | 12 | #include 13 | #include "./histogram.h" 14 | #include "./memory.h" 15 | #include "./port.h" 16 | 17 | #if defined(__cplusplus) || defined(c_plusplus) 18 | extern "C" { 19 | #endif 20 | 21 | typedef struct HistogramPair { 22 | uint32_t idx1; 23 | uint32_t idx2; 24 | double cost_combo; 25 | double cost_diff; 26 | } HistogramPair; 27 | 28 | #define CODE(X) /* Declaration */; 29 | 30 | #define FN(X) X ## Literal 31 | #include "./cluster_inc.h" /* NOLINT(build/include) */ 32 | #undef FN 33 | 34 | #define FN(X) X ## Command 35 | #include "./cluster_inc.h" /* NOLINT(build/include) */ 36 | #undef FN 37 | 38 | #define FN(X) X ## Distance 39 | #include "./cluster_inc.h" /* NOLINT(build/include) */ 40 | #undef FN 41 | 42 | #undef CODE 43 | 44 | #if defined(__cplusplus) || defined(c_plusplus) 45 | } /* extern "C" */ 46 | #endif 47 | 48 | #endif /* BROTLI_ENC_CLUSTER_H_ */ 49 | -------------------------------------------------------------------------------- /tests/ingress-auth-address.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "annotations": { 6 | "ingress.kubernetes.io/whitelist-source-range": "127.0.0.0/8" 7 | }, 8 | "creationTimestamp": "2017-04-26T01:34:08Z", 9 | "generation": 3, 10 | "name": "echoheaders", 11 | "namespace": "default", 12 | "resourceVersion": "7475305", 13 | "selfLink": "/apis/extensions/v1beta1/namespaces/default/ingresses/echoheaders", 14 | "uid": "71152265-2a20-11e7-a408-4201ac1fd809" 15 | }, 16 | "spec": { 17 | "rules": [ 18 | { 19 | "host": "echoheaders.gce.t6x.uk", 20 | "http": { 21 | "paths": [ 22 | { 23 | "path": "/foo", 24 | "backend": { 25 | "serviceName": "echoheaders", 26 | "servicePort": "http" 27 | } 28 | } 29 | ] 30 | } 31 | } 32 | ] 33 | }, 34 | "status": { 35 | "loadBalancer": {} 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /contrib/brotli/enc/block_encoder_inc.h: -------------------------------------------------------------------------------- 1 | /* NOLINT(build/header_guard) */ 2 | /* Copyright 2014 Google Inc. All Rights Reserved. 3 | 4 | Distributed under MIT license. 5 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 6 | */ 7 | 8 | /* template parameters: FN */ 9 | 10 | #define HistogramType FN(Histogram) 11 | 12 | /* Creates entropy codes for all block types and stores them to the bit 13 | stream. */ 14 | static void FN(BuildAndStoreEntropyCodes)(MemoryManager* m, BlockEncoder* self, 15 | const HistogramType* histograms, const size_t histograms_size, 16 | HuffmanTree* tree, size_t* storage_ix, uint8_t* storage) { 17 | const size_t alphabet_size = self->alphabet_size_; 18 | const size_t table_size = histograms_size * alphabet_size; 19 | self->depths_ = BROTLI_ALLOC(m, uint8_t, table_size); 20 | self->bits_ = BROTLI_ALLOC(m, uint16_t, table_size); 21 | if (BROTLI_IS_OOM(m)) return; 22 | 23 | { 24 | size_t i; 25 | for (i = 0; i < histograms_size; ++i) { 26 | size_t ix = i * alphabet_size; 27 | BuildAndStoreHuffmanTree(&histograms[i].data_[0], alphabet_size, tree, 28 | &self->depths_[ix], &self->bits_[ix], storage_ix, storage); 29 | } 30 | } 31 | } 32 | 33 | #undef HistogramType 34 | -------------------------------------------------------------------------------- /tests/ingress-ignore-whitelist-params.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "annotations": { 6 | "ingress.kubernetes.io/cache-ignore-query-params": "fox b*", 7 | "ingress.kubernetes.io/cache-whitelist-query-params": "*x*" 8 | }, 9 | "creationTimestamp": "2017-04-26T01:34:08Z", 10 | "generation": 3, 11 | "name": "echoheaders", 12 | "namespace": "default", 13 | "resourceVersion": "7475305", 14 | "selfLink": "/apis/extensions/v1beta1/namespaces/default/ingresses/echoheaders", 15 | "uid": "71152265-2a20-11e7-a408-4201ac1fd809" 16 | }, 17 | "spec": { 18 | "rules": [ 19 | { 20 | "host": "echoheaders.gce.t6x.uk", 21 | "http": { 22 | "paths": [ 23 | { 24 | "backend": { 25 | "serviceName": "echoheaders", 26 | "servicePort": "http" 27 | } 28 | } 29 | ] 30 | } 31 | } 32 | ] 33 | }, 34 | "status": { 35 | "loadBalancer": {} 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /docs/classes.md: -------------------------------------------------------------------------------- 1 | # Using multiple Ingress controllers 2 | 3 | If you want to deploy more than one Ingress controller inside a cluster (for 4 | example, to test the TS Ingress controller before deploying it properly), you 5 | will need to use Ingress classes to control which resources should be handled 6 | by which controller. 7 | 8 | The Ingress class is set as an annotation on the resource: 9 | 10 | ``` 11 | metadata: 12 | annotations: 13 | kubernetes.io/ingress.class: "trafficserver" 14 | ``` 15 | 16 | The TS Ingress controller will handle any Ingress resource which does not have 17 | an Ingress class set, or where the Ingress class is set to "trafficserver". 18 | 19 | To change the Ingress classes that TS will handle, set `ingress_classes` in 20 | `kubernetes.config` (or the `$TS_INGRESS_CLASSES` environment variable) to a 21 | whitespace-separate list of values, e.g. `"trafficserver ts-staging"`. This 22 | can be used to run multiple copies of the TS Ingress controller in one cluster. 23 | If you do this, the `trafficserver` class will not be handled unless you 24 | explicitly include it in the list. 25 | 26 | For more information, see 27 | [Using Multiple Ingress Controller](https://github.com/nginxinc/kubernetes-ingress/tree/master/examples/multiple-ingress-controllers) 28 | in the Kubernetes documentation. 29 | 30 | 31 | -------------------------------------------------------------------------------- /trafficserver-ds.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: trafficserver 5 | namespace: kube-system 6 | spec: 7 | selector: 8 | app: trafficserver 9 | ports: 10 | - name: http 11 | protocol: TCP 12 | port: 80 13 | targetPort: 8080 14 | - name: https 15 | protocol: TCP 16 | port: 443 17 | targetPort: 8443 18 | 19 | --- 20 | 21 | apiVersion: extensions/v1beta1 22 | kind: DaemonSet 23 | metadata: 24 | name: trafficserver 25 | namespace: kube-system 26 | labels: 27 | app: trafficserver 28 | spec: 29 | selector: 30 | matchLabels: 31 | app: trafficserver 32 | template: 33 | metadata: 34 | namespace: kube-system 35 | labels: 36 | app: trafficserver 37 | spec: 38 | nodeSelector: 39 | type: head 40 | terminationGracePeriodSeconds: 60 41 | containers: 42 | - name: trafficserver 43 | image: docker.io/torchbox/trafficserver-ingress-controller:latest 44 | imagePullPolicy: Always 45 | ports: 46 | - containerPort: 8080 47 | hostPort: 80 48 | - containerPort: 8443 49 | hostPort: 443 50 | volumeMounts: 51 | - name: ts-storage 52 | mountPath: /var/lib/trafficserver 53 | volumes: 54 | - name: ts-storage 55 | emptyDir: {} 56 | -------------------------------------------------------------------------------- /tests/ingress-auth-basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "annotations": { 6 | "ingress.kubernetes.io/auth-realm": "Test authentication", 7 | "ingress.kubernetes.io/auth-secret": "authtest", 8 | "ingress.kubernetes.io/auth-type": "basic" 9 | }, 10 | "creationTimestamp": "2017-04-26T01:34:08Z", 11 | "generation": 3, 12 | "name": "echoheaders", 13 | "namespace": "default", 14 | "resourceVersion": "7475305", 15 | "selfLink": "/apis/extensions/v1beta1/namespaces/default/ingresses/echoheaders", 16 | "uid": "71152265-2a20-11e7-a408-4201ac1fd809" 17 | }, 18 | "spec": { 19 | "rules": [ 20 | { 21 | "host": "echoheaders.gce.t6x.uk", 22 | "http": { 23 | "paths": [ 24 | { 25 | "path": "/foo", 26 | "backend": { 27 | "serviceName": "echoheaders", 28 | "servicePort": "http" 29 | } 30 | } 31 | ] 32 | } 33 | } 34 | ] 35 | }, 36 | "status": { 37 | "loadBalancer": {} 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /contrib/brotli/enc/static_dict.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Google Inc. All Rights Reserved. 2 | 3 | Distributed under MIT license. 4 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 5 | */ 6 | 7 | /* Class to model the static dictionary. */ 8 | 9 | #ifndef BROTLI_ENC_STATIC_DICT_H_ 10 | #define BROTLI_ENC_STATIC_DICT_H_ 11 | 12 | #include "../common/dictionary.h" 13 | #include 14 | #include "./port.h" 15 | 16 | #if defined(__cplusplus) || defined(c_plusplus) 17 | extern "C" { 18 | #endif 19 | 20 | #define BROTLI_MAX_STATIC_DICTIONARY_MATCH_LEN 37 21 | static const uint32_t kInvalidMatch = 0xfffffff; 22 | 23 | /* Matches data against static dictionary words, and for each length l, 24 | for which a match is found, updates matches[l] to be the minimum possible 25 | (distance << 5) + len_code. 26 | Returns 1 if matches have been found, otherwise 0. 27 | Prerequisites: 28 | matches array is at least BROTLI_MAX_STATIC_DICTIONARY_MATCH_LEN + 1 long 29 | all elements are initialized to kInvalidMatch */ 30 | BROTLI_INTERNAL BROTLI_BOOL BrotliFindAllStaticDictionaryMatches( 31 | const BrotliDictionary* dictionary, 32 | const uint8_t* data, size_t min_length, size_t max_length, 33 | uint32_t* matches); 34 | 35 | #if defined(__cplusplus) || defined(c_plusplus) 36 | } /* extern "C" */ 37 | #endif 38 | 39 | #endif /* BROTLI_ENC_STATIC_DICT_H_ */ 40 | -------------------------------------------------------------------------------- /tests/ingress.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "annotations": { 6 | "ingress.kubernetes.io/auth-realm": "test auth", 7 | "ingress.kubernetes.io/auth-secret": "authtest", 8 | "ingress.kubernetes.io/auth-type": "basic", 9 | "ingress.kubernetes.io/rewrite-target": "/dst" 10 | }, 11 | "creationTimestamp": "2017-04-26T01:34:08Z", 12 | "generation": 2, 13 | "name": "echoheaders", 14 | "namespace": "default", 15 | "resourceVersion": "3090663", 16 | "selfLink": "/apis/extensions/v1beta1/namespaces/default/ingresses/echoheaders", 17 | "uid": "71152265-2a20-11e7-a408-4201ac1fd809" 18 | }, 19 | "spec": { 20 | "rules": [ 21 | { 22 | "host": "echoheaders.gce.t6x.uk", 23 | "http": { 24 | "paths": [ 25 | { 26 | "backend": { 27 | "serviceName": "echoheaders", 28 | "servicePort": "http" 29 | }, 30 | "path": "/src" 31 | } 32 | ] 33 | } 34 | } 35 | ] 36 | }, 37 | "status": { 38 | "loadBalancer": {} 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tests/test-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDqjCCApKgAwIBAgIJAIpRudr1K5ijMA0GCSqGSIb3DQEBCwUAMGoxCzAJBgNV 3 | BAYTAkdCMRQwEgYDVQQIDAtPeGZvcmRzaGlyZTESMBAGA1UEBwwJQ2hhcmxidXJ5 4 | MRYwFAYDVQQKDA1Ub3JjaGJveCBMdGQuMRkwFwYDVQQDDBBlY2hvaGVhZGVycy50 5 | ZXN0MB4XDTE3MDUyNjE0NDY0M1oXDTM3MDUyMTE0NDY0M1owajELMAkGA1UEBhMC 6 | R0IxFDASBgNVBAgMC094Zm9yZHNoaXJlMRIwEAYDVQQHDAlDaGFybGJ1cnkxFjAU 7 | BgNVBAoMDVRvcmNoYm94IEx0ZC4xGTAXBgNVBAMMEGVjaG9oZWFkZXJzLnRlc3Qw 8 | ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCl8k1eJWZ2nKaJJGVxvMrb 9 | voYNA/0zbVYnEja+4WR1wbA7KMt1pVVFY45SD5NjRO+NCIVSGB74r99XuwFXU9Dm 10 | DUm5j7UxlmP/bYJhC5nO4A7bPTaapGyjALpsGr2Y7kaQbKKNclZvMRyM07NgXsyL 11 | eC1Owi2iXU0Ja/Zcf1YgtZw/UVJr6Glc8FrPfmp+rZrNZ/f2u/BMiXMBl5uUo8pN 12 | UWDUGkPnv66BRhR88wrr/z1NSFmn/VffEcefOyfDk2nTopzyLr109SfSb7k9kXhc 13 | wctPfAjzsn0f1xbB6qYONI7uqpghJtde/W1Msod6j0xlOzALumwF/g9IEbgWOK/j 14 | AgMBAAGjUzBRMB0GA1UdDgQWBBRkrtEO9RzHO94GwFn6NAuXiEZLFTAfBgNVHSME 15 | GDAWgBRkrtEO9RzHO94GwFn6NAuXiEZLFTAPBgNVHRMBAf8EBTADAQH/MA0GCSqG 16 | SIb3DQEBCwUAA4IBAQBryGAdpsS/Vyayta0s2WhprctZ51jqEd7w2DBXXDRcVNnG 17 | i3vRPzo+BFKtsaSP+zd6W074VuLnz9eqoNtStgj45PeefdJRvbCNE4efnfu1sq5v 18 | SxZY6+xuqbwVCis/OzOP8CtMpl5nBxJhFkP9Vksjip7XcRGMxuFJWliRDvapy/Pz 19 | +RsJQ+kmHYKNRlDStGKrJTjt6Dm+4tAJ2WFeyY+wBQ8jBRnuE9dLr3ruUUknDBww 20 | QvT9ZD3NpLieXiOGmrjuii0FHyeGGuwtSjIwl3uJ3qi5yFZTGvHIN3J19c2Vg1gt 21 | qpEREo/9twtkZ+RbGPAm48YK8bIQOij9wqukxzWy 22 | -----END CERTIFICATE----- 23 | -------------------------------------------------------------------------------- /tsapi/config.h: -------------------------------------------------------------------------------- 1 | /* vim:set sw=8 ts=8 noet: */ 2 | /* 3 | * Copyright (c) 2016-2017 Torchbox Ltd. 4 | * 5 | * Permission is granted to anyone to use this software for any purpose, 6 | * including commercial applications, and to alter it and redistribute it 7 | * freely. This software is provided 'as-is', without any express or implied 8 | * warranty. 9 | */ 10 | 11 | #ifndef CONFIG_H 12 | #define CONFIG_H 13 | 14 | #include "hash.h" 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | /* 21 | * Service account credential files. 22 | */ 23 | #define SA_TOKEN_FILE "/var/run/secrets/kubernetes.io/serviceaccount/token" 24 | #define SA_CACERT_FILE "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" 25 | 26 | typedef struct k8s_config { 27 | char *co_server; 28 | char *co_tls_certfile; 29 | char *co_tls_keyfile; 30 | char *co_tls_cafile; 31 | int co_tls_verify; 32 | char *co_token; 33 | int co_tls; 34 | int co_remap; 35 | hash_t co_classes; 36 | int co_xfp; 37 | char *co_configmap_namespace; 38 | char *co_configmap_name; 39 | } k8s_config_t; 40 | 41 | k8s_config_t *k8s_config_new(void); 42 | k8s_config_t *k8s_config_load(const char *file); 43 | k8s_config_t *k8s_incluster_config(void); 44 | void cfg_set_ingress_classes(k8s_config_t *, const char *classes); 45 | void k8s_config_free(k8s_config_t *); 46 | 47 | #ifdef __cplusplus 48 | } 49 | #endif 50 | 51 | #endif /* !CONFIG_H */ 52 | -------------------------------------------------------------------------------- /tests/generator.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # vim:set sw=8 ts=8 noet: 3 | # 4 | # This is a trivial HTTP server for use in tests. It only supports GET requests 5 | # and makes no attempt to validate its input or conform to any HTTP 6 | # specification. 7 | 8 | # Travis-CI won't let us remove netcat-openbsd, so instead check for the 9 | # normal version explicitly. 10 | NETCAT=nc 11 | if [ -e /bin/nc.traditional ]; then 12 | NETCAT=/bin/nc.traditional 13 | fi 14 | 15 | if [ -z "$1" ]; then 16 | echo >&2 "usage: $0 " 17 | exit 1 18 | fi 19 | 20 | ncpid=0 21 | 22 | if [ "$1" = "handle" ]; then 23 | read method path version 24 | 25 | while :; do 26 | read line 27 | if echo "$line" | grep -q '^[[:space:]]*$'; then 28 | break 29 | fi 30 | done 31 | 32 | printf 'HTTP/1.0 200 OK\r\n' 33 | printf 'Connection: close\r\n' 34 | printf 'Content-Type: text/plain;charset=UTF-8\r\n' 35 | printf '\r\n' 36 | 37 | printf 'Request method: %s\n' "$method" 38 | printf 'Request path: %s\n' "$path" 39 | sleep 1 40 | echo content; sleep 1 41 | echo content; sleep 1 42 | echo content; sleep 1 43 | echo content; sleep 1 44 | echo content; sleep 1 45 | echo content; sleep 1 46 | echo content; sleep 1 47 | echo content; sleep 1 48 | echo done 49 | exit 0 50 | fi 51 | 52 | trap '[ $ncpid != 0 ] && kill $ncpid; exit 0' INT TERM EXIT 0 53 | 54 | while :; do 55 | $NETCAT -l -p 48080 -c "$0 handle" "$1" & ncpid=$! 56 | wait $ncpid 57 | ncpid=0 58 | done 59 | -------------------------------------------------------------------------------- /contrib/brotli/enc/backward_references.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Google Inc. All Rights Reserved. 2 | 3 | Distributed under MIT license. 4 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 5 | */ 6 | 7 | /* Function to find backward reference copies. */ 8 | 9 | #ifndef BROTLI_ENC_BACKWARD_REFERENCES_H_ 10 | #define BROTLI_ENC_BACKWARD_REFERENCES_H_ 11 | 12 | #include "../common/constants.h" 13 | #include "../common/dictionary.h" 14 | #include 15 | #include "./command.h" 16 | #include "./hash.h" 17 | #include "./port.h" 18 | #include "./quality.h" 19 | 20 | #if defined(__cplusplus) || defined(c_plusplus) 21 | extern "C" { 22 | #endif 23 | 24 | /* "commands" points to the next output command to write to, "*num_commands" is 25 | initially the total amount of commands output by previous 26 | CreateBackwardReferences calls, and must be incremented by the amount written 27 | by this call. */ 28 | BROTLI_INTERNAL void BrotliCreateBackwardReferences( 29 | const BrotliDictionary* dictionary, size_t num_bytes, size_t position, 30 | const uint8_t* ringbuffer, size_t ringbuffer_mask, 31 | const BrotliEncoderParams* params, HasherHandle hasher, int* dist_cache, 32 | size_t* last_insert_len, Command* commands, size_t* num_commands, 33 | size_t* num_literals); 34 | 35 | #if defined(__cplusplus) || defined(c_plusplus) 36 | } /* extern "C" */ 37 | #endif 38 | 39 | #endif /* BROTLI_ENC_BACKWARD_REFERENCES_H_ */ 40 | -------------------------------------------------------------------------------- /tests/ingress-auth-all.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "annotations": { 6 | "ingress.kubernetes.io/auth-realm": "Test authentication", 7 | "ingress.kubernetes.io/auth-secret": "authtest", 8 | "ingress.kubernetes.io/auth-type": "basic", 9 | "ingress.kubernetes.io/whitelist-source-range": "127.0.0.0/8", 10 | "ingress.kubernetes.io/auth-satisfy": "all" 11 | }, 12 | "creationTimestamp": "2017-04-26T01:34:08Z", 13 | "generation": 3, 14 | "name": "echoheaders", 15 | "namespace": "default", 16 | "resourceVersion": "7475305", 17 | "selfLink": "/apis/extensions/v1beta1/namespaces/default/ingresses/echoheaders", 18 | "uid": "71152265-2a20-11e7-a408-4201ac1fd809" 19 | }, 20 | "spec": { 21 | "rules": [ 22 | { 23 | "host": "echoheaders.gce.t6x.uk", 24 | "http": { 25 | "paths": [ 26 | { 27 | "path": "/foo", 28 | "backend": { 29 | "serviceName": "echoheaders", 30 | "servicePort": "http" 31 | } 32 | } 33 | ] 34 | } 35 | } 36 | ] 37 | }, 38 | "status": { 39 | "loadBalancer": {} 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/ingress-auth-any.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "extensions/v1beta1", 3 | "kind": "Ingress", 4 | "metadata": { 5 | "annotations": { 6 | "ingress.kubernetes.io/auth-realm": "Test authentication", 7 | "ingress.kubernetes.io/auth-secret": "authtest", 8 | "ingress.kubernetes.io/auth-type": "basic", 9 | "ingress.kubernetes.io/whitelist-source-range": "127.0.0.0/8", 10 | "ingress.kubernetes.io/auth-satisfy": "any" 11 | }, 12 | "creationTimestamp": "2017-04-26T01:34:08Z", 13 | "generation": 3, 14 | "name": "echoheaders", 15 | "namespace": "default", 16 | "resourceVersion": "7475305", 17 | "selfLink": "/apis/extensions/v1beta1/namespaces/default/ingresses/echoheaders", 18 | "uid": "71152265-2a20-11e7-a408-4201ac1fd809" 19 | }, 20 | "spec": { 21 | "rules": [ 22 | { 23 | "host": "echoheaders.gce.t6x.uk", 24 | "http": { 25 | "paths": [ 26 | { 27 | "path": "/foo", 28 | "backend": { 29 | "serviceName": "echoheaders", 30 | "servicePort": "http" 31 | } 32 | } 33 | ] 34 | } 35 | } 36 | ] 37 | }, 38 | "status": { 39 | "loadBalancer": {} 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /docker/init.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # vim:set sw=8 ts=8 noet: 3 | # 4 | # Copyright (c) 2016-2017 Torchbox Ltd. 5 | # 6 | # Permission is granted to anyone to use this software for any purpose, 7 | # including commercial applications, and to alter it and redistribute it 8 | # freely. 9 | # 10 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 11 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 12 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 13 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 14 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 15 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 16 | # SOFTWARE. 17 | 18 | 19 | set -e 20 | 21 | mkdir -p /var/lib/trafficserver 22 | mkdir -p /var/log/trafficserver 23 | 24 | # Default to 128MB cache size. 25 | CACHEFILE=/var/lib/trafficserver/cache.db 26 | : ${TS_CACHE_SIZE=128} 27 | 28 | if [ \( ! -f "$CACHEFILE" \) -o "$(stat -c%s $CACHEFILE)" != $(expr $TS_CACHE_SIZE '*' 1024 '*' 1024) ]; then 29 | echo 'init.sh: initialising cache file' 30 | rm -f $CACHEFILE 31 | dd if=/dev/zero of=$CACHEFILE bs=1M count=128 32 | fi 33 | 34 | cat >/usr/local/etc/trafficserver/storage.config <<__EOF__ 35 | ${CACHEFILE} ${TS_CACHE_SIZE}M 36 | __EOF__ 37 | 38 | echo "CONFIG proxy.config.proxy_name STRING $(hostname)" \ 39 | >>/usr/local/etc/trafficserver/records.config 40 | 41 | exec /usr/local/bin/traffic_server 42 | -------------------------------------------------------------------------------- /contrib/brotli/enc/histogram_inc.h: -------------------------------------------------------------------------------- 1 | /* NOLINT(build/header_guard) */ 2 | /* Copyright 2013 Google Inc. All Rights Reserved. 3 | 4 | Distributed under MIT license. 5 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 6 | */ 7 | 8 | /* template parameters: Histogram, DATA_SIZE, DataType */ 9 | 10 | /* A simple container for histograms of data in blocks. */ 11 | 12 | typedef struct FN(Histogram) { 13 | uint32_t data_[DATA_SIZE]; 14 | size_t total_count_; 15 | double bit_cost_; 16 | } FN(Histogram); 17 | 18 | static BROTLI_INLINE void FN(HistogramClear)(FN(Histogram)* self) { 19 | memset(self->data_, 0, sizeof(self->data_)); 20 | self->total_count_ = 0; 21 | self->bit_cost_ = HUGE_VAL; 22 | } 23 | 24 | static BROTLI_INLINE void FN(ClearHistograms)( 25 | FN(Histogram)* array, size_t length) { 26 | size_t i; 27 | for (i = 0; i < length; ++i) FN(HistogramClear)(array + i); 28 | } 29 | 30 | static BROTLI_INLINE void FN(HistogramAdd)(FN(Histogram)* self, size_t val) { 31 | ++self->data_[val]; 32 | ++self->total_count_; 33 | } 34 | 35 | static BROTLI_INLINE void FN(HistogramAddVector)(FN(Histogram)* self, 36 | const DataType *p, size_t n) { 37 | self->total_count_ += n; 38 | n += 1; 39 | while (--n) ++self->data_[*p++]; 40 | } 41 | 42 | static BROTLI_INLINE void FN(HistogramAddHistogram)(FN(Histogram)* self, 43 | const FN(Histogram)* v) { 44 | size_t i; 45 | self->total_count_ += v->total_count_; 46 | for (i = 0; i < DATA_SIZE; ++i) { 47 | self->data_[i] += v->data_[i]; 48 | } 49 | } 50 | 51 | static BROTLI_INLINE size_t FN(HistogramDataSize)(void) { return DATA_SIZE; } 52 | -------------------------------------------------------------------------------- /docs/domainaccess.md: -------------------------------------------------------------------------------- 1 | # Domain access control 2 | 3 | Domain access control allows the server administrator to control which domains 4 | each namespace is allowed to use. This lets you operate multi-tenant clusters 5 | without one namespace being able to (accidentally or maliciously) intercept 6 | traffic intended for a different namespace. 7 | 8 | To configure domain access control, set the option `domain-access-list` in the 9 | [TS ConfigMap](config.md): 10 | 11 | ``` 12 | domain-access-list: *fooapp.com:fooapp-prod,fooapp-staging baz.bar.com:baz-microsite 13 | ``` 14 | 15 | The format is list of `:[,...]` entries separated 16 | by whitespace. The list is matched in order; the first matching entry for a 17 | particular Ingress's hostname is used to determine access. If the namespace 18 | containing the Ingress does not appear after the ':' for that entry, the Ingress 19 | will be ignored. 20 | 21 | Domains can be listed in several ways: 22 | 23 | * `*` will match any domain; 24 | * `www.myapp.com` will match only `www.myapp.com`, not `myapp.com`; 25 | * `*.myapp.com` will match `sub.myapp.com` but not `other.sub.myapp.com` or 26 | `myapp.com`. 27 | * `*myapp.com` will match `myapp.com` and `sub.myapp.com`, but not 28 | `other.sub.myapp.com`. 29 | 30 | Generally, to delegate an entire domain (such as `myapp.com`) to a namespace, 31 | you will want to use the `*myapp.com` form. 32 | 33 | The special namespace `*` will match any namespace. To permit domains not 34 | explicitly listed to be used by any namespace, add `*:*` to the end of the list. 35 | (By default, any domain not explicitly listed is denied.) 36 | -------------------------------------------------------------------------------- /travis-build.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # vim:set sw=8 ts=8 noet: 3 | 4 | set -e 5 | 6 | if [ -n "$TRAVIS_TAG" ]; then 7 | VERSION="$TRAVIS_TAG" 8 | else 9 | VERSION="v$(sed -ne '/AC_INIT/ {s/.*, \[\(.*\)\].*/\1/; p}' configure.ac)-dev" 10 | fi 11 | 12 | printf 'travis_fold:start:build-release\r' 13 | printf '>>> Building release.\n\n' 14 | 15 | # Always build from a release, so we know the release process works. 16 | make -f Makefile.dist VERSION=$VERSION release 17 | 18 | printf 'travis_fold:end:build-release\r' 19 | 20 | cd k8s-ts-ingress-$VERSION 21 | 22 | printf 'travis_fold:start:build-docker\r' 23 | printf '>>> Building Docker image.\n\n' 24 | # This tests the build and runs basic unit tests. 25 | DOCKER_REPOSITORY=torchbox/k8s-ts-ingress 26 | docker build --pull --build-arg build_id=${TRAVIS_BUILD_NUMBER} \ 27 | -t $DOCKER_REPOSITORY:$COMMIT . 28 | printf 'travis_fold:end:build-docker\r' 29 | 30 | printf 'travis_fold:start:test-e2e\r' 31 | printf '>>> Running end-to-end tests.\n\n' 32 | # Run e2e tests. 33 | sudo apt-get -qq update 34 | sudo apt-get -qy install libjson-c-dev libcurl4-openssl-dev libssl-dev \ 35 | netcat-traditional pkg-config 36 | tests/e2erun.sh 37 | printf 'travis_fold:end:test-e2e\r' 38 | 39 | # If this is a release, push the Docker image to Docker Hub. 40 | if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then 41 | printf 'travis_fold:start:release\r' 42 | printf '>>> Creating release.\n\n' 43 | 44 | docker login -u $DOCKER_USER -p $DOCKER_PASSWORD 45 | docker tag $DOCKER_REPOSITORY:$COMMIT $DOCKER_REPOSITORY:$VERSION 46 | docker push $DOCKER_REPOSITORY:$VERSION 47 | printf 'travis_fold:end:release\r' 48 | fi 49 | -------------------------------------------------------------------------------- /crypt/ts_crypt.h: -------------------------------------------------------------------------------- 1 | /* vim:set sw=8 ts=8 noet: */ 2 | /* 3 | * Copyright (c) 2016-2017 Torchbox Ltd. 4 | * 5 | * Permission is granted to anyone to use this software for any purpose, 6 | * including commercial applications, and to alter it and redistribute it 7 | * freely. This software is provided 'as-is', without any express or implied 8 | * warranty. 9 | */ 10 | 11 | #ifndef CRYPT_H 12 | #define CRYPT_H 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | typedef int (*crypt_fn_t) (const char *plain, const char *salt, 19 | char *buf, size_t n); 20 | 21 | int crypt_check(const char *plain, const char *hash); 22 | 23 | int crypt_des(const char *, const char *, char *, size_t); 24 | int crypt_md5(const char *, const char *, char *, size_t); 25 | int crypt_blowfish(const char *, const char *, char *, size_t); 26 | int crypt_sha256(const char *, const char *, char *, size_t); 27 | int crypt_sha512(const char *, const char *, char *, size_t); 28 | 29 | typedef int (*crypt_check_fn) (const char *, const char *); 30 | 31 | int crypt_check_des(const char *plain, const char *hashed); 32 | int crypt_check_phk_md5(const char *plain, const char *hashed); 33 | int crypt_check_blowfish(const char *plain, const char *hashed); 34 | int crypt_check_sha256(const char *plain, const char *hashed); 35 | int crypt_check_sha512(const char *plain, const char *hashed); 36 | int crypt_check_rfc2307_plain(const char *plain, const char *hashed); 37 | int crypt_check_rfc2307_sha(const char *plain, const char *hashed); 38 | int crypt_check_rfc2307_ssha(const char *plain, const char *hashed); 39 | 40 | #ifdef __cplusplus 41 | } 42 | #endif 43 | 44 | #endif /* !CRYPT_H */ 45 | -------------------------------------------------------------------------------- /contrib/brotli/enc/cluster.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Google Inc. All Rights Reserved. 2 | 3 | Distributed under MIT license. 4 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 5 | */ 6 | 7 | /* Functions for clustering similar histograms together. */ 8 | 9 | #include "./cluster.h" 10 | 11 | #include 12 | #include "./bit_cost.h" /* BrotliPopulationCost */ 13 | #include "./fast_log.h" 14 | #include "./histogram.h" 15 | #include "./memory.h" 16 | #include "./port.h" 17 | 18 | #if defined(__cplusplus) || defined(c_plusplus) 19 | extern "C" { 20 | #endif 21 | 22 | static BROTLI_INLINE BROTLI_BOOL HistogramPairIsLess( 23 | const HistogramPair* p1, const HistogramPair* p2) { 24 | if (p1->cost_diff != p2->cost_diff) { 25 | return TO_BROTLI_BOOL(p1->cost_diff > p2->cost_diff); 26 | } 27 | return TO_BROTLI_BOOL((p1->idx2 - p1->idx1) > (p2->idx2 - p2->idx1)); 28 | } 29 | 30 | /* Returns entropy reduction of the context map when we combine two clusters. */ 31 | static BROTLI_INLINE double ClusterCostDiff(size_t size_a, size_t size_b) { 32 | size_t size_c = size_a + size_b; 33 | return (double)size_a * FastLog2(size_a) + 34 | (double)size_b * FastLog2(size_b) - 35 | (double)size_c * FastLog2(size_c); 36 | } 37 | 38 | #define CODE(X) X 39 | 40 | #define FN(X) X ## Literal 41 | #include "./cluster_inc.h" /* NOLINT(build/include) */ 42 | #undef FN 43 | 44 | #define FN(X) X ## Command 45 | #include "./cluster_inc.h" /* NOLINT(build/include) */ 46 | #undef FN 47 | 48 | #define FN(X) X ## Distance 49 | #include "./cluster_inc.h" /* NOLINT(build/include) */ 50 | #undef FN 51 | 52 | #undef CODE 53 | 54 | #if defined(__cplusplus) || defined(c_plusplus) 55 | } /* extern "C" */ 56 | #endif 57 | -------------------------------------------------------------------------------- /tests/test-key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCl8k1eJWZ2nKaJ 3 | JGVxvMrbvoYNA/0zbVYnEja+4WR1wbA7KMt1pVVFY45SD5NjRO+NCIVSGB74r99X 4 | uwFXU9DmDUm5j7UxlmP/bYJhC5nO4A7bPTaapGyjALpsGr2Y7kaQbKKNclZvMRyM 5 | 07NgXsyLeC1Owi2iXU0Ja/Zcf1YgtZw/UVJr6Glc8FrPfmp+rZrNZ/f2u/BMiXMB 6 | l5uUo8pNUWDUGkPnv66BRhR88wrr/z1NSFmn/VffEcefOyfDk2nTopzyLr109SfS 7 | b7k9kXhcwctPfAjzsn0f1xbB6qYONI7uqpghJtde/W1Msod6j0xlOzALumwF/g9I 8 | EbgWOK/jAgMBAAECggEBAJjpRdtbsSfYvygd7pA4e+CylclGhLkvpbRI90M6Y5yS 9 | hnZs59YXLBTNYOZCzfgqHGajlF4KNffH75BilCDI7fQeCHJBdqAjyS8j1IDh9K+J 10 | DId+x2MF4cjtsdpNZamW3lTUlZCq6/R3l6w4otBJakeVzIIHMY+sU4E8B35CI7Xs 11 | xp/oOgo4Z3NfBUHfhxrQWqSBpbJCmo7L0jZv9CC/ilc1A7zi+z/CeOQYLSGyFNdn 12 | WG5W9SjLRjE8FpAiONoiO08xQCpED0B+F5HhymV3wxmvhbL2Z0uqQfxNTTYZqUxI 13 | eWQqE1OLi6VFTOkZzWRf2f5F6qryGUEP+xWMkv/Af8ECgYEA2ND0+2/u0jQWPs7I 14 | 4az0KYlrWxTdr/o6nQ7O4LbfAdfGcnLjXVbP3t3K71P22MpT+SL9bG8ZibI45xqj 15 | V9o0z8p4qap92gHGOf9/y3uz6oZ6l5PI3509eKOTL1QMNd3Te5d6q1y01mFEn1a4 16 | 97ORVbyTR4tkg4mH8dKSncmyzMMCgYEAw+/Y392XQoEJp0TTQWViyZF+qEk9Rw04 17 | az0TN+18F+k2JujfrLX9B8RoDzS2zFI9ozEqv8d8U7UQSt+06PNxBOHx33WtOlV5 18 | QjE6U0FD0mmR9EZaxxTnfm+Tfyousm5BWdO2Elyu8yWOxslUORKTXQwZWVcoOuht 19 | migRu9X43mECgYAvV4EGnexBzcnFsRU/4an2n+DnJGk7kaHWxXL6sjODjX/xYZCv 20 | wtLk0P0MwQK3V4Z6cd9wG9oxrM6r968O8cByVr1+HpIYVibYZyeaYMpqPS7rhgNo 21 | gEb53o222d1IrcUNyYepfzalUNvRBvigbX8gf2qRRqiN6Cvc66PD/FSkTQKBgFbB 22 | akulOAZQUE/p34hDNfx+GZC17RX6upJxFoNa+ek0b6/GyNMWOZUo19JzysSpXXVW 23 | ndEQqPH/Z9lfOCE1OUOqL4h7+Fmt4uT2Gxcl/Lu71s5MIIGptd571NknekmzG+iE 24 | H0f+FdC/PnqyRkKHAQzgAJFYUA3VQEJTn5aF5Y3BAoGAHCpq0j8TgWTbdqf2Njgt 25 | 76tumxbe/edZsV+zilFLkEraDnc5F+/5keG3QKO/ux8K3+w+TdFTuZyjd5/Dfrsu 26 | 5chs6JjlTnppkv3anDYe61NoCbcOqP52euEEcYNeODrBjf1Lz+NLNMTcj7UDkMKR 27 | kED7Z2nGCmRrCeNFYTaN2xw= 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # vim:set sw=8 ts=8 noet: 2 | # 3 | # Copyright (c) 2016-2017 Torchbox Ltd. 4 | # 5 | # Permission is granted to anyone to use this software for any purpose, 6 | # including commercial applications, and to alter it and redistribute it 7 | # freely. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 10 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 11 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 12 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 13 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 14 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 15 | # SOFTWARE. 16 | 17 | FROM torchbox/trafficserver:7.1.x-1.0 18 | 19 | ARG build_id=unknown 20 | 21 | COPY . /usr/src/k8s-ts-ingress 22 | 23 | RUN set -ex \ 24 | && apt-get update \ 25 | && apt-get -y install libssl1.0-dev libjson-c3 libjson-c-dev libc6-dev \ 26 | make gcc g++ pkgconf libcurl3 libcurl4-openssl-dev autoconf \ 27 | zlib1g-dev \ 28 | && cd /usr/src/k8s-ts-ingress \ 29 | && autoreconf -if \ 30 | && ./configure --with-tsxs=/usr/local/bin/tsxs \ 31 | --with-build-id=$build_id \ 32 | && make \ 33 | && make test \ 34 | && make install \ 35 | && apt-get -y remove libjson-c-dev libc6-dev gcc make pkgconf \ 36 | libcurl4-openssl-dev autoconf libssl1.0-dev \ 37 | && apt-get -y autoremove \ 38 | && cd / \ 39 | && rm -rf /var/cache/apt /var/lib/apt/lists/* /usr/src/k8s-ts-ingress 40 | 41 | COPY docker/init.sh / 42 | RUN chmod 755 /init.sh 43 | COPY docker/remap.config docker/records.config docker/plugin.config \ 44 | docker/ip_allow.config /usr/local/etc/trafficserver/ 45 | 46 | CMD [ "/init.sh" ] 47 | -------------------------------------------------------------------------------- /contrib/brotli/enc/block_splitter.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Google Inc. All Rights Reserved. 2 | 3 | Distributed under MIT license. 4 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 5 | */ 6 | 7 | /* Block split point selection utilities. */ 8 | 9 | #ifndef BROTLI_ENC_BLOCK_SPLITTER_H_ 10 | #define BROTLI_ENC_BLOCK_SPLITTER_H_ 11 | 12 | #include 13 | #include "./command.h" 14 | #include "./memory.h" 15 | #include "./port.h" 16 | #include "./quality.h" 17 | 18 | #if defined(__cplusplus) || defined(c_plusplus) 19 | extern "C" { 20 | #endif 21 | 22 | typedef struct BlockSplit { 23 | size_t num_types; /* Amount of distinct types */ 24 | size_t num_blocks; /* Amount of values in types and length */ 25 | uint8_t* types; 26 | uint32_t* lengths; 27 | 28 | size_t types_alloc_size; 29 | size_t lengths_alloc_size; 30 | } BlockSplit; 31 | 32 | BROTLI_INTERNAL void BrotliInitBlockSplit(BlockSplit* self); 33 | BROTLI_INTERNAL void BrotliDestroyBlockSplit(MemoryManager* m, 34 | BlockSplit* self); 35 | 36 | BROTLI_INTERNAL void BrotliSplitBlock(MemoryManager* m, 37 | const Command* cmds, 38 | const size_t num_commands, 39 | const uint8_t* data, 40 | const size_t offset, 41 | const size_t mask, 42 | const BrotliEncoderParams* params, 43 | BlockSplit* literal_split, 44 | BlockSplit* insert_and_copy_split, 45 | BlockSplit* dist_split); 46 | 47 | #if defined(__cplusplus) || defined(c_plusplus) 48 | } /* extern "C" */ 49 | #endif 50 | 51 | #endif /* BROTLI_ENC_BLOCK_SPLITTER_H_ */ 52 | -------------------------------------------------------------------------------- /gtest/src/gtest_main.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2006, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #include 31 | 32 | #include "gtest/gtest.h" 33 | 34 | GTEST_API_ int main(int argc, char **argv) { 35 | printf("Running main() from gtest_main.cc\n"); 36 | testing::InitGoogleTest(&argc, argv); 37 | return RUN_ALL_TESTS(); 38 | } 39 | -------------------------------------------------------------------------------- /tests/e2e/004-compression/run.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # vim:set sw=8 ts=8 noet: 3 | 4 | # Test compression. 5 | 6 | expect_output() { 7 | if echo "$output" | egrep -q "$@"; then 8 | return 0 9 | else 10 | echo "Failed: output did not include test string: [$*]" 11 | echo "Test output: [$output]" 12 | exit 1 13 | fi 14 | } 15 | 16 | # Uncached compression. 17 | 18 | printf '.' 19 | output=$(curl 2>&1 -visS --resolve echoheaders.test:58080:127.0.0.1 \ 20 | http://echoheaders.test:58080/this-is-a-test) 21 | expect_output "^Vary: Accept-Encoding" 22 | expect_output -v "Content-Encoding" 23 | 24 | printf '.' 25 | output=$(curl 2>&1 -visS --compressed -H'Accept-Encoding: gzip' \ 26 | --resolve echoheaders.test:58080:127.0.0.1 \ 27 | http://echoheaders.test:58080/this-is-a-test) 28 | expect_output "^Vary: Accept-Encoding" 29 | expect_output "^Content-Encoding: gzip" 30 | expect_output "^Request path: /this-is-a-test" 31 | 32 | # Test deflate here as well. 33 | printf '.' 34 | output=$(curl 2>&1 -visS --compressed -H'Accept-Encoding: deflate' \ 35 | --resolve echoheaders.test:58080:127.0.0.1 \ 36 | http://echoheaders.test:58080/this-is-a-test) 37 | expect_output "^Vary: Accept-Encoding" 38 | expect_output "^Content-Encoding: deflate" 39 | expect_output "^Request path: /this-is-a-test" 40 | 41 | # Cached compression. 42 | printf '.' 43 | output=$(curl 2>&1 -visS --resolve echoheaders.test:58080:127.0.0.1 \ 44 | http://echoheaders.test:58080/cached/test) 45 | expect_output "^X-Cache-Status: hit-fresh" 46 | expect_output "^Vary: Accept-Encoding" 47 | expect_output -v "Content-Encoding" 48 | 49 | printf '.' 50 | output=$(curl 2>&1 -visS --compressed \ 51 | --resolve echoheaders.test:58080:127.0.0.1 \ 52 | http://echoheaders.test:58080/cached/test) 53 | expect_output "^X-Cache-Status: hit-fresh" 54 | expect_output "^Vary: Accept-Encoding" 55 | expect_output "^Content-Encoding" 56 | expect_output "^Request path: /cached/test" 57 | -------------------------------------------------------------------------------- /Makefile.dist: -------------------------------------------------------------------------------- 1 | # vim:set sw=8 ts=8 noet: 2 | # 3 | # Copyright (c) 2016-2017 Torchbox Ltd. 4 | # 5 | # Permission is granted to anyone to use this software for any purpose, 6 | # including commercial applications, and to alter it and redistribute it 7 | # freely. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 10 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 11 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 12 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 13 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 14 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 15 | # SOFTWARE. 16 | 17 | DOCKER_REGISTRY?= torchbox/k8s-ts-ingress 18 | DOCKER_TAG?= latest 19 | DOCKER_IMAGE= ${DOCKER_REGISTRY}:${DOCKER_TAG} 20 | 21 | VERSION?= unversioned 22 | 23 | DISTFILES= api crypt util auth remap tsapi \ 24 | contrib \ 25 | gtest tests \ 26 | configure \ 27 | configure.ac \ 28 | acinclude \ 29 | aclocal.m4 \ 30 | autoconf.h.in \ 31 | config.guess \ 32 | config.sub \ 33 | install-sh \ 34 | kubernetes.config.example \ 35 | test.htpasswd \ 36 | Dockerfile \ 37 | Makefile.dist \ 38 | Makefile.in \ 39 | README.md \ 40 | docker \ 41 | example-daemonset.yaml 42 | 43 | docker-build: 44 | docker build --pull -t ${DOCKER_IMAGE} . 45 | 46 | docker-push: 47 | docker push ${DOCKER_IMAGE} 48 | 49 | release: 50 | autoreconf -if 51 | rm -rf k8s-ts-ingress-${VERSION} 52 | mkdir -p k8s-ts-ingress-${VERSION} 53 | tar cf dist.tar ${DISTFILES} 54 | tar xf dist.tar -C k8s-ts-ingress-${VERSION} 55 | tar cf k8s-ts-ingress-${VERSION}.tar k8s-ts-ingress-${VERSION} 56 | gzip -f k8s-ts-ingress-${VERSION}.tar 57 | @ls -oh k8s-ts-ingress-${VERSION}.tar.gz 58 | 59 | docs: 60 | mkdocs gh-deploy --clean 61 | 62 | .PHONY: docker-build docker-push release docs 63 | -------------------------------------------------------------------------------- /contrib/brotli/enc/memory.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2016 Google Inc. All Rights Reserved. 2 | 3 | Distributed under MIT license. 4 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 5 | */ 6 | 7 | /* Macros for memory management. */ 8 | 9 | #ifndef BROTLI_ENC_MEMORY_H_ 10 | #define BROTLI_ENC_MEMORY_H_ 11 | 12 | #include 13 | #include "./port.h" 14 | 15 | #if defined(__cplusplus) || defined(c_plusplus) 16 | extern "C" { 17 | #endif 18 | 19 | #if !defined(BROTLI_ENCODER_CLEANUP_ON_OOM) && \ 20 | !defined(BROTLI_ENCODER_EXIT_ON_OOM) 21 | #define BROTLI_ENCODER_EXIT_ON_OOM 22 | #endif 23 | 24 | typedef struct MemoryManager { 25 | brotli_alloc_func alloc_func; 26 | brotli_free_func free_func; 27 | void* opaque; 28 | #if !defined(BROTLI_ENCODER_EXIT_ON_OOM) 29 | BROTLI_BOOL is_oom; 30 | size_t perm_allocated; 31 | size_t new_allocated; 32 | size_t new_freed; 33 | void* pointers[256]; 34 | #endif /* BROTLI_ENCODER_EXIT_ON_OOM */ 35 | } MemoryManager; 36 | 37 | BROTLI_INTERNAL void BrotliInitMemoryManager( 38 | MemoryManager* m, brotli_alloc_func alloc_func, brotli_free_func free_func, 39 | void* opaque); 40 | 41 | BROTLI_INTERNAL void* BrotliAllocate(MemoryManager* m, size_t n); 42 | #define BROTLI_ALLOC(M, T, N) \ 43 | ((N) ? ((T*)BrotliAllocate((M), (N) * sizeof(T))) : NULL) 44 | 45 | BROTLI_INTERNAL void BrotliFree(MemoryManager* m, void* p); 46 | #define BROTLI_FREE(M, P) { \ 47 | BrotliFree((M), (P)); \ 48 | P = NULL; \ 49 | } 50 | 51 | #if defined(BROTLI_ENCODER_EXIT_ON_OOM) 52 | #define BROTLI_IS_OOM(M) (!!0) 53 | #else /* BROTLI_ENCODER_EXIT_ON_OOM */ 54 | #define BROTLI_IS_OOM(M) (!!(M)->is_oom) 55 | #endif /* BROTLI_ENCODER_EXIT_ON_OOM */ 56 | 57 | BROTLI_INTERNAL void BrotliWipeOutMemoryManager(MemoryManager* m); 58 | 59 | #if defined(__cplusplus) || defined(c_plusplus) 60 | } /* extern "C" */ 61 | #endif 62 | 63 | #endif /* BROTLI_ENC_MEMORY_H_ */ 64 | -------------------------------------------------------------------------------- /contrib/brotli/enc/bit_cost.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Google Inc. All Rights Reserved. 2 | 3 | Distributed under MIT license. 4 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 5 | */ 6 | 7 | /* Functions to estimate the bit cost of Huffman trees. */ 8 | 9 | #ifndef BROTLI_ENC_BIT_COST_H_ 10 | #define BROTLI_ENC_BIT_COST_H_ 11 | 12 | #include 13 | #include "./fast_log.h" 14 | #include "./histogram.h" 15 | #include "./port.h" 16 | 17 | #if defined(__cplusplus) || defined(c_plusplus) 18 | extern "C" { 19 | #endif 20 | 21 | static BROTLI_INLINE double ShannonEntropy(const uint32_t *population, 22 | size_t size, size_t *total) { 23 | size_t sum = 0; 24 | double retval = 0; 25 | const uint32_t *population_end = population + size; 26 | size_t p; 27 | if (size & 1) { 28 | goto odd_number_of_elements_left; 29 | } 30 | while (population < population_end) { 31 | p = *population++; 32 | sum += p; 33 | retval -= (double)p * FastLog2(p); 34 | odd_number_of_elements_left: 35 | p = *population++; 36 | sum += p; 37 | retval -= (double)p * FastLog2(p); 38 | } 39 | if (sum) retval += (double)sum * FastLog2(sum); 40 | *total = sum; 41 | return retval; 42 | } 43 | 44 | static BROTLI_INLINE double BitsEntropy( 45 | const uint32_t *population, size_t size) { 46 | size_t sum; 47 | double retval = ShannonEntropy(population, size, &sum); 48 | if (retval < sum) { 49 | /* At least one bit per literal is needed. */ 50 | retval = (double)sum; 51 | } 52 | return retval; 53 | } 54 | 55 | BROTLI_INTERNAL double BrotliPopulationCostLiteral(const HistogramLiteral*); 56 | BROTLI_INTERNAL double BrotliPopulationCostCommand(const HistogramCommand*); 57 | BROTLI_INTERNAL double BrotliPopulationCostDistance(const HistogramDistance*); 58 | 59 | #if defined(__cplusplus) || defined(c_plusplus) 60 | } /* extern "C" */ 61 | #endif 62 | 63 | #endif /* BROTLI_ENC_BIT_COST_H_ */ 64 | -------------------------------------------------------------------------------- /contrib/brotli/enc/histogram.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Google Inc. All Rights Reserved. 2 | 3 | Distributed under MIT license. 4 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 5 | */ 6 | 7 | /* Models the histograms of literals, commands and distance codes. */ 8 | 9 | #ifndef BROTLI_ENC_HISTOGRAM_H_ 10 | #define BROTLI_ENC_HISTOGRAM_H_ 11 | 12 | #include /* memset */ 13 | 14 | #include "../common/constants.h" 15 | #include 16 | #include "./block_splitter.h" 17 | #include "./command.h" 18 | #include "./context.h" 19 | #include "./port.h" 20 | 21 | #if defined(__cplusplus) || defined(c_plusplus) 22 | extern "C" { 23 | #endif 24 | 25 | #define FN(X) X ## Literal 26 | #define DATA_SIZE BROTLI_NUM_LITERAL_SYMBOLS 27 | #define DataType uint8_t 28 | #include "./histogram_inc.h" /* NOLINT(build/include) */ 29 | #undef DataType 30 | #undef DATA_SIZE 31 | #undef FN 32 | 33 | #define FN(X) X ## Command 34 | #define DataType uint16_t 35 | #define DATA_SIZE BROTLI_NUM_COMMAND_SYMBOLS 36 | #include "./histogram_inc.h" /* NOLINT(build/include) */ 37 | #undef DATA_SIZE 38 | #undef FN 39 | 40 | #define FN(X) X ## Distance 41 | #define DATA_SIZE BROTLI_NUM_DISTANCE_SYMBOLS 42 | #include "./histogram_inc.h" /* NOLINT(build/include) */ 43 | #undef DataType 44 | #undef DATA_SIZE 45 | #undef FN 46 | 47 | BROTLI_INTERNAL void BrotliBuildHistogramsWithContext( 48 | const Command* cmds, const size_t num_commands, 49 | const BlockSplit* literal_split, const BlockSplit* insert_and_copy_split, 50 | const BlockSplit* dist_split, const uint8_t* ringbuffer, size_t pos, 51 | size_t mask, uint8_t prev_byte, uint8_t prev_byte2, 52 | const ContextType* context_modes, HistogramLiteral* literal_histograms, 53 | HistogramCommand* insert_and_copy_histograms, 54 | HistogramDistance* copy_dist_histograms); 55 | 56 | #if defined(__cplusplus) || defined(c_plusplus) 57 | } /* extern "C" */ 58 | #endif 59 | 60 | #endif /* BROTLI_ENC_HISTOGRAM_H_ */ 61 | -------------------------------------------------------------------------------- /docs/source.md: -------------------------------------------------------------------------------- 1 | # Installing the plugin from source 2 | 3 | If you want to integrate Kubernetes with an existing Traffic Server installation, 4 | you can build the plugin from source. If you're planning to deploy the plugin 5 | inside a Kubernetes cluster, you should read [Using the Docker image](docker.md) 6 | instead. 7 | 8 | ## Requirements 9 | 10 | The following are required to build: 11 | 12 | * Traffic Server 7.1 or later (including development headers). Older versions 13 | will not be supported as they are lacking features the Ingress controller 14 | requires. 15 | * A working C99 compiler and `make` utility. 16 | * json-c library 17 | * cURL library 18 | * OpenSSL (or a compatible TLS library, e.g. LibreSSL) 19 | 20 | If you want to run the unit tests, a C++11 compiler is required. If you want to 21 | run the end-to-end tests, a Linux/amd64 host is required (because those tests 22 | require running the Kubernetes API server). 23 | 24 | ## Building 25 | 26 | To build and install the plugin: 27 | 28 | ```sh 29 | $ autoreconf -if # only if building from a git checkout 30 | $ ./configure [--with-tsxs=/path/to/trafficserver/bin/tsxs] 31 | $ make 32 | $ make install 33 | ``` 34 | 35 | This will put `kubernetes.so` in your Traffic Server plugins directory. Edit 36 | `plugin.config` to tell Traffic Server to load the plugin. 37 | 38 | To run the unit tests: 39 | 40 | ```sh 41 | $ make test 42 | ``` 43 | 44 | To run the end-to-end tests: 45 | 46 | ```sh 47 | $ tests/e2erun.sh 48 | ``` 49 | 50 | ## Configuration 51 | 52 | 53 | If Traffic Server is not running inside the cluster, you will need to provide a 54 | `kubernetes.config` configuration file. See [Configuration](config.md) for 55 | details. 56 | 57 | If TS is running inside the cluster, it will pick up its service account details 58 | automatically and the configuration file is not required, but you will need to 59 | ensure it has access to the resources it needs to run. If you're using RBAC 60 | for authorization, see `rbac.yaml` for an example RBAC configuration. 61 | -------------------------------------------------------------------------------- /tests/ts_mockapi.cc: -------------------------------------------------------------------------------- 1 | /* vim:set sw=8 ts=8 noet: */ 2 | /* 3 | * Copyright (c) 2016-2017 Torchbox Ltd. 4 | * 5 | * Permission is granted to anyone to use this software for any purpose, 6 | * including commercial applications, and to alter it and redistribute it 7 | * freely. This software is provided 'as-is', without any express or implied 8 | * warranty. 9 | */ 10 | /* 11 | * Mock some TS API functions that we use in testing. 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include // for strdup 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | #include "tests/test.h" 25 | 26 | extern "C" { 27 | 28 | int ts_api_errors; 29 | 30 | void 31 | TSError(char const *fmt, ...) 32 | { 33 | va_list args; 34 | va_start(args, fmt); 35 | std::fputs("[ TSAPI ] ", stderr); 36 | std::vfprintf(stderr, fmt, args); 37 | std::fputs("\n", stderr); 38 | va_end(args); 39 | 40 | ++ts_api_errors; 41 | } 42 | 43 | void 44 | TSDebug(char const *tag, char const *fmt, ...) 45 | { 46 | } 47 | 48 | void 49 | TSSslContextDestroy(TSSslContext ctx) 50 | { 51 | SSL_CTX *sslctx = reinterpret_cast(ctx); 52 | SSL_CTX_free(sslctx); 53 | } 54 | 55 | const char * 56 | TSConfigDirGet(void) 57 | { 58 | /* Not actually used for anything in tests. */ 59 | return "/usr/local/etc"; 60 | } 61 | 62 | TSSslContext 63 | TSSslServerContextCreate(void) 64 | { 65 | SSL_CTX *ctx = SSL_CTX_new(SSLv23_server_method()); 66 | return reinterpret_cast(ctx); 67 | } 68 | 69 | char * 70 | _k8s_get_ssl_error(void) 71 | { 72 | BIO *bio = BIO_new(BIO_s_mem()); 73 | size_t len; 74 | char *ret, *buf; 75 | 76 | ERR_print_errors(bio); 77 | len = BIO_get_mem_data(bio, &buf); 78 | if (len == 0) { 79 | BIO_free(bio); 80 | return strdup("no error"); 81 | } 82 | 83 | if ((ret = static_cast(malloc(len + 1))) == NULL) { 84 | BIO_free(bio); 85 | return NULL; 86 | } 87 | 88 | std::memcpy(ret, buf, len); 89 | buf[len] = '\0'; 90 | BIO_free(bio); 91 | return ret; 92 | } 93 | } // extern "C" 94 | -------------------------------------------------------------------------------- /docs/annotations.md: -------------------------------------------------------------------------------- 1 | # Ingress annotations 2 | 3 | The behaviour of an Ingress can be configured by setting annotations on the 4 | Ingress resource, e.g.: 5 | 6 | ```yaml 7 | metadata: 8 | annotations: 9 | ingress.kubernetes.io/rewrite-target: '/myapp' 10 | ``` 11 | 12 | Annotations whose names with `ingress.kubernetes.io` are standard annotations 13 | supported by most Ingress controllers; those beginning with 14 | `ingress.kubernetes.io` are specific to the Traffic Server Ingress controller. 15 | 16 | * `ingress.kubernetes.io/rewrite-target`: if set to a string, the portion of the 17 | request path matched by the Ingress `path` attribute will be replaced with 18 | this string. This has no effect on an Ingress without a `path` set. 19 | 20 | * `ingress.kubernetes.io/app-root`: if set to a path, requests for `/` will be 21 | redirected to this path. This can be used for applications which sit in a 22 | subdirectory rather than at the root. 23 | 24 | * `ingress.kubernetes.io/follow-redirects`: if `"true"`, Traffic Server will 25 | follow 3xx redirect responses and serve the final response to the client. 26 | If the redirect destination is cached, it will be cached with the cache key 27 | of the original request. Redirects will only be followed to other Ingress 28 | resources, not to arbitrary destinations (but see below about proxying to 29 | external resources). 30 | 31 | * `ingress.kubernetes.io/preserve-host`: if `"false"`, set the `Host` header 32 | in the request to the backend name (e.g., the pod name), instead of the 33 | original request host. 34 | 35 | * `ingress.kubernetes.io/read-response-timeout": set the time in seconds that 36 | TS will wait for for the response from the origin. If this timeout is 37 | exceeded, an HTTP 504 error will be returned to the client. 38 | 39 | * `ingress.kubernetes.io/http2-enable`: if `"false"`, HTTP/2 will be disabled on 40 | this Ingress even if it's enabled globally. This can only be set on the 41 | Ingress that contains the default backend for a particular hostname (i.e., 42 | where no `path` attribute is set). 43 | -------------------------------------------------------------------------------- /docs/docker.md: -------------------------------------------------------------------------------- 1 | # Using the Docker image on Kubernetes 2 | 3 | We provide two examples Kubernetes deployments for the TS ingress controller: 4 | 5 | * `example-daemonset.yaml` uses a DaemonSet, with an example of using node 6 | taints and affinity to run the controller only on master nodes, and exposes 7 | TS using a hostPort; 8 | * `example-deployment.yaml` uses a Deployment, with a nodePort Service used to 9 | expose TS. 10 | 11 | These both use the Docker image `docker.io/torchbox/k8s-ts-ingress:v1.0.0-alpha8`. 12 | 13 | You will probably want to read and edit one of these files before using it. 14 | 15 | Unfortunately, there are many different ways to expose an Ingress controller on 16 | Kubernetes, and we can't document every possible variation, so you will need to 17 | decide what method is best for your cluster. 18 | 19 | ## Runtime configuration 20 | 21 | Most Traffic Server configuration (`records.config` entries) can be changed 22 | using environment variables; see the 23 | [Traffic Server Documentation](https://docs.trafficserver.apache.org/en/latest/admin-guide/files/records.config.en.html#environment-overrides). 24 | For example, to make Traffic Server listen on port 7080 for HTTP requests, 25 | set `PROXY_CONFIG_HTTP_SERVER_PORTS=7080`. 26 | 27 | The TS Docker image provides one additional environment variable: 28 | 29 | * `TS_CACHE_SIZE=nnn`: Size of the on-disk cache file to create, in megabytes. 30 | 31 | ## Cache storage 32 | 33 | The example deployment resources use an `emptyDir` for cache storage. This 34 | means the cache will persist across node reboots, but will we cleared if the 35 | pod is move to a different node, or if it's upgraded (which deletes the old pod). 36 | 37 | The cache file will be created automatically on startup if it doesn't exist. 38 | 39 | For persistent cache storage, mount a volume on `/var/lib/trafficserver`. 40 | However, be aware that only one instance of TS can access the cache at once. If 41 | you are running multiple copies, you will need to create a separate PV for each 42 | instance (perhaps by using a StatefulSet instead of a DaemonSet). 43 | 44 | -------------------------------------------------------------------------------- /gtest/include/gtest/internal/custom/gtest.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Injection point for custom user configurations. 31 | // The following macros can be defined: 32 | // 33 | // GTEST_OS_STACK_TRACE_GETTER_ - The name of an implementation of 34 | // OsStackTraceGetterInterface. 35 | // 36 | // ** Custom implementation starts here ** 37 | 38 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ 39 | #define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ 40 | 41 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ 42 | -------------------------------------------------------------------------------- /util/test_base64.cc: -------------------------------------------------------------------------------- 1 | /* vim:set sw=8 ts=8 noet: */ 2 | /* 3 | * Copyright (c) 2016-2017 Torchbox Ltd. 4 | * 5 | * Permission is granted to anyone to use this software for any purpose, 6 | * including commercial applications, and to alter it and redistribute it 7 | * freely. This software is provided 'as-is', without any express or implied 8 | * warranty. 9 | */ 10 | 11 | /* 12 | * Tests for base64.c: base64 encoding/decoding functions. 13 | */ 14 | 15 | #include 16 | #include 17 | 18 | #include "gtest/gtest.h" 19 | 20 | #include "base64.h" 21 | 22 | using std::string; 23 | using std::vector; 24 | using std::equal; 25 | 26 | namespace { 27 | struct base64_test { 28 | string plain; 29 | string encoded; 30 | }; 31 | 32 | vector const tests{ 33 | { "test", "dGVzdA==" }, 34 | { "test2", "dGVzdDI=" }, 35 | { "test 3", "dGVzdCAz" }, 36 | { string("\xff\x80\x7f\x00", 4), 37 | "/4B/AA==" }, 38 | }; 39 | } 40 | 41 | TEST(Base64, Encode) 42 | { 43 | for (auto &&test : tests) { 44 | size_t n = base64_encode_len(test.plain.size()); 45 | ASSERT_EQ(n, test.encoded.size()); 46 | 47 | vector encoded(n); 48 | base64_encode((unsigned char const *)test.plain.data(), 49 | test.plain.size(), 50 | &encoded[0]); 51 | 52 | ASSERT_TRUE(equal(test.encoded.begin(), test.encoded.end(), 53 | encoded.begin())) 54 | << "expected [" << test.encoded << "], got [" 55 | << string(encoded.begin(), encoded.end()) << "]"; 56 | } 57 | } 58 | 59 | TEST(Base64, Decode) 60 | { 61 | for (auto &&test : tests) { 62 | ssize_t n = base64_decode_len(test.encoded.size()); 63 | ASSERT_GE(n, 0); 64 | ASSERT_GE((size_t) n, test.plain.size()); 65 | 66 | vector decoded(n); 67 | n = base64_decode(test.encoded.data(), 68 | test.encoded.size(), 69 | (unsigned char *)&decoded[0]); 70 | 71 | ASSERT_GE(n, 0); 72 | ASSERT_EQ((size_t) n, test.plain.size()); 73 | decoded.resize(n); 74 | 75 | ASSERT_TRUE(equal(test.plain.begin(), test.plain.end(), 76 | decoded.begin())) 77 | << "expected [" << test.plain << "], got [" 78 | << string(decoded.begin(), decoded.end()) << "]"; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /contrib/brotli/enc/prefix.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Google Inc. All Rights Reserved. 2 | 3 | Distributed under MIT license. 4 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 5 | */ 6 | 7 | /* Functions for encoding of integers into prefix codes the amount of extra 8 | bits, and the actual values of the extra bits. */ 9 | 10 | #ifndef BROTLI_ENC_PREFIX_H_ 11 | #define BROTLI_ENC_PREFIX_H_ 12 | 13 | #include "../common/constants.h" 14 | #include 15 | #include 16 | #include "./fast_log.h" 17 | 18 | #if defined(__cplusplus) || defined(c_plusplus) 19 | extern "C" { 20 | #endif 21 | 22 | /* Here distance_code is an intermediate code, i.e. one of the special codes or 23 | the actual distance increased by BROTLI_NUM_DISTANCE_SHORT_CODES - 1. */ 24 | static BROTLI_INLINE void PrefixEncodeCopyDistance(size_t distance_code, 25 | size_t num_direct_codes, 26 | size_t postfix_bits, 27 | uint16_t* code, 28 | uint32_t* extra_bits) { 29 | if (distance_code < BROTLI_NUM_DISTANCE_SHORT_CODES + num_direct_codes) { 30 | *code = (uint16_t)distance_code; 31 | *extra_bits = 0; 32 | return; 33 | } else { 34 | size_t dist = ((size_t)1 << (postfix_bits + 2u)) + 35 | (distance_code - BROTLI_NUM_DISTANCE_SHORT_CODES - num_direct_codes); 36 | size_t bucket = Log2FloorNonZero(dist) - 1; 37 | size_t postfix_mask = (1u << postfix_bits) - 1; 38 | size_t postfix = dist & postfix_mask; 39 | size_t prefix = (dist >> bucket) & 1; 40 | size_t offset = (2 + prefix) << bucket; 41 | size_t nbits = bucket - postfix_bits; 42 | *code = (uint16_t)( 43 | (BROTLI_NUM_DISTANCE_SHORT_CODES + num_direct_codes + 44 | ((2 * (nbits - 1) + prefix) << postfix_bits) + postfix)); 45 | *extra_bits = (uint32_t)( 46 | (nbits << 24) | ((dist - offset) >> postfix_bits)); 47 | } 48 | } 49 | 50 | #if defined(__cplusplus) || defined(c_plusplus) 51 | } /* extern "C" */ 52 | #endif 53 | 54 | #endif /* BROTLI_ENC_PREFIX_H_ */ 55 | -------------------------------------------------------------------------------- /contrib/rax/rax_malloc.h: -------------------------------------------------------------------------------- 1 | /* Rax -- A radix tree implementation. 2 | * 3 | * Copyright (c) 2017, Salvatore Sanfilippo 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * * Neither the name of Redis nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | /* Allocator selection. 32 | * 33 | * This file is used in order to change the Rax allocator at compile time. 34 | * Just define the following defines to what you want to use. Also add 35 | * the include of your alternate allocator if needed (not needed in order 36 | * to use the default libc allocator). */ 37 | 38 | #ifndef RAX_ALLOC_H 39 | #define RAX_ALLOC_H 40 | #define rax_malloc malloc 41 | #define rax_realloc realloc 42 | #define rax_free free 43 | #endif 44 | -------------------------------------------------------------------------------- /kubernetes.config.example: -------------------------------------------------------------------------------- 1 | # Example configuration file for TS Kubernetes plugins. 2 | # 3 | # Most of the settings in this file can also be given as environment variables, 4 | # which will override anything set here. 5 | 6 | ### API server configuration 7 | # 8 | # This is required when running outside the cluster, but not necessary when 9 | # running in-cluster; the pod's service account will be used by default. 10 | 11 | # Set the URL of the Kubernetes API server. (Environment variable: $TS_SERVER.) 12 | # 13 | # To re-use existing kubectl credentials, you can run "kubectl proxy" and use 14 | # http://localhost:8001 as the server. In that case, do not configure a TLS 15 | # certificate or token. 16 | # 17 | server: https://apiserver.mycluster.com:8443 18 | 19 | # Optional (but recommended): configure the certificate authority to verify the 20 | # API server connection. (Environment: $TS_CAFILE.) 21 | cafile: /mnt/c/Users/ft/.kube/kube-prod.ca 22 | 23 | # Optional: configure the TLS certificate and key to authenticate to the 24 | # API server. (Environment: $TS_CERTFILE, $TS_KEYFILE.) 25 | certfile: /mnt/c/Users/ft/.kube/kube-prod.crt 26 | keyfile: /mnt/c/Users/ft/.kube/kube-prod.key 27 | 28 | # Optional: configure the bearer token to authenticate to the API server. 29 | # (Environment: $TS_TOKEN.) 30 | #token: ABCD1234 31 | 32 | # If true (the default), the TLS server certificate of the API server will be 33 | # verified. This is strongly recommended and there should be no reason to 34 | # disable it. (Environment: $TS_VERIFY_TLS.) 35 | #verify_tls: true 36 | 37 | # If you want to change the default ingress class(es), set this. 38 | # (Environment: $TS_INGRESS_CLASSES.) 39 | #ingress_classes: trafficserver nginx 40 | 41 | ### TLS configuration 42 | 43 | # Set this to false to disable TLS. (Environment: $TS_TLS.) 44 | #tls: false 45 | 46 | # Set this to false to disable sending the X-Forwarded-Proto header to the 47 | # backend, indicating the client protocol ("http" or "https"). If this is 48 | # enabled (the default), any existing header in the request will be removed. 49 | #x_forwarded_proto: false 50 | 51 | ### Remap configuration 52 | 53 | # Set this to false to disable remapping. (Environment: $TS_REMAP.) 54 | #remap: false 55 | -------------------------------------------------------------------------------- /contrib/brotli/common/dictionary.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Google Inc. All Rights Reserved. 2 | 3 | Distributed under MIT license. 4 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 5 | */ 6 | 7 | /* Collection of static dictionary words. */ 8 | 9 | #ifndef BROTLI_COMMON_DICTIONARY_H_ 10 | #define BROTLI_COMMON_DICTIONARY_H_ 11 | 12 | #include 13 | #include 14 | 15 | #if defined(__cplusplus) || defined(c_plusplus) 16 | extern "C" { 17 | #endif 18 | 19 | typedef struct BrotliDictionary { 20 | /** 21 | * Number of bits to encode index of dictionary word in a bucket. 22 | * 23 | * Specification: Appendix A. Static Dictionary Data 24 | * 25 | * Words in a dictionary are bucketed by length. 26 | * @c 0 means that there are no words of a given length. 27 | * Dictionary consists of words with length of [4..24] bytes. 28 | * Values at [0..3] and [25..31] indices should not be addressed. 29 | */ 30 | const uint8_t size_bits_by_length[32]; 31 | 32 | /* assert(offset[i + 1] == offset[i] + (bits[i] ? (i << bits[i]) : 0)) */ 33 | const uint32_t offsets_by_length[32]; 34 | 35 | /* assert(data_size == offsets_by_length[31]) */ 36 | const size_t data_size; 37 | 38 | /* Data array is not bound, and should obey to size_bits_by_length values. 39 | Specified size matches default (RFC 7932) dictionary. Its size is 40 | defined by data_size */ 41 | const uint8_t* data; 42 | } BrotliDictionary; 43 | 44 | BROTLI_COMMON_API extern const BrotliDictionary* BrotliGetDictionary(void); 45 | 46 | /** 47 | * Sets dictionary data. 48 | * 49 | * When dictionary data is already set / present, this method is no-op. 50 | * 51 | * Dictionary data MUST be provided before BrotliGetDictionary is invoked. 52 | * This method is used ONLY in multi-client environment (e.g. C + Java), 53 | * to reduce storage by sharing single dictionary between implementations. 54 | */ 55 | BROTLI_COMMON_API void BrotliSetDictionaryData(const uint8_t* data); 56 | 57 | #define BROTLI_MIN_DICTIONARY_WORD_LENGTH 4 58 | #define BROTLI_MAX_DICTIONARY_WORD_LENGTH 24 59 | 60 | #if defined(__cplusplus) || defined(c_plusplus) 61 | } /* extern "C" */ 62 | #endif 63 | 64 | #endif /* BROTLI_COMMON_DICTIONARY_H_ */ 65 | -------------------------------------------------------------------------------- /gtest/include/gtest/internal/custom/gtest-printers.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // This file provides an injection point for custom printers in a local 31 | // installation of gTest. 32 | // It will be included from gtest-printers.h and the overrides in this file 33 | // will be visible to everyone. 34 | // See documentation at gtest/gtest-printers.h for details on how to define a 35 | // custom printer. 36 | // 37 | // ** Custom implementation starts here ** 38 | 39 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ 40 | #define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ 41 | 42 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ 43 | -------------------------------------------------------------------------------- /tests/records.config: -------------------------------------------------------------------------------- 1 | # TS records.config for end-to-end testing. 2 | 3 | CONFIG proxy.config.http.server_ports STRING 58080 58443:ssl 4 | CONFIG proxy.config.http.cache.http INT 1 5 | CONFIG proxy.config.diags.debug.enabled INT 1 6 | CONFIG proxy.config.diags.debug.tags STRING kubernetes.* 7 | 8 | ############################################################################## 9 | # Cache control. Docs: 10 | # https://docs.trafficserver.apache.org/records.config#cache-control 11 | # https://docs.trafficserver.apache.org/en/latest/admin-guide/files/cache.config.en.html 12 | ############################################################################## 13 | CONFIG proxy.config.http.cache.ignore_client_cc_max_age INT 1 14 | CONFIG proxy.config.http.normalize_ae_gzip INT 0 15 | CONFIG proxy.config.http.cache.cache_responses_to_cookies INT 1 16 | CONFIG proxy.config.http.cache.cache_urls_that_look_dynamic INT 1 17 | # https://docs.trafficserver.apache.org/records.config#proxy-config-http-cache-when-to-revalidate 18 | CONFIG proxy.config.http.cache.when_to_revalidate INT 0 19 | # https://docs.trafficserver.apache.org/records.config#proxy-config-http-cache-required-headers 20 | CONFIG proxy.config.http.cache.required_headers INT 2 21 | 22 | CONFIG proxy.config.url_remap.remap_required INT 1 23 | CONFIG proxy.config.url_remap.pristine_host_hdr INT 1 24 | CONFIG proxy.config.reverse_proxy.enabled INT 1 25 | 26 | CONFIG proxy.config.ssl.client.verify.server INT 0 27 | CONFIG proxy.config.ssl.client.CA.cert.filename STRING NULL 28 | CONFIG proxy.config.ssl.server.cipher_suite STRING ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-DSS-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA 29 | -------------------------------------------------------------------------------- /gtest/src/gtest-all.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: mheule@google.com (Markus Heule) 31 | // 32 | // Google C++ Testing Framework (Google Test) 33 | // 34 | // Sometimes it's desirable to build Google Test by compiling a single file. 35 | // This file serves this purpose. 36 | 37 | // This line ensures that gtest.h can be compiled on its own, even 38 | // when it's fused. 39 | #include "gtest/gtest.h" 40 | 41 | // The following lines pull in the real gtest *.cc files. 42 | #include "src/gtest.cc" 43 | #include "src/gtest-death-test.cc" 44 | #include "src/gtest-filepath.cc" 45 | #include "src/gtest-port.cc" 46 | #include "src/gtest-printers.cc" 47 | #include "src/gtest-test-part.cc" 48 | #include "src/gtest-typed-test.cc" 49 | -------------------------------------------------------------------------------- /contrib/brotli/common/constants.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2016 Google Inc. All Rights Reserved. 2 | 3 | Distributed under MIT license. 4 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 5 | */ 6 | 7 | #ifndef BROTLI_COMMON_CONSTANTS_H_ 8 | #define BROTLI_COMMON_CONSTANTS_H_ 9 | 10 | /* Specification: 7.3. Encoding of the context map */ 11 | #define BROTLI_CONTEXT_MAP_MAX_RLE 16 12 | 13 | /* Specification: 2. Compressed representation overview */ 14 | #define BROTLI_MAX_NUMBER_OF_BLOCK_TYPES 256 15 | 16 | /* Specification: 3.3. Alphabet sizes: insert-and-copy length */ 17 | #define BROTLI_NUM_LITERAL_SYMBOLS 256 18 | #define BROTLI_NUM_COMMAND_SYMBOLS 704 19 | #define BROTLI_NUM_BLOCK_LEN_SYMBOLS 26 20 | #define BROTLI_MAX_CONTEXT_MAP_SYMBOLS (BROTLI_MAX_NUMBER_OF_BLOCK_TYPES + \ 21 | BROTLI_CONTEXT_MAP_MAX_RLE) 22 | #define BROTLI_MAX_BLOCK_TYPE_SYMBOLS (BROTLI_MAX_NUMBER_OF_BLOCK_TYPES + 2) 23 | 24 | /* Specification: 3.5. Complex prefix codes */ 25 | #define BROTLI_REPEAT_PREVIOUS_CODE_LENGTH 16 26 | #define BROTLI_REPEAT_ZERO_CODE_LENGTH 17 27 | #define BROTLI_CODE_LENGTH_CODES (BROTLI_REPEAT_ZERO_CODE_LENGTH + 1) 28 | /* "code length of 8 is repeated" */ 29 | #define BROTLI_INITIAL_REPEATED_CODE_LENGTH 8 30 | 31 | /* Specification: 4. Encoding of distances */ 32 | #define BROTLI_NUM_DISTANCE_SHORT_CODES 16 33 | #define BROTLI_MAX_NPOSTFIX 3 34 | #define BROTLI_MAX_NDIRECT 120 35 | #define BROTLI_MAX_DISTANCE_BITS 24U 36 | /* BROTLI_NUM_DISTANCE_SYMBOLS == 520 */ 37 | #define BROTLI_NUM_DISTANCE_SYMBOLS (BROTLI_NUM_DISTANCE_SHORT_CODES + \ 38 | BROTLI_MAX_NDIRECT + \ 39 | (BROTLI_MAX_DISTANCE_BITS << \ 40 | (BROTLI_MAX_NPOSTFIX + 1))) 41 | 42 | /* 7.1. Context modes and context ID lookup for literals */ 43 | /* "context IDs for literals are in the range of 0..63" */ 44 | #define BROTLI_LITERAL_CONTEXT_BITS 6 45 | 46 | /* 7.2. Context ID for distances */ 47 | #define BROTLI_DISTANCE_CONTEXT_BITS 2 48 | 49 | /* 9.1. Format of the Stream Header */ 50 | /* Number of slack bytes for window size. Don't confuse 51 | with BROTLI_NUM_DISTANCE_SHORT_CODES. */ 52 | #define BROTLI_WINDOW_GAP 16 53 | #define BROTLI_MAX_BACKWARD_LIMIT(W) (((size_t)1 << (W)) - BROTLI_WINDOW_GAP) 54 | 55 | #endif /* BROTLI_COMMON_CONSTANTS_H_ */ 56 | -------------------------------------------------------------------------------- /tests/httpd.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # vim:set sw=8 ts=8 noet: 3 | # 4 | # This is a trivial HTTP server for use in tests. It only supports GET requests 5 | # and makes no attempt to validate its input or conform to any HTTP 6 | # specification. 7 | 8 | # Travis-CI won't let us remove netcat-openbsd, so instead check for the 9 | # normal version explicitly. 10 | NETCAT=nc 11 | if [ -e /bin/nc.traditional ]; then 12 | NETCAT=/bin/nc.traditional 13 | fi 14 | 15 | if [ -z "$1" ]; then 16 | echo >&2 "usage: $0 " 17 | exit 1 18 | fi 19 | 20 | port=48080 21 | [ ! -z "$2" ] && port=$2 22 | 23 | ncpid=0 24 | 25 | if [ "$1" = "handle" ]; then 26 | hasims=no 27 | read method path version 28 | 29 | while :; do 30 | read line 31 | if echo "$line" | grep -qi "If-Modified-Since:"; then 32 | hasims=yes 33 | fi 34 | 35 | if echo "$line" | grep -q '^[[:space:]]*$'; then 36 | break 37 | fi 38 | done 39 | 40 | printf >&2 'handling request.\n' 41 | 42 | if (echo "$path" | grep -q "/notmodified/") && [ $hasims = yes ]; then 43 | printf 'HTTP/1.0 304 Not modified\r\n' 44 | printf 'Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT\r\n' 45 | printf 'Connection: close\r\n' 46 | printf '\r\n\r\n' 47 | exit 0 48 | fi 49 | 50 | printf 'HTTP/1.0 200 OK\r\n' 51 | printf 'Connection: close\r\n' 52 | printf 'Content-Type: text/plain;charset=UTF-8\r\n' 53 | 54 | # Set various headers based on the request path. These are cumulative, 55 | # so a request path might be /cached/serverpush/nexthopcc/foobar. 56 | 57 | if echo "$path" | grep -q "/cached/"; then 58 | printf 'Cache-Control: public, max-age=3600\r\n' 59 | fi 60 | if echo "$path" | grep -q "/server-push/"; then 61 | printf 'Link: ; rel=preload; as=script\r\n' 62 | printf 'Link: ; rel=preload; as=script\r\n' 63 | fi 64 | if echo "$path" | grep -q "/nexthopcc/"; then 65 | printf 'Cache-Control: public, max-age=7200\r\n' 66 | printf 'X-Next-Hop-Cache-Control: no-cache, max-age=3600, public\r\n' 67 | fi 68 | if echo "$path" | grep -q "/setcookie/"; then 69 | printf 'Set-Cookie: mycookie=foobar\r\n' 70 | fi 71 | printf '\r\n' 72 | printf 'Request method: %s\n' "$method" 73 | printf 'Request path: %s\n' "$path" 74 | exit 0 75 | fi 76 | 77 | trap '[ $ncpid != 0 ] && kill $ncpid; exit 0' INT TERM EXIT 0 78 | 79 | while :; do 80 | $NETCAT -l -p $port -c "$0 handle" "$1" & ncpid=$! 81 | wait $ncpid 82 | ncpid=0 83 | done 84 | -------------------------------------------------------------------------------- /gtest/include/gtest/gtest_prod.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: wan@google.com (Zhanyong Wan) 31 | // 32 | // Google C++ Testing Framework definitions useful in production code. 33 | 34 | #ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_ 35 | #define GTEST_INCLUDE_GTEST_GTEST_PROD_H_ 36 | 37 | // When you need to test the private or protected members of a class, 38 | // use the FRIEND_TEST macro to declare your tests as friends of the 39 | // class. For example: 40 | // 41 | // class MyClass { 42 | // private: 43 | // void MyMethod(); 44 | // FRIEND_TEST(MyClassTest, MyMethod); 45 | // }; 46 | // 47 | // class MyClassTest : public testing::Test { 48 | // // ... 49 | // }; 50 | // 51 | // TEST_F(MyClassTest, MyMethod) { 52 | // // Can call MyClass::MyMethod() here. 53 | // } 54 | 55 | #define FRIEND_TEST(test_case_name, test_name)\ 56 | friend class test_case_name##_##test_name##_Test 57 | 58 | #endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_ 59 | -------------------------------------------------------------------------------- /contrib/brotli/enc/compress_fragment_two_pass.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2015 Google Inc. All Rights Reserved. 2 | 3 | Distributed under MIT license. 4 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 5 | */ 6 | 7 | /* Function for fast encoding of an input fragment, independently from the input 8 | history. This function uses two-pass processing: in the first pass we save 9 | the found backward matches and literal bytes into a buffer, and in the 10 | second pass we emit them into the bit stream using prefix codes built based 11 | on the actual command and literal byte histograms. */ 12 | 13 | #ifndef BROTLI_ENC_COMPRESS_FRAGMENT_TWO_PASS_H_ 14 | #define BROTLI_ENC_COMPRESS_FRAGMENT_TWO_PASS_H_ 15 | 16 | #include 17 | #include "./memory.h" 18 | #include "./port.h" 19 | 20 | #if defined(__cplusplus) || defined(c_plusplus) 21 | extern "C" { 22 | #endif 23 | 24 | static const size_t kCompressFragmentTwoPassBlockSize = 1 << 17; 25 | 26 | /* Compresses "input" string to the "*storage" buffer as one or more complete 27 | meta-blocks, and updates the "*storage_ix" bit position. 28 | 29 | If "is_last" is 1, emits an additional empty last meta-block. 30 | 31 | REQUIRES: "input_size" is greater than zero, or "is_last" is 1. 32 | REQUIRES: "input_size" is less or equal to maximal metablock size (1 << 24). 33 | REQUIRES: "command_buf" and "literal_buf" point to at least 34 | kCompressFragmentTwoPassBlockSize long arrays. 35 | REQUIRES: All elements in "table[0..table_size-1]" are initialized to zero. 36 | REQUIRES: "table_size" is a power of two 37 | OUTPUT: maximal copy distance <= |input_size| 38 | OUTPUT: maximal copy distance <= BROTLI_MAX_BACKWARD_LIMIT(18) */ 39 | BROTLI_INTERNAL void BrotliCompressFragmentTwoPass(MemoryManager* m, 40 | const uint8_t* input, 41 | size_t input_size, 42 | BROTLI_BOOL is_last, 43 | uint32_t* command_buf, 44 | uint8_t* literal_buf, 45 | int* table, 46 | size_t table_size, 47 | size_t* storage_ix, 48 | uint8_t* storage); 49 | 50 | #if defined(__cplusplus) || defined(c_plusplus) 51 | } /* extern "C" */ 52 | #endif 53 | 54 | #endif /* BROTLI_ENC_COMPRESS_FRAGMENT_TWO_PASS_H_ */ 55 | -------------------------------------------------------------------------------- /contrib/brotli/enc/utf8_util.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Google Inc. All Rights Reserved. 2 | 3 | Distributed under MIT license. 4 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 5 | */ 6 | 7 | /* Heuristics for deciding about the UTF8-ness of strings. */ 8 | 9 | #include "./utf8_util.h" 10 | 11 | #include 12 | 13 | #if defined(__cplusplus) || defined(c_plusplus) 14 | extern "C" { 15 | #endif 16 | 17 | static size_t BrotliParseAsUTF8( 18 | int* symbol, const uint8_t* input, size_t size) { 19 | /* ASCII */ 20 | if ((input[0] & 0x80) == 0) { 21 | *symbol = input[0]; 22 | if (*symbol > 0) { 23 | return 1; 24 | } 25 | } 26 | /* 2-byte UTF8 */ 27 | if (size > 1u && 28 | (input[0] & 0xe0) == 0xc0 && 29 | (input[1] & 0xc0) == 0x80) { 30 | *symbol = (((input[0] & 0x1f) << 6) | 31 | (input[1] & 0x3f)); 32 | if (*symbol > 0x7f) { 33 | return 2; 34 | } 35 | } 36 | /* 3-byte UFT8 */ 37 | if (size > 2u && 38 | (input[0] & 0xf0) == 0xe0 && 39 | (input[1] & 0xc0) == 0x80 && 40 | (input[2] & 0xc0) == 0x80) { 41 | *symbol = (((input[0] & 0x0f) << 12) | 42 | ((input[1] & 0x3f) << 6) | 43 | (input[2] & 0x3f)); 44 | if (*symbol > 0x7ff) { 45 | return 3; 46 | } 47 | } 48 | /* 4-byte UFT8 */ 49 | if (size > 3u && 50 | (input[0] & 0xf8) == 0xf0 && 51 | (input[1] & 0xc0) == 0x80 && 52 | (input[2] & 0xc0) == 0x80 && 53 | (input[3] & 0xc0) == 0x80) { 54 | *symbol = (((input[0] & 0x07) << 18) | 55 | ((input[1] & 0x3f) << 12) | 56 | ((input[2] & 0x3f) << 6) | 57 | (input[3] & 0x3f)); 58 | if (*symbol > 0xffff && *symbol <= 0x10ffff) { 59 | return 4; 60 | } 61 | } 62 | /* Not UTF8, emit a special symbol above the UTF8-code space */ 63 | *symbol = 0x110000 | input[0]; 64 | return 1; 65 | } 66 | 67 | /* Returns 1 if at least min_fraction of the data is UTF8-encoded.*/ 68 | BROTLI_BOOL BrotliIsMostlyUTF8( 69 | const uint8_t* data, const size_t pos, const size_t mask, 70 | const size_t length, const double min_fraction) { 71 | size_t size_utf8 = 0; 72 | size_t i = 0; 73 | while (i < length) { 74 | int symbol; 75 | size_t bytes_read = 76 | BrotliParseAsUTF8(&symbol, &data[(pos + i) & mask], length - i); 77 | i += bytes_read; 78 | if (symbol < 0x110000) size_utf8 += bytes_read; 79 | } 80 | return TO_BROTLI_BOOL(size_utf8 > min_fraction * (double)length); 81 | } 82 | 83 | #if defined(__cplusplus) || defined(c_plusplus) 84 | } /* extern "C" */ 85 | #endif 86 | -------------------------------------------------------------------------------- /api/configmap.c: -------------------------------------------------------------------------------- 1 | /* vim:set sw=8 ts=8 noet: */ 2 | /* 3 | * Copyright (c) 2016-2017 Torchbox Ltd. 4 | * 5 | * Permission is granted to anyone to use this software for any purpose, 6 | * including commercial applications, and to alter it and redistribute it 7 | * freely. This software is provided 'as-is', without any express or implied 8 | * warranty. 9 | */ 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | #include "api.h" 18 | #include "base64.h" 19 | 20 | void 21 | configmap_free(configmap_t *configmap) 22 | { 23 | hash_free(configmap->cm_data); 24 | free(configmap->cm_name); 25 | free(configmap->cm_namespace); 26 | free(configmap); 27 | } 28 | 29 | configmap_t * 30 | configmap_make(json_object *obj) 31 | { 32 | configmap_t *configmap = NULL; 33 | json_object *metadata, *tmp, *data; 34 | json_object_iter iter; 35 | 36 | if ((configmap = calloc(1, sizeof(*configmap))) == NULL) 37 | return NULL; 38 | 39 | configmap->cm_data = hash_new(127, free); 40 | 41 | if (!json_object_object_get_ex(obj, "metadata", &metadata) 42 | || !json_object_is_type(metadata, json_type_object)) { 43 | TSDebug("kubernetes_api", "configmap_make: no metadata! (obj: [%s]", 44 | json_object_get_string(obj)); 45 | goto error; 46 | } 47 | 48 | if (!json_object_object_get_ex(metadata, "namespace", &tmp) 49 | || !json_object_is_type(tmp, json_type_string)) { 50 | TSDebug("kubernetes_api", "configmap_make: no namespace!"); 51 | goto error; 52 | } 53 | configmap->cm_namespace = strdup(json_object_get_string(tmp)); 54 | 55 | if (!json_object_object_get_ex(metadata, "name", &tmp) 56 | || !json_object_is_type(tmp, json_type_string)) { 57 | TSDebug("kubernetes_api", "configmap_make: no name!"); 58 | goto error; 59 | } 60 | configmap->cm_name = strdup(json_object_get_string(tmp)); 61 | 62 | if (!json_object_object_get_ex(obj, "data", &data)) { 63 | TSDebug("kubernetes_api", "configmap_make: %s/%s: no data!", 64 | configmap->cm_namespace, configmap->cm_name); 65 | return configmap; 66 | } 67 | 68 | if (!json_object_is_type(data, json_type_object)) { 69 | TSDebug("kubernetes_api", "configmap_make: %s/%s: data is no object!", 70 | configmap->cm_namespace, configmap->cm_name); 71 | return configmap; 72 | } 73 | 74 | json_object_object_foreachC(data, iter) { 75 | if (!json_object_is_type(iter.val, json_type_string)) 76 | continue; 77 | 78 | hash_set(configmap->cm_data, iter.key, 79 | strdup(json_object_get_string(iter.val))); 80 | } 81 | 82 | return configmap; 83 | 84 | error: 85 | configmap_free(configmap); 86 | return NULL; 87 | } 88 | -------------------------------------------------------------------------------- /docker/trafficserver.yml: -------------------------------------------------------------------------------- 1 | # vim:set sw=2 ts=2 et 2 | 3 | apiVersion: v1 4 | kind: Service 5 | metadata: 6 | name: trafficserver 7 | namespace: kube-system 8 | spec: 9 | selector: 10 | app: trafficserver 11 | type: NodePort 12 | ports: 13 | - name: http 14 | protocol: TCP 15 | port: 80 16 | nodePort: 30080 17 | targetPort: http 18 | - name: https 19 | protocol: TCP 20 | port: 443 21 | nodePort: 30443 22 | targetPort: https 23 | 24 | --- 25 | 26 | apiVersion: extensions/v1beta1 27 | kind: Deployment 28 | metadata: 29 | name: trafficserver 30 | namespace: kube-system 31 | labels: 32 | app: trafficserver 33 | spec: 34 | replicas: 2 35 | 36 | selector: 37 | matchLabels: 38 | app: trafficserver 39 | 40 | strategy: 41 | type: RollingUpdate 42 | rollingUpdate: 43 | maxSurge: 1 44 | maxUnavailable: 0 45 | 46 | template: 47 | metadata: 48 | namespace: kube-system 49 | labels: 50 | app: trafficserver 51 | 52 | spec: 53 | 54 | volumes: 55 | - name: ts-storage 56 | emptyDir: {} 57 | 58 | containers: 59 | - name: trafficserver 60 | 61 | image: docker.io/torchbox/trafficserver-ingress-controller:latest 62 | imagePullPolicy: Always 63 | 64 | ports: 65 | - name: http 66 | protocol: TCP 67 | containerPort: 8080 68 | - name: https 69 | protocol: TCP 70 | containerPort: 8443 71 | 72 | volumeMounts: 73 | - name: ts-storage 74 | mountPath: /var/lib/trafficserver 75 | 76 | resources: 77 | limits: 78 | cpu: "1" 79 | memory: 196Mi 80 | requests: 81 | cpu: 100m 82 | memory: 128Mi 83 | 84 | livenessProbe: 85 | httpGet: 86 | path: /__trafficserver_alive 87 | port: http 88 | httpHeaders: 89 | - name: Host 90 | value: localhost 91 | initialDelaySeconds: 3 92 | timeoutSeconds: 10 93 | failureThreshold: 3 94 | successThreshold: 1 95 | periodSeconds: 3 96 | 97 | readinessProbe: 98 | httpGet: 99 | path: /__trafficserver_alive 100 | port: http 101 | httpHeaders: 102 | - name: Host 103 | value: localhost 104 | initialDelaySeconds: 3 105 | timeoutSeconds: 10 106 | failureThreshold: 3 107 | successThreshold: 1 108 | periodSeconds: 3 109 | -------------------------------------------------------------------------------- /contrib/brotli/enc/find_match_length.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2010 Google Inc. All Rights Reserved. 2 | 3 | Distributed under MIT license. 4 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 5 | */ 6 | 7 | /* Function to find maximal matching prefixes of strings. */ 8 | 9 | #ifndef BROTLI_ENC_FIND_MATCH_LENGTH_H_ 10 | #define BROTLI_ENC_FIND_MATCH_LENGTH_H_ 11 | 12 | #include 13 | #include "./port.h" 14 | 15 | #if defined(__cplusplus) || defined(c_plusplus) 16 | extern "C" { 17 | #endif 18 | 19 | /* Separate implementation for little-endian 64-bit targets, for speed. */ 20 | #if defined(__GNUC__) && defined(_LP64) && defined(IS_LITTLE_ENDIAN) 21 | 22 | static BROTLI_INLINE size_t FindMatchLengthWithLimit(const uint8_t* s1, 23 | const uint8_t* s2, 24 | size_t limit) { 25 | size_t matched = 0; 26 | size_t limit2 = (limit >> 3) + 1; /* + 1 is for pre-decrement in while */ 27 | while (BROTLI_PREDICT_TRUE(--limit2)) { 28 | if (BROTLI_PREDICT_FALSE(BROTLI_UNALIGNED_LOAD64(s2) == 29 | BROTLI_UNALIGNED_LOAD64(s1 + matched))) { 30 | s2 += 8; 31 | matched += 8; 32 | } else { 33 | uint64_t x = 34 | BROTLI_UNALIGNED_LOAD64(s2) ^ BROTLI_UNALIGNED_LOAD64(s1 + matched); 35 | size_t matching_bits = (size_t)__builtin_ctzll(x); 36 | matched += matching_bits >> 3; 37 | return matched; 38 | } 39 | } 40 | limit = (limit & 7) + 1; /* + 1 is for pre-decrement in while */ 41 | while (--limit) { 42 | if (BROTLI_PREDICT_TRUE(s1[matched] == *s2)) { 43 | ++s2; 44 | ++matched; 45 | } else { 46 | return matched; 47 | } 48 | } 49 | return matched; 50 | } 51 | #else 52 | static BROTLI_INLINE size_t FindMatchLengthWithLimit(const uint8_t* s1, 53 | const uint8_t* s2, 54 | size_t limit) { 55 | size_t matched = 0; 56 | const uint8_t* s2_limit = s2 + limit; 57 | const uint8_t* s2_ptr = s2; 58 | /* Find out how long the match is. We loop over the data 32 bits at a 59 | time until we find a 32-bit block that doesn't match; then we find 60 | the first non-matching bit and use that to calculate the total 61 | length of the match. */ 62 | while (s2_ptr <= s2_limit - 4 && 63 | BROTLI_UNALIGNED_LOAD32(s2_ptr) == 64 | BROTLI_UNALIGNED_LOAD32(s1 + matched)) { 65 | s2_ptr += 4; 66 | matched += 4; 67 | } 68 | while ((s2_ptr < s2_limit) && (s1[matched] == *s2_ptr)) { 69 | ++s2_ptr; 70 | ++matched; 71 | } 72 | return matched; 73 | } 74 | #endif 75 | 76 | #if defined(__cplusplus) || defined(c_plusplus) 77 | } /* extern "C" */ 78 | #endif 79 | 80 | #endif /* BROTLI_ENC_FIND_MATCH_LENGTH_H_ */ 81 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | dnl vim:set sw=8 ts=8 noet: 2 | dnl 3 | dnl Copyright (c) 2016-2017 Torchbox Ltd. 4 | dnl 5 | dnl Permission is granted to anyone to use this software for any purpose, 6 | dnl including commercial applications, and to alter it and redistribute it 7 | dnl freely. 8 | dnl 9 | dnl THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 10 | dnl IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 11 | dnl FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 12 | dnl AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 13 | dnl LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 14 | dnl OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 15 | dnl SOFTWARE. 16 | 17 | AC_INIT([k8s-ts-ingress], [1.0.0-alpha9]) 18 | 19 | AC_CANONICAL_BUILD 20 | AC_CANONICAL_HOST 21 | 22 | AC_CONFIG_MACRO_DIRS([acinclude]) 23 | AC_CONFIG_HEADERS([autoconf.h]) 24 | 25 | BUILD_ID=unknown 26 | AC_ARG_WITH([build-id], 27 | [AS_HELP_STRING([--with-build-id=ID], [set build id])], 28 | [BUILD_ID="$withval"]) 29 | AS_IF([test "$BUILD_ID" != "unknown"], [ 30 | AC_DEFINE_UNQUOTED([BUILD_ID], ["$BUILD_ID"], [Numeric id of this build]) 31 | ]) 32 | 33 | AC_ARG_WITH([tsxs], 34 | [AS_HELP_STRING([--with-tsxs[=PATH]], [path to Traffic Server tsxs])], 35 | [TSXS="$withval"]) 36 | 37 | AS_IF([test -n "$TSXS" -a -x "$TSXS"], [ 38 | AC_SUBST(TSXS) 39 | ], [ 40 | TSXS=tsxs 41 | AC_CHECK_PROG(HAVE_TSXS, $TSXS, yes, no) 42 | 43 | AS_IF([test "${HAVE_TSXS}" != "yes"], [ 44 | AC_ERROR([could not find tsxs; maybe you need --with-tsxs=/path/to/tsxs]) 45 | ]) 46 | ]) 47 | 48 | PIC_FLAG=-fPIC 49 | AC_ARG_WITH([cc-pic-flag], 50 | [AS_HELP_STRING([--with-cc-pic-flag[=FLAG]], 51 | [cc flag to produce position independent code [-fPIC]])], 52 | [PIC_FLAG="$withval"]) 53 | CFLAGS="$CFLAGS $PIC_FLAG" 54 | 55 | TS_CC=`$TSXS -q CC` 56 | TS_CXX=`$TSXS -q CXX` 57 | TS_CFLAGS=`$TSXS -q CFLAGS` 58 | TS_CXXFLAGS=`$TSXS -q CXXFLAGS` 59 | TS_INCDIR=`$TSXS -q INCLUDEDIR` 60 | TS_PLUGINDIR=`$TSXS -q LIBEXECDIR` 61 | AC_SUBST(TS_CFLAGS) 62 | AC_SUBST(TS_CXXFLAGS) 63 | AC_SUBST(TS_INCDIR) 64 | AC_SUBST(TS_PLUGINDIR) 65 | 66 | AC_LANG_C 67 | AC_PROG_CC([$TS_CC]) 68 | AC_PROG_CC_C99 69 | AS_IF([test "$ac_cv_prog_cc_c99" = "no" ], [ 70 | AC_ERROR([a C99 compiler is required to build this plugin]) 71 | ]) 72 | 73 | AC_PROG_CXX([$TS_CXX]) 74 | 75 | PKG_CHECK_MODULES(JSON, json-c) 76 | AC_SUBST([JSON_CFLAGS]) 77 | AC_SUBST([JSON_LIBS]) 78 | 79 | ACX_PTHREAD 80 | 81 | PKG_CHECK_MODULES(ZLIB, zlib, [], [ 82 | AC_CHECK_LIB(z, deflateInit2, [], [AC_ERROR([could not find zlib])]) 83 | ]) 84 | 85 | AC_CHECK_LIB(ssl, SSL_CTX_new, [], [AC_ERROR([could not find OpenSSL])]) 86 | AC_CHECK_LIB(crypto, MD5_Update, [], [AC_ERROR([could not find OpenSSL])]) 87 | 88 | LIBCURL_CHECK_CONFIG([], [], [], [ 89 | AC_MSG_ERROR([libcurl is required to build]) 90 | ]) 91 | 92 | AC_OUTPUT([Makefile contrib/brotli/Makefile]) 93 | -------------------------------------------------------------------------------- /contrib/brotli/enc/compress_fragment.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2015 Google Inc. All Rights Reserved. 2 | 3 | Distributed under MIT license. 4 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 5 | */ 6 | 7 | /* Function for fast encoding of an input fragment, independently from the input 8 | history. This function uses one-pass processing: when we find a backward 9 | match, we immediately emit the corresponding command and literal codes to 10 | the bit stream. */ 11 | 12 | #ifndef BROTLI_ENC_COMPRESS_FRAGMENT_H_ 13 | #define BROTLI_ENC_COMPRESS_FRAGMENT_H_ 14 | 15 | #include 16 | #include "./memory.h" 17 | #include "./port.h" 18 | 19 | #if defined(__cplusplus) || defined(c_plusplus) 20 | extern "C" { 21 | #endif 22 | 23 | /* Compresses "input" string to the "*storage" buffer as one or more complete 24 | meta-blocks, and updates the "*storage_ix" bit position. 25 | 26 | If "is_last" is 1, emits an additional empty last meta-block. 27 | 28 | "cmd_depth" and "cmd_bits" contain the command and distance prefix codes 29 | (see comment in encode.h) used for the encoding of this input fragment. 30 | If "is_last" is 0, they are updated to reflect the statistics 31 | of this input fragment, to be used for the encoding of the next fragment. 32 | 33 | "*cmd_code_numbits" is the number of bits of the compressed representation 34 | of the command and distance prefix codes, and "cmd_code" is an array of 35 | at least "(*cmd_code_numbits + 7) >> 3" size that contains the compressed 36 | command and distance prefix codes. If "is_last" is 0, these are also 37 | updated to represent the updated "cmd_depth" and "cmd_bits". 38 | 39 | REQUIRES: "input_size" is greater than zero, or "is_last" is 1. 40 | REQUIRES: "input_size" is less or equal to maximal metablock size (1 << 24). 41 | REQUIRES: All elements in "table[0..table_size-1]" are initialized to zero. 42 | REQUIRES: "table_size" is an odd (9, 11, 13, 15) power of two 43 | OUTPUT: maximal copy distance <= |input_size| 44 | OUTPUT: maximal copy distance <= BROTLI_MAX_BACKWARD_LIMIT(18) */ 45 | BROTLI_INTERNAL void BrotliCompressFragmentFast(MemoryManager* m, 46 | const uint8_t* input, 47 | size_t input_size, 48 | BROTLI_BOOL is_last, 49 | int* table, size_t table_size, 50 | uint8_t cmd_depth[128], 51 | uint16_t cmd_bits[128], 52 | size_t* cmd_code_numbits, 53 | uint8_t* cmd_code, 54 | size_t* storage_ix, 55 | uint8_t* storage); 56 | 57 | #if defined(__cplusplus) || defined(c_plusplus) 58 | } /* extern "C" */ 59 | #endif 60 | 61 | #endif /* BROTLI_ENC_COMPRESS_FRAGMENT_H_ */ 62 | -------------------------------------------------------------------------------- /contrib/brotli/enc/write_bits.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2010 Google Inc. All Rights Reserved. 2 | 3 | Distributed under MIT license. 4 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 5 | */ 6 | 7 | /* Write bits into a byte array. */ 8 | 9 | #ifndef BROTLI_ENC_WRITE_BITS_H_ 10 | #define BROTLI_ENC_WRITE_BITS_H_ 11 | 12 | #include 13 | #include /* printf */ 14 | 15 | #include 16 | #include "./port.h" 17 | 18 | #if defined(__cplusplus) || defined(c_plusplus) 19 | extern "C" { 20 | #endif 21 | 22 | /*#define BIT_WRITER_DEBUG */ 23 | 24 | /* This function writes bits into bytes in increasing addresses, and within 25 | a byte least-significant-bit first. 26 | 27 | The function can write up to 56 bits in one go with WriteBits 28 | Example: let's assume that 3 bits (Rs below) have been written already: 29 | 30 | BYTE-0 BYTE+1 BYTE+2 31 | 32 | 0000 0RRR 0000 0000 0000 0000 33 | 34 | Now, we could write 5 or less bits in MSB by just sifting by 3 35 | and OR'ing to BYTE-0. 36 | 37 | For n bits, we take the last 5 bits, OR that with high bits in BYTE-0, 38 | and locate the rest in BYTE+1, BYTE+2, etc. */ 39 | static BROTLI_INLINE void BrotliWriteBits(size_t n_bits, 40 | uint64_t bits, 41 | size_t * BROTLI_RESTRICT pos, 42 | uint8_t * BROTLI_RESTRICT array) { 43 | #ifdef IS_LITTLE_ENDIAN 44 | /* This branch of the code can write up to 56 bits at a time, 45 | 7 bits are lost by being perhaps already in *p and at least 46 | 1 bit is needed to initialize the bit-stream ahead (i.e. if 7 47 | bits are in *p and we write 57 bits, then the next write will 48 | access a byte that was never initialized). */ 49 | uint8_t *p = &array[*pos >> 3]; 50 | uint64_t v = *p; 51 | #ifdef BIT_WRITER_DEBUG 52 | printf("WriteBits %2d 0x%016llx %10d\n", n_bits, bits, *pos); 53 | #endif 54 | assert((bits >> n_bits) == 0); 55 | assert(n_bits <= 56); 56 | v |= bits << (*pos & 7); 57 | BROTLI_UNALIGNED_STORE64(p, v); /* Set some bits. */ 58 | *pos += n_bits; 59 | #else 60 | /* implicit & 0xff is assumed for uint8_t arithmetics */ 61 | uint8_t *array_pos = &array[*pos >> 3]; 62 | const size_t bits_reserved_in_first_byte = (*pos & 7); 63 | size_t bits_left_to_write; 64 | bits <<= bits_reserved_in_first_byte; 65 | *array_pos++ |= (uint8_t)bits; 66 | for (bits_left_to_write = n_bits + bits_reserved_in_first_byte; 67 | bits_left_to_write >= 9; 68 | bits_left_to_write -= 8) { 69 | bits >>= 8; 70 | *array_pos++ = (uint8_t)bits; 71 | } 72 | *array_pos = 0; 73 | *pos += n_bits; 74 | #endif 75 | } 76 | 77 | static BROTLI_INLINE void BrotliWriteBitsPrepareStorage( 78 | size_t pos, uint8_t *array) { 79 | #ifdef BIT_WRITER_DEBUG 80 | printf("WriteBitsPrepareStorage %10d\n", pos); 81 | #endif 82 | assert((pos & 7) == 0); 83 | array[pos >> 3] = 0; 84 | } 85 | 86 | #if defined(__cplusplus) || defined(c_plusplus) 87 | } /* extern "C" */ 88 | #endif 89 | 90 | #endif /* BROTLI_ENC_WRITE_BITS_H_ */ 91 | -------------------------------------------------------------------------------- /tests/e2e/002-tls/run.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # vim:set sw=8 ts=8 noet: 3 | 4 | # Test basic functionality, i.e. that routing requests to an endpoint works. 5 | 6 | expect_output() { 7 | if echo "$output" | egrep -q "$@"; then 8 | return 0 9 | else 10 | echo "Failed: output did not include test string: [$*]" 11 | echo "Test output: [$output]" 12 | exit 1 13 | fi 14 | } 15 | 16 | # Basic TLS test. 17 | printf '.' 18 | output=$(curl 2>&1 -sS --cacert tests/test-cert.pem \ 19 | --resolve echoheaders.test:58443:127.0.0.1 \ 20 | https://echoheaders.test:58443/this-is-a-test) 21 | expect_output "Request path: /this-is-a-test" 22 | 23 | # Test minimum TLS 1.0. 24 | printf '.' 25 | output=$(curl 2>&1 -kvisS --tlsv1.0 --resolve tls10.echoheaders.test:58443:127.0.0.1 \ 26 | https://tls10.echoheaders.test:58443/) 27 | expect_output 'HTTP/[012.]* 200' 28 | 29 | printf '.' 30 | output=$(curl 2>&1 -kvisS --tlsv1.1 --resolve tls10.echoheaders.test:58443:127.0.0.1 \ 31 | https://tls10.echoheaders.test:58443/) 32 | expect_output 'HTTP/[012.]* 200' 33 | 34 | printf '.' 35 | output=$(curl 2>&1 -kvisS --tlsv1.2 --resolve tls10.echoheaders.test:58443:127.0.0.1 \ 36 | https://tls10.echoheaders.test:58443/) 37 | expect_output 'HTTP/[012.]* 200' 38 | 39 | # Test minimum TLS 1.1. 40 | printf '.' 41 | output=$(curl 2>&1 -kvisS --tlsv1.0 --resolve tls11.echoheaders.test:58443:127.0.0.1 \ 42 | https://tls11.echoheaders.test:58443/) 43 | expect_output 'alert handshake failure' 44 | expect_output -v 'HTTP/[012.]* 200' 45 | 46 | printf '.' 47 | output=$(curl 2>&1 -kvisS --tlsv1.1 --resolve tls11.echoheaders.test:58443:127.0.0.1 \ 48 | https://tls11.echoheaders.test:58443/) 49 | expect_output 'HTTP/[012.]* 200' 50 | 51 | printf '.' 52 | output=$(curl 2>&1 -kvisS --tlsv1.2 --resolve tls11.echoheaders.test:58443:127.0.0.1 \ 53 | https://tls11.echoheaders.test:58443/) 54 | expect_output 'HTTP/[012.]* 200' 55 | 56 | # Test minimum TLS 1.2. 57 | printf '.' 58 | output=$(curl 2>&1 -kvisS --tlsv1.0 --resolve tls12.echoheaders.test:58443:127.0.0.1 \ 59 | https://tls12.echoheaders.test:58443/) 60 | expect_output 'alert handshake failure' 61 | expect_output -v 'HTTP/[012.]* 200' 62 | 63 | printf '.' 64 | output=$(curl 2>&1 -kvisS --tlsv1.1 --resolve tls12.echoheaders.test:58443:127.0.0.1 \ 65 | https://tls12.echoheaders.test:58443/) 66 | expect_output 'alert handshake failure' 67 | expect_output -v 'HTTP/[012.]* 200' 68 | 69 | printf '.' 70 | output=$(curl 2>&1 -kvisS --tlsv1.2 --resolve tls12.echoheaders.test:58443:127.0.0.1 \ 71 | https://tls12.echoheaders.test:58443/) 72 | expect_output 'HTTP/[012.]* 200' 73 | 74 | # Test default TLS. 75 | printf '.' 76 | output=$(curl 2>&1 -ksS --cacert tests/test-cert.pem \ 77 | --resolve default.echoheaders.test:58443:127.0.0.1 \ 78 | https://default.echoheaders.test:58443/this-is-a-test) 79 | expect_output "Request path: /this-is-a-test" 80 | 81 | printf '.' 82 | output=$(curl 2>&1 -ksS --cacert tests/test-cert.pem \ 83 | --resolve notdefault.echoheaders.test:58443:127.0.0.1 \ 84 | https://notdefault.echoheaders.test:58443/this-is-a-test) 85 | expect_output 'alert handshake failure' 86 | expect_output -v "Request path: /this-is-a-test" 87 | -------------------------------------------------------------------------------- /contrib/brotli/include/brotli/types.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Google Inc. All Rights Reserved. 2 | 3 | Distributed under MIT license. 4 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 5 | */ 6 | 7 | /** 8 | * @file 9 | * Common types used in decoder and encoder API. 10 | */ 11 | 12 | #ifndef BROTLI_COMMON_TYPES_H_ 13 | #define BROTLI_COMMON_TYPES_H_ 14 | 15 | #include /* for size_t */ 16 | 17 | #if defined(_MSC_VER) && (_MSC_VER < 1600) 18 | typedef __int8 int8_t; 19 | typedef unsigned __int8 uint8_t; 20 | typedef __int16 int16_t; 21 | typedef unsigned __int16 uint16_t; 22 | typedef __int32 int32_t; 23 | typedef unsigned __int32 uint32_t; 24 | typedef unsigned __int64 uint64_t; 25 | typedef __int64 int64_t; 26 | #else 27 | #include 28 | #endif /* defined(_MSC_VER) && (_MSC_VER < 1600) */ 29 | 30 | /** 31 | * A portable @c bool replacement. 32 | * 33 | * ::BROTLI_BOOL is a "documentation" type: actually it is @c int, but in API it 34 | * denotes a type, whose only values are ::BROTLI_TRUE and ::BROTLI_FALSE. 35 | * 36 | * ::BROTLI_BOOL values passed to Brotli should either be ::BROTLI_TRUE or 37 | * ::BROTLI_FALSE, or be a result of ::TO_BROTLI_BOOL macros. 38 | * 39 | * ::BROTLI_BOOL values returned by Brotli should not be tested for equality 40 | * with @c true, @c false, ::BROTLI_TRUE, ::BROTLI_FALSE, but rather should be 41 | * evaluated, for example: @code{.cpp} 42 | * if (SomeBrotliFunction(encoder, BROTLI_TRUE) && 43 | * !OtherBrotliFunction(decoder, BROTLI_FALSE)) { 44 | * bool x = !!YetAnotherBrotliFunction(encoder, TO_BROLTI_BOOL(2 * 2 == 4)); 45 | * DoSomething(x); 46 | * } 47 | * @endcode 48 | */ 49 | #define BROTLI_BOOL int 50 | /** Portable @c true replacement. */ 51 | #define BROTLI_TRUE 1 52 | /** Portable @c false replacement. */ 53 | #define BROTLI_FALSE 0 54 | /** @c bool to ::BROTLI_BOOL conversion macros. */ 55 | #define TO_BROTLI_BOOL(X) (!!(X) ? BROTLI_TRUE : BROTLI_FALSE) 56 | 57 | #define BROTLI_MAKE_UINT64_T(high, low) ((((uint64_t)(high)) << 32) | low) 58 | 59 | #define BROTLI_UINT32_MAX (~((uint32_t)0)) 60 | #define BROTLI_SIZE_MAX (~((size_t)0)) 61 | 62 | /** 63 | * Allocating function pointer type. 64 | * 65 | * @param opaque custom memory manager handle provided by client 66 | * @param size requested memory region size; can not be @c 0 67 | * @returns @c 0 in the case of failure 68 | * @returns a valid pointer to a memory region of at least @p size bytes 69 | * long otherwise 70 | */ 71 | typedef void* (*brotli_alloc_func)(void* opaque, size_t size); 72 | 73 | /** 74 | * Deallocating function pointer type. 75 | * 76 | * This function @b SHOULD do nothing if @p address is @c 0. 77 | * 78 | * @param opaque custom memory manager handle provided by client 79 | * @param address memory region pointer returned by ::brotli_alloc_func, or @c 0 80 | */ 81 | typedef void (*brotli_free_func)(void* opaque, void* address); 82 | 83 | #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ 84 | !defined(__cplusplus) && !defined(__PGI) 85 | #define BROTLI_ARRAY_PARAM(L) L 86 | #else 87 | #define BROTLI_ARRAY_PARAM(L) 88 | #endif 89 | 90 | #endif /* BROTLI_COMMON_TYPES_H_ */ 91 | -------------------------------------------------------------------------------- /autoconf.h.in: -------------------------------------------------------------------------------- 1 | /* autoconf.h.in. Generated from configure.ac by autoheader. */ 2 | 3 | /* Numeric id of this build */ 4 | #undef BUILD_ID 5 | 6 | /* Define to 1 if you have the `crypto' library (-lcrypto). */ 7 | #undef HAVE_LIBCRYPTO 8 | 9 | /* Define to 1 if you have a functional curl library. */ 10 | #undef HAVE_LIBCURL 11 | 12 | /* Define to 1 if you have the `ssl' library (-lssl). */ 13 | #undef HAVE_LIBSSL 14 | 15 | /* Define to 1 if you have the `z' library (-lz). */ 16 | #undef HAVE_LIBZ 17 | 18 | /* Define if you have POSIX threads libraries and header files. */ 19 | #undef HAVE_PTHREAD 20 | 21 | /* Defined if libcurl supports AsynchDNS */ 22 | #undef LIBCURL_FEATURE_ASYNCHDNS 23 | 24 | /* Defined if libcurl supports IDN */ 25 | #undef LIBCURL_FEATURE_IDN 26 | 27 | /* Defined if libcurl supports IPv6 */ 28 | #undef LIBCURL_FEATURE_IPV6 29 | 30 | /* Defined if libcurl supports KRB4 */ 31 | #undef LIBCURL_FEATURE_KRB4 32 | 33 | /* Defined if libcurl supports libz */ 34 | #undef LIBCURL_FEATURE_LIBZ 35 | 36 | /* Defined if libcurl supports NTLM */ 37 | #undef LIBCURL_FEATURE_NTLM 38 | 39 | /* Defined if libcurl supports SSL */ 40 | #undef LIBCURL_FEATURE_SSL 41 | 42 | /* Defined if libcurl supports SSPI */ 43 | #undef LIBCURL_FEATURE_SSPI 44 | 45 | /* Defined if libcurl supports DICT */ 46 | #undef LIBCURL_PROTOCOL_DICT 47 | 48 | /* Defined if libcurl supports FILE */ 49 | #undef LIBCURL_PROTOCOL_FILE 50 | 51 | /* Defined if libcurl supports FTP */ 52 | #undef LIBCURL_PROTOCOL_FTP 53 | 54 | /* Defined if libcurl supports FTPS */ 55 | #undef LIBCURL_PROTOCOL_FTPS 56 | 57 | /* Defined if libcurl supports HTTP */ 58 | #undef LIBCURL_PROTOCOL_HTTP 59 | 60 | /* Defined if libcurl supports HTTPS */ 61 | #undef LIBCURL_PROTOCOL_HTTPS 62 | 63 | /* Defined if libcurl supports IMAP */ 64 | #undef LIBCURL_PROTOCOL_IMAP 65 | 66 | /* Defined if libcurl supports LDAP */ 67 | #undef LIBCURL_PROTOCOL_LDAP 68 | 69 | /* Defined if libcurl supports POP3 */ 70 | #undef LIBCURL_PROTOCOL_POP3 71 | 72 | /* Defined if libcurl supports RTSP */ 73 | #undef LIBCURL_PROTOCOL_RTSP 74 | 75 | /* Defined if libcurl supports SMTP */ 76 | #undef LIBCURL_PROTOCOL_SMTP 77 | 78 | /* Defined if libcurl supports TELNET */ 79 | #undef LIBCURL_PROTOCOL_TELNET 80 | 81 | /* Defined if libcurl supports TFTP */ 82 | #undef LIBCURL_PROTOCOL_TFTP 83 | 84 | /* Define to the address where bug reports for this package should be sent. */ 85 | #undef PACKAGE_BUGREPORT 86 | 87 | /* Define to the full name of this package. */ 88 | #undef PACKAGE_NAME 89 | 90 | /* Define to the full name and version of this package. */ 91 | #undef PACKAGE_STRING 92 | 93 | /* Define to the one symbol short name of this package. */ 94 | #undef PACKAGE_TARNAME 95 | 96 | /* Define to the home page for this package. */ 97 | #undef PACKAGE_URL 98 | 99 | /* Define to the version of this package. */ 100 | #undef PACKAGE_VERSION 101 | 102 | /* Define to the necessary symbol if this constant uses a non-standard name on 103 | your system. */ 104 | #undef PTHREAD_CREATE_JOINABLE 105 | 106 | /* Define curl_free() as free() if our version of curl lacks curl_free. */ 107 | #undef curl_free 108 | -------------------------------------------------------------------------------- /docs/external.md: -------------------------------------------------------------------------------- 1 | # Proxying to external services 2 | 3 | Sometimes, you might want to proxy traffic to a service that doesn't run as a 4 | Kubernetes pod. This can be used to expose external services via an Ingress, 5 | and to allow the `follow-redirects` annotation to access external resources. 6 | 7 | ## External proxying via IP address 8 | 9 | To proxy requests to a particular IP address or a set of IP address, create a 10 | `Service` resource without a selector, and create its associated `Endpoints` 11 | resource: 12 | 13 | ```yaml 14 | kind: Service 15 | apiVersion: v1 16 | metadata: 17 | name: external-service 18 | spec: 19 | ports: 20 | - protocol: TCP 21 | port: 80 22 | 23 | --- 24 | 25 | kind: Endpoints 26 | apiVersion: v1 27 | metadata: 28 | name: external-service 29 | subsets: 30 | - addresses: 31 | - ip: 1.2.3.4 32 | ports: 33 | - port: 80 34 | ``` 35 | 36 | You can now define an Ingress to route traffic to this service: 37 | 38 | ```yaml 39 | apiVersion: extensions/v1beta1 40 | kind: Ingress 41 | metadata: 42 | name: external-ingress 43 | spec: 44 | rules: 45 | - host: external.example.com 46 | http: 47 | paths: 48 | - backend: 49 | serviceName: external-service 50 | servicePort: 80 51 | ``` 52 | 53 | Traffic Server will now route requests for `http://external.example.com/` to your 54 | external service at IP address `1.2.3.4`. 55 | 56 | ## External proxying via hostname 57 | 58 | To proxy to an external hostname, create a `Service` resource of type 59 | `ExternalName`: 60 | 61 | ```yaml 62 | kind: Service 63 | apiVersion: v1 64 | metadata: 65 | name: external-service 66 | spec: 67 | type: ExternalName 68 | externalName: my-external-backend.example.com 69 | ``` 70 | 71 | You do not need to configure an `Endpoints` resource as with an external IP 72 | address. Create an Ingress for this Service: 73 | 74 | ```yaml 75 | apiVersion: extensions/v1beta1 76 | kind: Ingress 77 | metadata: 78 | name: external-ingress 79 | annotations: 80 | ingress.kubernetes.io/preserve-host: "false" 81 | spec: 82 | rules: 83 | - host: external.example.com 84 | http: 85 | paths: 86 | - backend: 87 | serviceName: external-service 88 | servicePort: 80 89 | ``` 90 | 91 | Now requests for `http://external.example.com` will be proxied to 92 | `http://my-external-backend.example.com`. 93 | 94 | When using an ExternalName Service, the `servicePort` must be an integer; 95 | named ports are not supported. 96 | 97 | In most cases, you will want to set the `preserve-host` annotation to `"false"` 98 | so that the external service sees the hostname it's expecting, rather than the 99 | hostname in the client request. 100 | 101 | ## External proxying and TLS 102 | 103 | By default, even if a request uses TLS, it will be proxied to the external 104 | backend via HTTP. To use TLS for the backend, set an annotation on the Ingress: 105 | `ingress.kubernetes.io/secure-backends: "true"`. This is not very useful for 106 | external IP addresses, because it's unlikely the backend will have a TLS 107 | certificate for its IP address, but it will work well with `ExternalName` 108 | services. 109 | 110 | For TLS to work, remember to set `servicePort` to `443` (or some other suitable 111 | value). 112 | 113 | 114 | -------------------------------------------------------------------------------- /docs/serverpush.md: -------------------------------------------------------------------------------- 1 | # HTTP/2 Server Push 2 | 3 | HTTP/2 server push is a mechanism to allow a server to return multiple documents 4 | in response to a single HTTP request. Server push can be used to improve page 5 | load performance when the server knows that a client requesting one document 6 | will also request another document; for example, when the client requests an HTML 7 | page, the server might also include the page's assets in its response. This 8 | avoids the need for the client to download and parse the HTML before requesting 9 | the assets, reducing the total number of HTTP transactions and improving the 10 | page load time. 11 | 12 | However, server push has the significant disadvantage that the pushed documents 13 | are _always_ sent to the client, even if the client already has them in its 14 | cache and wouldn't have requested them otherwise. Thus, pushing every asset 15 | used on a page can easily reduce performance (and waste bandwidth) by forcing 16 | the client to download objects it already has. We may look at ways of mitigating 17 | this on the server side in a future release (by detecting which assets the client 18 | might already have), but there is currently no perfect solution to this problem. 19 | 20 | Deciding when to use server push is a complicated and application-specific issue, 21 | which we won't cover here. The following article may be helpful: 22 | 23 | * [Smashing Magazine: "A Comprehensive Guide To HTTP/2 Server Push"](https://www.smashingmagazine.com/2017/04/guide-http2-server-push/) 24 | 25 | ## Configuring Server Push 26 | 27 | Server push is enabled by default. If you want to disable server push on an 28 | Ingress, use the `ingress.kubernetes.io/server-push` annotation: 29 | 30 | ```yaml 31 | metadata: 32 | annotations: 33 | ingress.kubernetes.io/server-push: "false" 34 | ``` 35 | 36 | Like other implementations, Traffic Server uses the `Link` header field in the 37 | HTTP response to determine what content to push to the client. Processing is 38 | done as soon as the response header is received, so if your application is slow 39 | to generate the response body, it can still begin pushing assets to the client 40 | once the header is sent. 41 | 42 | To push a document, include a `Link` header field in your response with the 43 | `rel=preload` attribute: 44 | 45 | ```http 46 | Link: ; rel=preload; as=style 47 | ``` 48 | 49 | The argument to the `as` attribute should be one of the standard request 50 | destinations ("audio", "document", "embed", "font", "image", "manifest", "object", 51 | "report", "script", "serviceworker", "sharedworker", "style", "track", "video", 52 | "worker", or "xslt") although TS does not enforce this and will push the object 53 | anyway. 54 | 55 | If you want to include a `rel=preload` link but not use server push for that 56 | resource, add the `nopush` attribute: 57 | 58 | ```http 59 | Link: ; rel=preload; as=image; nopush 60 | ``` 61 | 62 | ## Server Push and caching 63 | 64 | Before TS can push an object to the client, it must have a copy of the object 65 | itself. This means you should almost always enable [caching](caching.md) on 66 | assets you intend to push; otherwise, the client will have to wait while TS 67 | goes back to the application to fetch each pushed asset, and you have lost a 68 | significant fraction of the performance you might gain from using server push. 69 | -------------------------------------------------------------------------------- /gtest/include/gtest/internal/custom/gtest-port.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Injection point for custom user configurations. 31 | // The following macros can be defined: 32 | // 33 | // Flag related macros: 34 | // GTEST_FLAG(flag_name) 35 | // GTEST_USE_OWN_FLAGFILE_FLAG_ - Define to 0 when the system provides its 36 | // own flagfile flag parsing. 37 | // GTEST_DECLARE_bool_(name) 38 | // GTEST_DECLARE_int32_(name) 39 | // GTEST_DECLARE_string_(name) 40 | // GTEST_DEFINE_bool_(name, default_val, doc) 41 | // GTEST_DEFINE_int32_(name, default_val, doc) 42 | // GTEST_DEFINE_string_(name, default_val, doc) 43 | // 44 | // Test filtering: 45 | // GTEST_TEST_FILTER_ENV_VAR_ - The name of an environment variable that 46 | // will be used if --GTEST_FLAG(test_filter) 47 | // is not provided. 48 | // 49 | // Logging: 50 | // GTEST_LOG_(severity) 51 | // GTEST_CHECK_(condition) 52 | // Functions LogToStderr() and FlushInfoLog() have to be provided too. 53 | // 54 | // Threading: 55 | // GTEST_HAS_NOTIFICATION_ - Enabled if Notification is already provided. 56 | // GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ - Enabled if Mutex and ThreadLocal are 57 | // already provided. 58 | // Must also provide GTEST_DECLARE_STATIC_MUTEX_(mutex) and 59 | // GTEST_DEFINE_STATIC_MUTEX_(mutex) 60 | // 61 | // GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks) 62 | // GTEST_LOCK_EXCLUDED_(locks) 63 | // 64 | // ** Custom implementation starts here ** 65 | 66 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ 67 | #define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ 68 | 69 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ 70 | -------------------------------------------------------------------------------- /contrib/brotli/enc/histogram.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2013 Google Inc. All Rights Reserved. 2 | 3 | Distributed under MIT license. 4 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 5 | */ 6 | 7 | /* Build per-context histograms of literals, commands and distance codes. */ 8 | 9 | #include "./histogram.h" 10 | 11 | #include "./block_splitter.h" 12 | #include "./command.h" 13 | #include "./context.h" 14 | 15 | #if defined(__cplusplus) || defined(c_plusplus) 16 | extern "C" { 17 | #endif 18 | 19 | typedef struct BlockSplitIterator { 20 | const BlockSplit* split_; /* Not owned. */ 21 | size_t idx_; 22 | size_t type_; 23 | size_t length_; 24 | } BlockSplitIterator; 25 | 26 | static void InitBlockSplitIterator(BlockSplitIterator* self, 27 | const BlockSplit* split) { 28 | self->split_ = split; 29 | self->idx_ = 0; 30 | self->type_ = 0; 31 | self->length_ = split->lengths ? split->lengths[0] : 0; 32 | } 33 | 34 | static void BlockSplitIteratorNext(BlockSplitIterator* self) { 35 | if (self->length_ == 0) { 36 | ++self->idx_; 37 | self->type_ = self->split_->types[self->idx_]; 38 | self->length_ = self->split_->lengths[self->idx_]; 39 | } 40 | --self->length_; 41 | } 42 | 43 | void BrotliBuildHistogramsWithContext( 44 | const Command* cmds, const size_t num_commands, 45 | const BlockSplit* literal_split, const BlockSplit* insert_and_copy_split, 46 | const BlockSplit* dist_split, const uint8_t* ringbuffer, size_t start_pos, 47 | size_t mask, uint8_t prev_byte, uint8_t prev_byte2, 48 | const ContextType* context_modes, HistogramLiteral* literal_histograms, 49 | HistogramCommand* insert_and_copy_histograms, 50 | HistogramDistance* copy_dist_histograms) { 51 | size_t pos = start_pos; 52 | BlockSplitIterator literal_it; 53 | BlockSplitIterator insert_and_copy_it; 54 | BlockSplitIterator dist_it; 55 | size_t i; 56 | 57 | InitBlockSplitIterator(&literal_it, literal_split); 58 | InitBlockSplitIterator(&insert_and_copy_it, insert_and_copy_split); 59 | InitBlockSplitIterator(&dist_it, dist_split); 60 | for (i = 0; i < num_commands; ++i) { 61 | const Command* cmd = &cmds[i]; 62 | size_t j; 63 | BlockSplitIteratorNext(&insert_and_copy_it); 64 | HistogramAddCommand(&insert_and_copy_histograms[insert_and_copy_it.type_], 65 | cmd->cmd_prefix_); 66 | for (j = cmd->insert_len_; j != 0; --j) { 67 | size_t context; 68 | BlockSplitIteratorNext(&literal_it); 69 | context = context_modes ? 70 | ((literal_it.type_ << BROTLI_LITERAL_CONTEXT_BITS) + 71 | Context(prev_byte, prev_byte2, context_modes[literal_it.type_])) : 72 | literal_it.type_; 73 | HistogramAddLiteral(&literal_histograms[context], 74 | ringbuffer[pos & mask]); 75 | prev_byte2 = prev_byte; 76 | prev_byte = ringbuffer[pos & mask]; 77 | ++pos; 78 | } 79 | pos += CommandCopyLen(cmd); 80 | if (CommandCopyLen(cmd)) { 81 | prev_byte2 = ringbuffer[(pos - 2) & mask]; 82 | prev_byte = ringbuffer[(pos - 1) & mask]; 83 | if (cmd->cmd_prefix_ >= 128) { 84 | size_t context; 85 | BlockSplitIteratorNext(&dist_it); 86 | context = (dist_it.type_ << BROTLI_DISTANCE_CONTEXT_BITS) + 87 | CommandDistanceContext(cmd); 88 | HistogramAddDistance(©_dist_histograms[context], 89 | cmd->dist_prefix_); 90 | } 91 | } 92 | } 93 | } 94 | 95 | #if defined(__cplusplus) || defined(c_plusplus) 96 | } /* extern "C" */ 97 | #endif 98 | -------------------------------------------------------------------------------- /api/namespace.c: -------------------------------------------------------------------------------- 1 | /* vim:set sw=8 ts=8 noet: */ 2 | /* 3 | * Copyright (c) 2016-2017 Torchbox Ltd. 4 | * 5 | * Permission is granted to anyone to use this software for any purpose, 6 | * including commercial applications, and to alter it and redistribute it 7 | * freely. This software is provided 'as-is', without any express or implied 8 | * warranty. 9 | */ 10 | 11 | #include 12 | 13 | #include 14 | 15 | #include "api.h" 16 | 17 | namespace_t * 18 | namespace_make(const char *name) 19 | { 20 | namespace_t *ret; 21 | 22 | if ((ret = calloc(1, sizeof(*ret))) == NULL) 23 | return NULL; 24 | 25 | if ((ret->ns_name = strdup(name)) == NULL) { 26 | namespace_free(ret); 27 | return NULL; 28 | } 29 | 30 | if ((ret->ns_ingresses = hash_new(127, (hash_free_fn) ingress_free)) == NULL) { 31 | namespace_free(ret); 32 | return NULL; 33 | } 34 | 35 | if ((ret->ns_secrets = hash_new(127, (hash_free_fn) secret_free)) == NULL) { 36 | namespace_free(ret); 37 | return NULL; 38 | } 39 | 40 | if ((ret->ns_services = hash_new(127, (hash_free_fn) service_free)) == NULL) { 41 | namespace_free(ret); 42 | return NULL; 43 | } 44 | 45 | if ((ret->ns_endpointses = hash_new(127, (hash_free_fn) endpoints_free)) == NULL) { 46 | namespace_free(ret); 47 | return NULL; 48 | } 49 | 50 | return ret; 51 | } 52 | 53 | void 54 | namespace_free(namespace_t *ns) 55 | { 56 | TSDebug("kubernetes", "namespace_free: %p", ns); 57 | hash_free(ns->ns_ingresses); 58 | hash_free(ns->ns_secrets); 59 | hash_free(ns->ns_services); 60 | hash_free(ns->ns_endpointses); 61 | free(ns->ns_name); 62 | free(ns); 63 | } 64 | 65 | void 66 | namespace_put_ingress(namespace_t *ns, ingress_t *ing) 67 | { 68 | hash_del(ns->ns_ingresses, ing->in_name); 69 | hash_set(ns->ns_ingresses, ing->in_name, ing); 70 | } 71 | 72 | ingress_t * 73 | namespace_get_ingress(namespace_t *ns, const char *name) 74 | { 75 | return hash_get(ns->ns_ingresses, name); 76 | } 77 | 78 | void 79 | namespace_del_ingress(namespace_t *ns, const char *name) 80 | { 81 | hash_del(ns->ns_ingresses, name); 82 | } 83 | 84 | void 85 | namespace_put_secret(namespace_t *ns, secret_t *sec) 86 | { 87 | hash_del(ns->ns_secrets, sec->se_name); 88 | hash_set(ns->ns_secrets, sec->se_name, sec); 89 | } 90 | 91 | secret_t * 92 | namespace_get_secret(namespace_t *ns, const char *name) 93 | { 94 | return hash_get(ns->ns_secrets, name); 95 | } 96 | 97 | void 98 | namespace_del_secret(namespace_t *ns, const char *name) 99 | { 100 | hash_del(ns->ns_secrets, name); 101 | } 102 | 103 | void 104 | namespace_put_service(namespace_t *ns, service_t *svc) 105 | { 106 | hash_del(ns->ns_services, svc->sv_name); 107 | hash_set(ns->ns_services, svc->sv_name, svc); 108 | } 109 | 110 | service_t * 111 | namespace_get_service(namespace_t *ns, const char *name) 112 | { 113 | return hash_get(ns->ns_services, name); 114 | } 115 | 116 | void 117 | namespace_del_service(namespace_t *ns, const char *name) 118 | { 119 | hash_del(ns->ns_services, name); 120 | } 121 | 122 | void 123 | namespace_put_endpoints(namespace_t *ns, endpoints_t *eps) 124 | { 125 | hash_del(ns->ns_endpointses, eps->ep_name); 126 | hash_set(ns->ns_endpointses, eps->ep_name, eps); 127 | } 128 | 129 | endpoints_t * 130 | namespace_get_endpoints(namespace_t *ns, const char *name) 131 | { 132 | return hash_get(ns->ns_endpointses, name); 133 | } 134 | 135 | void 136 | namespace_del_endpoints(namespace_t *ns, const char *name) 137 | { 138 | hash_del(ns->ns_endpointses, name); 139 | } 140 | -------------------------------------------------------------------------------- /tests/e2e/005-auth/run.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # vim:set sw=8 ts=8 noet: 3 | 4 | # Test basic functionality, i.e. that routing requests to an endpoint works. 5 | 6 | set -e 7 | 8 | expect_output() { 9 | if echo "$output" | egrep -q "$@"; then 10 | return 0 11 | else 12 | echo "Failed: output did not include test string: [$*]" 13 | echo "Test output: [$output]" 14 | exit 1 15 | fi 16 | } 17 | 18 | 19 | set -e 20 | 21 | printf '.' 22 | 23 | # Test password-only authentication with all supported crypt algorithms. 24 | 25 | output=$(curl 2>&1 -visS --resolve echoheaders.test:58080:127.0.0.1 \ 26 | http://echoheaders.test:58080/this-is-a-test) 27 | expect_output 'HTTP/[012.]* 401 Unauthorized' 28 | expect_output 'WWW-Authenticate: Basic realm="auth test"' 29 | 30 | for credentials in \ 31 | plaintest:plaintest \ 32 | destest:destest \ 33 | md5test:md5test \ 34 | bftest:bfest \ 35 | sha256test:sha256test \ 36 | sha512test:sha512test \ 37 | shatest:shatest \ 38 | sshatest:sshatest; do 39 | printf '.' 40 | output=$(curl 2>&1 -vsS -u plaintest:plaintest \ 41 | --resolve echoheaders.test:58080:127.0.0.1 \ 42 | http://echoheaders.test:58080/this-is-a-test) 43 | expect_output 'HTTP/[012.]* 200 OK' 44 | done 45 | 46 | # SATISFY IP CORRECT? AUTH CORRECT? 47 | # 48 | # ALL YES YES 49 | printf '.' 50 | output=$(curl 2>&1 -visS -u plaintest:plaintest \ 51 | --resolve all-ipok.echoheaders.test:58080:127.0.0.1 \ 52 | http://all-ipok.echoheaders.test:58080/this-is-a-test) 53 | expect_output 'HTTP/[012.]* 200 OK' 54 | 55 | # ALL YES NO 56 | printf '.' 57 | output=$(curl 2>&1 -visS -u plaintest:laintest \ 58 | --resolve all-ipok.echoheaders.test:58080:127.0.0.1 \ 59 | http://all-ipok.echoheaders.test:58080/this-is-a-test) 60 | expect_output 'HTTP/[012.]* 401 Unauthorized' 61 | expect_output 'WWW-Authenticate: Basic realm="auth test"' 62 | 63 | # APP NO YES 64 | printf '.' 65 | output=$(curl 2>&1 -visS -u plaintest:plaintest \ 66 | --resolve all-ipbad.echoheaders.test:58080:127.0.0.1 \ 67 | http://all-ipbad.echoheaders.test:58080/this-is-a-test) 68 | expect_output 'HTTP/[012.]* 403 Forbidden' 69 | 70 | # ALL NO NO 71 | printf '.' 72 | output=$(curl 2>&1 -visS -u plaintest:laintest \ 73 | --resolve all-ipbad.echoheaders.test:58080:127.0.0.1 \ 74 | http://all-ipbad.echoheaders.test:58080/this-is-a-test) 75 | expect_output 'HTTP/[012.]* 403 Forbidden' 76 | 77 | # ANY YES YES 78 | printf '.' 79 | output=$(curl 2>&1 -visS -u plaintest:plaintest \ 80 | --resolve any-ipok.echoheaders.test:58080:127.0.0.1 \ 81 | http://any-ipok.echoheaders.test:58080/this-is-a-test) 82 | expect_output 'HTTP/[012.]* 200 OK' 83 | 84 | # ANY YES NO 85 | printf '.' 86 | output=$(curl 2>&1 -visS -u plaintest:laintest \ 87 | --resolve any-ipok.echoheaders.test:58080:127.0.0.1 \ 88 | http://any-ipok.echoheaders.test:58080/this-is-a-test) 89 | expect_output 'HTTP/[012.]* 200 OK' 90 | 91 | # ANY NO YES 92 | printf '.' 93 | output=$(curl 2>&1 -visS -u plaintest:plaintest \ 94 | --resolve any-ipbad.echoheaders.test:58080:127.0.0.1 \ 95 | http://any-ipbad.echoheaders.test:58080/this-is-a-test) 96 | expect_output 'HTTP/[012.]* 200 OK' 97 | 98 | # ANY NO NO 99 | printf '.' 100 | output=$(curl 2>&1 -visS -u plaintest:laintest \ 101 | --resolve any-ipbad.echoheaders.test:58080:127.0.0.1 \ 102 | http://any-ipbad.echoheaders.test:58080/this-is-a-test) 103 | expect_output 'HTTP/[012.]* 401 Unauthorized' 104 | expect_output 'WWW-Authenticate: Basic realm="auth test"' 105 | -------------------------------------------------------------------------------- /tests/e2e/006-cors/run.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # vim:set sw=8 ts=8 noet: 3 | 4 | # Test basic functionality, i.e. that routing requests to an endpoint works. 5 | 6 | set -e 7 | 8 | expect_output() { 9 | if echo "$output" | egrep -q "$@"; then 10 | return 0 11 | else 12 | echo "Failed: output did not include test string: [$*]" 13 | echo "Test output: [$output]" 14 | exit 1 15 | fi 16 | } 17 | 18 | 19 | set -e 20 | 21 | 22 | # If there's no Origin header in the request, the response should not include 23 | # any CORS headers. 24 | printf '.' 25 | output=$(curl 2>&1 -visS --resolve echoheaders.test:58080:127.0.0.1 \ 26 | http://echoheaders.test:58080/this-is-a-test) 27 | expect_output 'HTTP/[012.]* 200 OK' 28 | expect_output -v 'Access-Control-' 29 | 30 | printf '.' 31 | output=$(curl 2>&1 -XOPTIONS -visS --resolve echoheaders.test:58080:127.0.0.1 \ 32 | http://echoheaders.test:58080/this-is-a-test) 33 | expect_output 'HTTP/[012.]* 200 OK' 34 | expect_output -v 'Access-Control-' 35 | 36 | # Simple requests should include Access-Control-Allow-Origin, but no other 37 | # headers. 38 | printf '.' 39 | output=$(curl 2>&1 -visS -H'Origin: http://example.com' \ 40 | --resolve echoheaders.test:58080:127.0.0.1 \ 41 | http://echoheaders.test:58080/this-is-a-test) 42 | expect_output 'HTTP/[012.]* 200 OK' 43 | expect_output 'Access-Control-Allow-Origin: \*' 44 | expect_output -v 'Access-Control-Allow-Methods' 45 | expect_output -v 'Access-Control-Allow-Headers' 46 | expect_output -v 'Access-Control-Allow-Credentials' 47 | expect_output -v 'Access-Control-Max-Age' 48 | 49 | # Preflight requests for a public resource should include allow-origin and 50 | # max-age, but not any other headers, because we only want to allow simple 51 | # requests. 52 | printf '.' 53 | output=$(curl 2>&1 -visS -XOPTIONS \ 54 | -H'Origin: http://example.com' \ 55 | -H'Access-Control-Request-Method: POST' \ 56 | --resolve echoheaders.test:58080:127.0.0.1 \ 57 | http://echoheaders.test:58080/this-is-a-test) 58 | expect_output 'HTTP/[012.]* 204 No content' 59 | expect_output 'Access-Control-Allow-Origin: \*' 60 | expect_output 'Access-Control-Max-Age: 3600' 61 | expect_output -v 'Access-Control-Allow-Methods' 62 | expect_output -v 'Access-Control-Allow-Headers' 63 | expect_output -v 'Access-Control-Allow-Credentials' 64 | 65 | # Preflight request for a private resource. 66 | printf '.' 67 | output=$(curl 2>&1 -visS -XOPTIONS \ 68 | -H'Origin: http://example.com' \ 69 | -H'Access-Control-Request-Method: POST' \ 70 | --resolve private.echoheaders.test:58080:127.0.0.1 \ 71 | http://private.echoheaders.test:58080/this-is-a-test) 72 | expect_output 'HTTP/[012.]* 204 No content' 73 | expect_output 'Access-Control-Allow-Origin: http://example.com' 74 | expect_output -v 'Access-Control-Max-Age' 75 | expect_output 'Access-Control-Allow-Methods: PUT, DELETE' 76 | expect_output 'Access-Control-Allow-Headers: X-CustomHeader' 77 | expect_output 'Access-Control-Allow-Credentials: true' 78 | 79 | # Preflight request for a private resource with an incorrect origin. 80 | printf '.' 81 | output=$(curl 2>&1 -visS -XOPTIONS \ 82 | -H'Origin: http://wrong.example.com' \ 83 | -H'Access-Control-Request-Method: POST' \ 84 | --resolve private.echoheaders.test:58080:127.0.0.1 \ 85 | http://private.echoheaders.test:58080/this-is-a-test) 86 | expect_output 'HTTP/[012.]* 200 OK' 87 | expect_output -v 'Access-Control-Allow-Origin' 88 | expect_output -v 'Access-Control-Max-Age' 89 | expect_output -v 'Access-Control-Allow-Methods' 90 | expect_output -v 'Access-Control-Allow-Headers' 91 | expect_output -v 'Access-Control-Allow-Credentials' 92 | -------------------------------------------------------------------------------- /util/base64.c: -------------------------------------------------------------------------------- 1 | /* vim:set sw=8 ts=8 noet: */ 2 | /* 3 | * Copyright (c) 2011, 2017 Felicity Tarnell. 4 | * 5 | * Permission is granted to anyone to use this software for any purpose, 6 | * including commercial applications, and to alter it and redistribute it 7 | * freely. This software is provided 'as-is', without any express or implied 8 | * warranty. 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include "base64.h" 16 | 17 | static char b64table[] = 18 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 19 | #define b64untable(c) \ 20 | ( ((c) >= 'A' && (c) <= 'Z') ? ((c) - 'A') \ 21 | : ((c) >= 'a' && (c) <= 'z') ? (((c) - 'a') + 26) \ 22 | : ((c) >= '0' && (c) <= '9') ? (((c) - '0') + 52) \ 23 | : ((c) == '+') ? 62 \ 24 | : ((c) == '/') ? 63 \ 25 | : ((c) == '=') ? 0 \ 26 | : -1) \ 27 | 28 | /* 29 | * Encode the given inbuf, which is inlen bytes long, as base64 and write the 30 | * result to outbuf, which must be large enough to hold the output. Use 31 | * base64_encode_len(inlen) to determine the size of the output. 32 | * 33 | * base64_encode cannot fail. 34 | */ 35 | void 36 | base64_encode(const unsigned char *inbuf, size_t inlen, char *outbuf) 37 | { 38 | size_t left = inlen; 39 | 40 | while (left > 0) { 41 | unsigned char d[4] = {}; 42 | int todo = left > 3 ? 3 : left; 43 | 44 | switch (todo) { 45 | case 3: 46 | d[3] |= (inbuf[2] & 0x3F); 47 | d[2] |= ((inbuf[2] & 0xC0) >> 6); 48 | case 2: 49 | d[2] |= (inbuf[1] & 0x0F) << 2; 50 | d[1] |= ((inbuf[1] & 0xF0) >> 4); 51 | case 1: 52 | d[0] = (inbuf[0] & 0xFC) >> 2; 53 | d[1] |= (inbuf[0] & 0x03) << 4; 54 | } 55 | 56 | *outbuf++ = b64table[d[0]]; 57 | *outbuf++ = b64table[d[1]]; 58 | 59 | if (todo >= 3) { 60 | *outbuf++ = b64table[d[2]]; 61 | *outbuf++ = b64table[d[3]]; 62 | } else if (todo == 2) { 63 | *outbuf++ = b64table[d[2]]; 64 | *outbuf++ = '='; 65 | } else if (todo == 1) { 66 | *outbuf++ = '='; 67 | *outbuf++ = '='; 68 | } 69 | 70 | left -= todo; 71 | inbuf += todo; 72 | } 73 | } 74 | 75 | /* 76 | * Decode the given inbuf, which contains inlen bytes of base64 data, and write 77 | * the result to outbuf. outbuf must be large enough to hold the output; use 78 | * base64_encode_len(inlen) to determine the maximum size of the output. 79 | * 80 | * Returns the actual length of the decoded data (which may be less than 81 | * base64_encode_len(inlen)), or -1 if invalid base64 encoding was detected. 82 | */ 83 | ssize_t 84 | base64_decode(char const *inbuf, size_t inlen, unsigned char *outbuf) 85 | { 86 | unsigned const char *p = (unsigned const char *)inbuf, 87 | *end = p + inlen; 88 | ssize_t nbytes = 0; 89 | 90 | while ((end - p) >= 4) { 91 | unsigned char d[3]; 92 | int padding = 0; 93 | 94 | if (p[3] == '=') ++padding; 95 | if (p[2] == '=') ++padding; 96 | 97 | if (p[1] == '=' || p[0] == '=') 98 | return -1; 99 | 100 | if (padding && ((end - p) > 4)) 101 | return -1; 102 | 103 | if (b64untable(p[3]) == -1) return -1; 104 | if (b64untable(p[2]) == -1) return -1; 105 | if (b64untable(p[1]) == -1) return -1; 106 | if (b64untable(p[0]) == -1) return -1; 107 | 108 | d[2] = b64untable(p[3]) & 0x3F; 109 | d[2] |= (b64untable(p[2]) & 0x03) << 6; 110 | d[1] = (b64untable(p[2]) & 0x3C) >> 2; 111 | d[1] |= (b64untable(p[1]) & 0x0F) << 4; 112 | d[0] = (b64untable(p[1]) & 0x30) >> 4; 113 | d[0] |= b64untable(p[0]) << 2; 114 | 115 | bcopy(d, outbuf, (3 - padding)); 116 | nbytes += (3 - padding); 117 | 118 | if (padding) 119 | break; 120 | 121 | outbuf += 3; 122 | p += 4; 123 | } 124 | 125 | return nbytes; 126 | } 127 | 128 | --------------------------------------------------------------------------------