Compare commits

...
117 Commits
Author SHA1 Message Date
Sergey Lyubka a204c80308 Update ca.pem links 2021-10-01 09:25:34 +01:00
Sergey Lyubka 7d620965e2 Update ca.pem: DST root CA has expired 2021-10-01 09:22:49 +01:00
Sergey Lyubka 0149654791 Update README 2021-10-01 08:26:34 +01:00
Sergey Lyubka f08d280429 Version 7.4 2021-09-30 13:35:44 +01:00
Sergey Lyubka 6fbb749431 7.4 -> 7.5 2021-09-30 13:34:55 +01:00
Sergey Lyubka 61070d136d Add nxp-mimxrt1020-azurertos to Actions 2021-09-27 13:55:19 +01:00
Sergey Lyubka ea85f93e37 Merge branch 'master' of github.com:cesanta/mongoose 2021-09-27 13:52:59 +01:00
Sergey Lyubka 46029c501a Fix #1359 - add conditional for MSVC, _DEBUG and strdup 2021-09-27 13:52:39 +01:00
Sergey Lyubka 78e1fdd1c9 Merge pull request #1365 from zudwalex/mimxrt1020_example
Add NXP MIMXRT1020 AzureRTOS example
2021-09-27 11:50:48 +01:00
Alex Alashkin 9ef5c7c667 Add NXP MIMXRT1020 AzureRTOS example 2021-09-27 11:12:15 +03:00
Sergey Lyubka cdf279e438 Merge pull request #1358 from yermin/master
makes it more readable
2021-09-27 09:00:11 +01:00
Sergey Lyubka cdd192abe4 Merge pull request #1363 from tophatgeeks/patch-1
Update README - Jordan Ramsey Edits.md
2021-09-27 08:44:42 +01:00
Sergey Lyubka 9af6f4b02e Merge pull request #1360 from zudwalex/azure_basics
Add AzureRTOS basic support
2021-09-27 08:39:15 +01:00
Alex Alashkin d86ceecd8c Add AzureRTOS basic support 2021-09-26 10:25:44 +03:00
yermin 8f693b92a7 makes it more readable
Signed-off-by: yermin <yermin@buaa.edu.cn>
2021-09-24 11:30:21 +08:00
tophatgeeks 6b1ff37cf3 Update README.md
I have gone through and edited for consistency, punctuation, wording, and grammar. If you have questions feel free to reach out.  I fixed some spelling errors "if" instead of "is" "update" instead of "updatw", etc. 

-Jordan Ramsey
2021-09-23 12:07:00 -04:00
Sergey Lyubka c490ff8ae7 Fix typo 2021-09-22 20:38:28 +01:00
Sergey Lyubka f73ebbf689 Fix #1354 - report correct errno in mg_open_listener() 2021-09-22 18:52:42 +01:00
Sergey Lyubka 1928ba9c1f Merge branch 'master' of github.com:cesanta/mongoose 2021-09-22 11:51:26 +01:00
Sergey Lyubka ad3655fb92 Docs spelling 2021-09-22 11:51:16 +01:00
novlean 29e0158689 Merge pull request #1355 from cesanta/novlean-patch-1
2021
2021-09-21 18:07:33 +01:00
novlean aaf55b6da0 2021 2021-09-21 18:02:11 +01:00
Sergey Lyubka 90a131bd29 Include ipv6 wrapping brackets [] in the result of mg_url_host() 2021-09-21 08:10:27 +01:00
Sergey Lyubka 8652006aea Remove dead code 2021-09-20 12:26:09 +01:00
Sergey Lyubka 2139fbc4b7 Support multiple web roots 2021-09-20 12:24:44 +01:00
Sergey Lyubka 2b48e8b03a Send suback 2021-09-18 20:56:56 +01:00
Sergey Lyubka a7afea0963 Handle ipv4-mapped addresses 2021-09-18 19:38:59 +01:00
Sergey Lyubka 9d1e61de93 Update docs 2021-09-17 15:59:15 +01:00
Sergey Lyubka 9b6b1a68f4 Add MQTT version check 2021-09-17 14:02:29 +01:00
Sergey Lyubka c7bd63ef53 Fix #1351 - squash warning 2021-09-17 11:07:20 +01:00
Sergey Lyubka 40b3382023 Enable WS data size check 2021-09-17 10:56:58 +01:00
Sergey Lyubka a70c5e726d Merge branch 'master' of github.com:cesanta/mongoose 2021-09-16 11:17:02 +01:00
Sergey Lyubka 409fdaec59 Rename posix_* -> p_* to avoid build conflict on linux 2021-09-16 11:16:10 +01:00
Sergey Lyubka 372aa369c4 Merge pull request #1350 from zudwalex/mg_parameters_retval
Add parameters descriptions to documentation
2021-09-15 20:51:18 +01:00
Alex Alashkin eb94704d8d Add params and retvals 2021-09-15 22:18:44 +03:00
Sergey Lyubka 894a168833 Get rid of fs->realpath 2021-09-15 07:43:48 +01:00
Sergey Lyubka f3eb466af3 Update docs 2021-09-15 07:43:24 +01:00
Sergey Lyubka df848973dc Fix unamalgamated target 2021-09-14 12:27:02 +01:00
Sergey Lyubka f37e5ecc38 WS frame len sanity check 2021-09-14 10:26:03 +01:00
Sergey Lyubka 6316609a5f Show log level 2021-09-13 13:48:02 +01:00
Sergey Lyubka dca08d32bd Fix URL 2021-09-13 13:47:49 +01:00
Sergey Lyubka 2b287f50f1 Add gitter badge 2021-09-02 10:28:16 +01:00
Sergey Lyubka acf58972f7 Fix posix_open() 2021-09-02 10:20:55 +01:00
Sergey Lyubka 5bf5516b29 struct iobuf doc 2021-08-30 13:06:45 +01:00
Sergey Lyubka 40b99e3751 Print openssl error on TLS error 2021-08-30 11:45:30 +01:00
Sergey Lyubka 28a56370d4 Fix zeromem() call in mg_iobuf_del() 2021-08-30 11:39:19 +01:00
Sergey Lyubka e3589577ed Update OpenSSL handshake error codepath 2021-08-29 16:54:24 +01:00
Sergey Lyubka 38beb4cbc0 Update readme 2021-08-28 22:00:46 +01:00
Sergey Lyubka 167af7f160 docs update 2021-08-28 20:27:55 +01:00
Sergey Lyubka 7d91885413 Update docs 2021-08-28 11:16:45 +01:00
Sergey Lyubka 0de83157dc Update docs 2021-08-28 08:52:41 +01:00
Sergey Lyubka cc9639b3cb Update docs 2021-08-28 08:48:47 +01:00
Sergey Lyubka cb0ac1868f Update docs 2021-08-28 08:46:01 +01:00
Sergey Lyubka e653147119 Merge pull request #1344 from timgates42/bugfix_typo_priority
docs: fix simple typo, priorty -> priority
2021-08-28 08:37:26 +01:00
Sergey Lyubka f3d15a0440 Update docs 2021-08-28 08:25:31 +01:00
Sergey Lyubka 0bc736d384 Update docs 2021-08-28 08:23:33 +01:00
Sergey Lyubka 3bf7b817f6 Update docs 2021-08-28 08:21:29 +01:00
Sergey Lyubka 477e48bf54 mg_iobuf_append -> mg_iobuf_add 2021-08-28 08:08:54 +01:00
Sergey Lyubka 913e730ec2 mg_iobuf_delete -> mg_iobuf_del 2021-08-28 07:16:38 +01:00
Sergey Lyubka bd64043377 mg_comma -> mg_commalist 2021-08-28 06:54:56 +01:00
Tim Gates 9f827feeaa docs: fix simple typo, priorty -> priority
There is a small typo in examples/stm32-freertos-tcp/stm32f7/core_cm7.h.

Should read `priority` rather than `priorty`.
2021-08-28 07:46:08 +10:00
Sergey Lyubka 714b7a8145 Handle WS fragmentation 2021-08-27 10:25:24 +01:00
Sergey Lyubka 7ba6fda236 Add stm32-nucleo-h743z and stm32-nucleo-f429z 2021-08-26 11:40:47 +01:00
Sergey Lyubka fc9c454518 Add mg_check_ip_acl() 2021-08-25 07:59:31 +01:00
Sergey Lyubka 1c456fc2df mg_next_comma_entry -> mg_comma 2021-08-23 16:54:58 +01:00
Sergey Lyubka 9b37ac384f Merge pull request #1341 from lnksz/bugfix-1340-http_chunked
Fix #1340: Long HTTP Chunks
2021-08-23 14:50:39 +01:00
Sergey Lyubka 99b279d5e5 Add examples/stm32-nucleo-f746z 2021-08-23 10:38:11 +01:00
Kristof Havasi 4d07a99ee2 Fix bug in long HTTP chunk handling
Due to a copy/paste error, the start of the payload in the latest parsed
chunk was compared to chunk-length of the terminating chunk (5 chars).
So only chunks were parsed as expected, which also had a single hex
digit length.
2021-08-23 08:50:58 +02:00
Kristof Havasi f6f0e49de4 Add failing test for HTTP chunk
This test would have caught #1340: handling chunks longer than 15 chars
2021-08-23 08:19:46 +02:00
Sergey Lyubka 07568a8f06 Docs nits 2021-08-22 10:51:40 +01:00
Sergey Lyubka 71e9019211 Docs nitpicks 2021-08-20 20:31:32 +01:00
Sergey Lyubka 0937213f4b Merge pull request #1336 from zudwalex/freertos_lwip_support
Update FREERTOS + LWIP support
2021-08-12 12:57:06 +01:00
Sergey Lyubka 6c42350fcf docs 2021-08-12 12:24:28 +01:00
Alex Alashkin 453d4be4d0 Update FREERTOS + LWIP support 2021-08-12 13:54:43 +03:00
Sergey Lyubka 104c4fab19 More docs 2021-08-11 19:24:33 +01:00
Sergey Lyubka fd5eb2d3f9 Refactor mg_mkpipe() 2021-08-11 19:17:04 +01:00
Sergey Lyubka 8b770d2a0d Fix #1334 - typo in mg_call(..MG_EV_WS_OPEN) call 2021-08-11 04:52:39 +01:00
Sergey Lyubka b739aa89f1 Update readme 2021-08-09 09:43:21 +01:00
Sergey Lyubka 11c07470bb Refactor UDP handling 2021-08-07 22:55:13 +01:00
Sergey Lyubka 76865cbe14 Fix STM32 build 2021-08-07 17:52:51 +01:00
Sergey Lyubka b7ce8213d7 Better multithreading support: remove mg_socketpair, add mg_mkpipe() and mg_rmpipe() 2021-08-07 17:22:47 +01:00
Sergey Lyubka 86f43cd8d6 Refactor mg_socketpair and document MG_ENABLE_NATIVE_SOCKETPAIR 2021-08-06 10:23:08 +01:00
Sergey Lyubka 2407509ce0 More detailed environment questions 2021-08-05 10:49:24 +01:00
Sergey Lyubka 47ce072af7 Fix #1331 - add comment about order of operations in conn_close() 2021-08-05 10:39:24 +01:00
Sergey Lyubka c2c6ff11ed Fix #1329 - send MG_EV_WS_OPEN for server connections 2021-08-04 11:38:32 +01:00
Sergey Lyubka 9b18a6350a Make ws_upgrade() respond with error if request is not and upgrade 2021-08-03 23:37:50 +01:00
Sergey Lyubka a36050ab4b Fix #1326 - spelling errors 2021-08-02 00:23:01 +01:00
Sergey Lyubka 568484f079 Fix #920 - add MQTT over Websocket client example 2021-08-01 14:10:21 +01:00
Sergey Lyubka 3ea4f1fda8 Merge pull request #1324 from ignacionr/fix/issue-1323
allow for in-url colon, when port is not specified
2021-07-31 22:30:04 +01:00
Sergey Lyubka 5366844581 Fix #1325 - squash gcc 10 warning, and optimise casts 2021-07-31 22:26:43 +01:00
Ignacio Rodriguez e52a6184c4 test and fix 2021-07-30 12:34:55 -05:00
Sergey Lyubka b40b1232cc Enhance packed fs serving 2021-07-30 17:41:23 +01:00
Sergey Lyubka 3a46055e52 Better packed test 2021-07-30 13:19:20 +01:00
Sergey Lyubka 2af5d07467 Fix stm32 GA 2021-07-29 14:28:20 +01:00
Sergey Lyubka c2176f969b Implement FS virtualization 2021-07-29 14:21:20 +01:00
Sergey Lyubka 9346122c29 Add FS API layer 2021-07-28 21:11:07 +01:00
Sergey Lyubka b98556a4dc Enable mg_fopen_packed on ARM 2021-07-27 09:54:45 +01:00
Sergey Lyubka 55d102e450 Enable mg_fopen_packed in newlib 2021-07-27 09:50:11 +01:00
Sergey Lyubka dfc22af10f Run docker non-interactive 2021-07-26 18:18:29 +01:00
Sergey Lyubka 2d585474c1 Add riscv target, enhance arm target 2021-07-26 11:00:37 +01:00
Sergey Lyubka 53ee984eb7 Fix mg_prefix test 2021-07-26 09:26:52 +01:00
Sergey Lyubka bdb747f9de Fix mg_prefix test 2021-07-26 09:15:17 +01:00
Sergey Lyubka 299075c930 Add test for fopen_packed() 2021-07-26 09:05:34 +01:00
Sergey Lyubka b0e0247b21 Add ascii to the packed data 2021-07-25 21:08:02 +01:00
Sergey Lyubka 35abd695cd Add packed FS 2021-07-25 10:22:56 +01:00
Sergey Lyubka df2ffd1187 Refactor serve dir even more 2021-07-24 22:00:37 +01:00
Sergey Lyubka b378082ec4 Refactor mg_http_serve_dir() 2021-07-24 21:48:19 +01:00
Sergey Lyubka fb4fae9174 Optimise file serving path 2021-07-24 21:23:52 +01:00
Sergey Lyubka cddff2b1b8 Cleanup on riscv baremetal build 2021-07-24 11:40:52 +01:00
Sergey Lyubka d6dbf831f7 Remove mg_stat 2021-07-24 10:35:48 +01:00
Sergey Lyubka 7e1d4325ec Fail examples target if any example fails 2021-07-24 08:45:51 +01:00
Sergey Lyubka 2a2c17a232 Remove MG_ENABLE_STDIO and cleanup 2021-07-24 03:44:00 +01:00
Sergey Lyubka d130c6f42d Remove leftovers 2021-07-24 02:44:25 +01:00
Sergey Lyubka a09238debd Place config.h before arch*.h 2021-07-23 20:48:48 +01:00
Sergey Lyubka 328a87b02a Remove mg_file_size() 2021-07-23 20:18:34 +01:00
Sergey Lyubka 529faa1172 MG_ENABLE_FS -> MG_ENABLE_STDIO 2021-07-23 19:47:26 +01:00
Sergey Lyubka 8e5efd4804 7.3 -> 7.4 2021-07-23 12:17:05 +01:00
98 changed files with 5874 additions and 5356 deletions

No files matched your search

+6 -3
View File
@@ -6,6 +6,9 @@
# Environment # Environment
- mongoose version: _X.Y_ - mongoose version (e.g. 7.3): _X.Y_
- OS: _?_ - Compiler/IDE (e.g. arm-none-eabi-gcc 9.3): _?_
- Compiler/IDE: _?_ - Target OS (e.g. FreeRTOS 10.3.1, Linux 5.8): _?_
- Target hardware/board (e.g. STM32F411): _?_
- Connectivity chip/module (e.g. WizNet W5500): _?_
- Target SDK (e.g. STM32CubeF1 1.8.4): _?_
+45 -1
View File
@@ -11,6 +11,8 @@ jobs:
run: make test test++ IPV6=0 run: make test test++ IPV6=0
- name: openssl - name: openssl
run: make test SSL=OPENSSL IPV6=0 run: make test SSL=OPENSSL IPV6=0
- name: unamalgamated
run: make unamalgamated
examples: examples:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@@ -18,7 +20,7 @@ jobs:
- name: Install packages - name: Install packages
run: sudo apt-get install libmbedtls-dev run: sudo apt-get install libmbedtls-dev
- name: examples - name: examples
run: make ex run: make clean examples
macos: macos:
runs-on: macos-latest runs-on: macos-latest
steps: steps:
@@ -49,3 +51,45 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: arm - name: arm
run: make arm run: make arm
esp32:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: esp32
run: make -C examples/esp32 build
esp8266:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: esp8266
run: make -C examples/esp8266 build
stm32-freertos-tcp:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: stm32-freertos-tcp
run: make -C examples/stm32-freertos-tcp build
stm32-nucleo-f746z:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: stm32-nucleo-f746z
run: make -C examples/stm32-nucleo-f746z build
stm32-nucleo-f429z:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: stm32-nucleo-f429z
run: make -C examples/stm32-nucleo-f429z build
stm32-nucleo-h743z:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: stm32-nucleo-h743z
run: make -C examples/stm32-nucleo-h743z build
nxp-mimxrt1020-azurertos:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: nxp-mimxrt1020-azurertos
run: make -C examples/nxp-mimxrt1020-azurertos build
+1 -1
View File
@@ -1,5 +1,5 @@
Copyright (c) 2004-2013 Sergey Lyubka Copyright (c) 2004-2013 Sergey Lyubka
Copyright (c) 2013-2020 Cesanta Software Limited Copyright (c) 2013-2021 Cesanta Software Limited
All rights reserved All rights reserved
This software is dual-licensed: you can redistribute it and/or modify This software is dual-licensed: you can redistribute it and/or modify
+59 -52
View File
@@ -1,26 +1,20 @@
SRCS = $(wildcard src/*.c) SRCS = mongoose.c test/unit_test.c test/packed_fs.c
HDRS = $(wildcard src/*.h) HDRS = $(wildcard src/*.h)
DEFS ?= -DMG_MAX_HTTP_HEADERS=5 -DMG_ENABLE_LINES -DMG_ENABLE_DIRECTORY_LISTING=1 -DMG_ENABLE_SSI=1 DEFS ?= -DMG_MAX_HTTP_HEADERS=7 -DMG_ENABLE_LINES -DMG_ENABLE_PACKED_FS=1
WARN ?= -W -Wall -Werror -Wshadow -Wdouble-promotion -fno-common -Wconversion WARN ?= -W -Wall -Werror -Wshadow -Wdouble-promotion -fno-common -Wconversion
OPTS ?= -O3 -g3 OPTS ?= -O3 -g3
INCS ?= -Isrc -I. INCS ?= -Isrc -I.
CFLAGS ?= $(OPTS) $(WARN) $(INCS) $(DEFS) $(TFLAGS) $(EXTRA) CFLAGS ?= $(OPTS) $(WARN) $(INCS) $(DEFS) $(TFLAGS) $(EXTRA)
SSL ?= MBEDTLS SSL ?= MBEDTLS
CDIR ?= $(realpath $(CURDIR)) CWD ?= $(realpath $(CURDIR))
VC98 = docker run --rm -e WINEDEBUG=-all -v $(CDIR):$(CDIR) -w $(CDIR) docker.io/mdashnet/vc98 DOCKER ?= docker run --rm -e Tmp=. -e WINEDEBUG=-all -v $(CWD):$(CWD) -w $(CWD)
VC2017 = docker run --rm -e WINEDEBUG=-all -v $(CDIR):$(CDIR) -w $(CDIR) docker.io/mdashnet/vc2017
MINGW = docker run --rm -v $(CDIR):$(CDIR) -w $(CDIR) docker.io/mdashnet/mingw
GCC = docker run --rm -v $(CDIR):$(CDIR) -w $(CDIR) mdashnet/cc2
ARM = docker run -v $(CDIR):$(CDIR) -w $(CDIR) mdashnet/armgcc
VCFLAGS = /nologo /W3 /O2 /I. $(DEFS) $(TFLAGS) VCFLAGS = /nologo /W3 /O2 /I. $(DEFS) $(TFLAGS)
CLANG ?= clang # /usr/local/opt/llvm\@9/bin/clang
IPV6 ?= 1 IPV6 ?= 1
ASAN_OPTIONS ?= ASAN_OPTIONS ?=
EXAMPLES := $(wildcard examples/*) EXAMPLES := $(wildcard examples/*)
EXAMPLE_TARGET ?= example
PREFIX ?= /usr/local PREFIX ?= /usr/local
SOVERSION = 7.2 VERSION ?= $(shell cut -d'"' -f2 src/version.h)
.PHONY: ex test .PHONY: examples test
ifeq "$(SSL)" "MBEDTLS" ifeq "$(SSL)" "MBEDTLS"
MBEDTLS ?= /usr MBEDTLS ?= /usr
@@ -33,32 +27,42 @@ CFLAGS += -DMG_ENABLE_OPENSSL=1 -I$(OPENSSL)/include
LDFLAGS ?= -L$(OPENSSL)/lib -lssl -lcrypto LDFLAGS ?= -L$(OPENSSL)/lib -lssl -lcrypto
endif endif
all: mg_prefix test test++ ex vc98 vc2017 mingw mingw++ linux linux++ infer fuzz all: mg_prefix unpacked test test++ arm examples vc98 vc2017 mingw mingw++ linux linux++ fuzz
ex: examples:
@for X in $(EXAMPLES); do $(MAKE) -C $$X $(EXAMPLE_TARGET); done @for X in $(EXAMPLES); do $(MAKE) -C $$X example || break; done
test/packed_fs.c: Makefile src/fs.h src/ssi.h test/fuzz.c test/data/a.txt
$(CC) $(CFLAGS) test/pack.c -o pack
./pack $? > $@
# Check that all external (exported) symbols have "mg_" prefix # Check that all external (exported) symbols have "mg_" prefix
mg_prefix: mongoose.c mongoose.h mg_prefix: mongoose.c mongoose.h
$(CLANG) mongoose.c $(CFLAGS) -c -o /tmp/x.o && nm /tmp/x.o | grep ' T' | grep -v 'mg_' ; test $$? = 1 $(CC) mongoose.c $(CFLAGS) -c -o /tmp/x.o && nm /tmp/x.o | grep ' T' | grep -v 'mg_' ; test $$? = 1
# C++ build # C++ build
test++: CLANG = g++ test++: CC = g++
test++: WARN += -Wno-shadow -Wno-missing-field-initializers -Wno-deprecated test++: WARN += -Wno-shadow -Wno-missing-field-initializers -Wno-deprecated
test++: test test++: test
# Make sure we can build from an unamalgamated sources # Make sure we can build from an unamalgamated sources
unamalgamated: $(SRCS) $(HDRS) Makefile unamalgamated: $(HDRS) Makefile test/packed_fs.c
$(CLANG) src/*.c test/unit_test.c $(CFLAGS) $(LDFLAGS) -g -o unit_test $(CC) src/*.c test/packed_fs.c test/unit_test.c $(CFLAGS) $(LDFLAGS) -g -o unit_test
fuzz: mongoose.c mongoose.h Makefile test/fuzz.c
$(CLANG) mongoose.c test/fuzz.c $(CFLAGS) -DMG_ENABLE_LINES -DMG_ENABLE_LOG=0 -fsanitize=fuzzer,signed-integer-overflow,address $(LDFLAGS) -g -o fuzzer
$(DEBUGGER) ./fuzzer
# make CLANG=/usr/local/opt/llvm\@8/bin/clang ASAN_OPTIONS=detect_leaks=1 unpacked:
$(CC) -I. mongoose.c test/unit_test.c -o unit_test
fuzzer: mongoose.c mongoose.h Makefile test/fuzz.c
clang mongoose.c test/fuzz.c $(WARN) $(INCS) -DMG_ENABLE_LINES -DMG_ENABLE_LOG=0 -fsanitize=fuzzer,signed-integer-overflow,address -g -o $@
fuzz: fuzzer
$(RUN) ./fuzzer
# make CC=/usr/local/opt/llvm\@8/bin/clang ASAN_OPTIONS=detect_leaks=1
test: CFLAGS += -DMG_ENABLE_IPV6=$(IPV6) -fsanitize=address#,undefined test: CFLAGS += -DMG_ENABLE_IPV6=$(IPV6) -fsanitize=address#,undefined
test: mongoose.c mongoose.h Makefile test/unit_test.c test: mongoose.h Makefile $(SRCS)
$(CLANG) mongoose.c test/unit_test.c $(CFLAGS) -coverage $(LDFLAGS) -g -o unit_test $(CC) $(SRCS) $(CFLAGS) -coverage $(LDFLAGS) -g -o unit_test
ASAN_OPTIONS=$(ASAN_OPTIONS) $(DEBUGGER) ./unit_test ASAN_OPTIONS=$(ASAN_OPTIONS) $(RUN) ./unit_test
coverage: test coverage: test
gcov -l -n *.gcno | sed '/^$$/d' | sed 'N;s/\n/ /' gcov -l -n *.gcno | sed '/^$$/d' | sed 'N;s/\n/ /'
@@ -70,29 +74,35 @@ upload-coverage: coverage
infer: infer:
infer run -- cc test/unit_test.c -c -W -Wall -Werror -Isrc -I. -O2 -DMG_ENABLE_MBEDTLS=1 -DMG_ENABLE_LINES -I/usr/local/Cellar/mbedtls/2.23.0/include -DMG_ENABLE_IPV6=1 -g -o /dev/null infer run -- cc test/unit_test.c -c -W -Wall -Werror -Isrc -I. -O2 -DMG_ENABLE_MBEDTLS=1 -DMG_ENABLE_LINES -I/usr/local/Cellar/mbedtls/2.23.0/include -DMG_ENABLE_IPV6=1 -g -o /dev/null
arm: mongoose.h $(SRCS)
$(DOCKER) mdashnet/armgcc arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb $(SRCS) test/mongoose_custom.c -Itest -DMG_ARCH=MG_ARCH_CUSTOM $(OPTS) $(WARN) $(INCS) $(DEFS) -o unit_test -nostartfiles --specs nosys.specs -e 0
riscv: mongoose.h $(SRCS)
$(DOCKER) mdashnet/riscv riscv-none-elf-gcc -march=rv32imc -mabi=ilp32 $(SRCS) test/mongoose_custom.c -Itest -DMG_ARCH=MG_ARCH_CUSTOM $(OPTS) $(WARN) $(INCS) $(DEFS) -o unit_test
#vc98: VCFLAGS += -DMG_ENABLE_IPV6=1 #vc98: VCFLAGS += -DMG_ENABLE_IPV6=1
vc98: Makefile mongoose.c mongoose.h test/unit_test.c vc98: Makefile mongoose.h $(SRCS)
$(VC98) wine cl mongoose.c test/unit_test.c $(VCFLAGS) ws2_32.lib /Fe$@.exe $(DOCKER) mdashnet/vc98 wine cl $(SRCS) $(VCFLAGS) ws2_32.lib /Fe$@.exe
$(VC98) wine $@.exe $(DOCKER) mdashnet/vc98 wine $@.exe
#vc2017: VCFLAGS += -DMG_ENABLE_IPV6=1 #vc2017: VCFLAGS += -DMG_ENABLE_IPV6=1
vc2017: Makefile mongoose.c mongoose.h test/unit_test.c vc2017: Makefile mongoose.h $(SRCS)
$(VC2017) wine64 cl mongoose.c test/unit_test.c $(VCFLAGS) ws2_32.lib /Fe$@.exe $(DOCKER) mdashnet/vc2017 wine64 cl $(SRCS) $(VCFLAGS) ws2_32.lib /Fe$@.exe
$(VC2017) wine64 $@.exe $(DOCKER) mdashnet/vc2017 wine64 $@.exe
mingw: Makefile mongoose.c mongoose.h test/unit_test.c mingw: Makefile mongoose.h $(SRCS)
$(MINGW) i686-w64-mingw32-gcc mongoose.c test/unit_test.c -W -Wall -Werror -I. $(DEFS) -lwsock32 -o test.exe $(DOCKER) mdashnet/mingw i686-w64-mingw32-gcc $(SRCS) -W -Wall -Werror -I. $(DEFS) -lwsock32 -o test.exe
$(VC98) wine test.exe $(DOCKER) mdashnet/vc98 wine test.exe
mingw++: Makefile mongoose.c mongoose.h test/unit_test.c mingw++: Makefile mongoose.h $(SRCS)
$(MINGW) i686-w64-mingw32-g++ mongoose.c test/unit_test.c -W -Wall -Werror -I. $(DEFS) -lwsock32 -o test.exe $(DOCKER) mdashnet/mingw i686-w64-mingw32-g++ $(SRCS) -W -Wall -Werror -I. $(DEFS) -lwsock32 -o test.exe
# Note: for some reason, a binary built with mingw g++, fails to run # Note: for some reason, a binary built with mingw g++, fails to run
#linux: CFLAGS += -DMG_ENABLE_IPV6=$(IPV6) #linux: CFLAGS += -DMG_ENABLE_IPV6=$(IPV6)
linux: CFLAGS += -fsanitize=address,undefined linux: CFLAGS += -fsanitize=address,undefined
linux: Makefile mongoose.c mongoose.h test/unit_test.c linux: Makefile mongoose.h $(SRCS)
$(GCC) $(CC) mongoose.c test/unit_test.c $(CFLAGS) $(LDFLAGS) -o unit_test_gcc $(DOCKER) mdashnet/cc2 gcc $(SRCS) $(CFLAGS) $(LDFLAGS) -o unit_test_gcc
$(GCC) ./unit_test_gcc $(DOCKER) mdashnet/cc2 ./unit_test_gcc
linux++: CC = g++ linux++: CC = g++
linux++: WARN += -Wno-missing-field-initializers linux++: WARN += -Wno-missing-field-initializers
@@ -100,26 +110,23 @@ linux++: linux
linux-libs: CFLAGS += -fPIC linux-libs: CFLAGS += -fPIC
linux-libs: mongoose.o linux-libs: mongoose.o
$(CC) mongoose.o $(LDFLAGS) -shared -o libmongoose.so.$(SOVERSION) $(CC) mongoose.o $(LDFLAGS) -shared -o libmongoose.so.$(VERSION)
$(AR) rcs libmongoose.a mongoose.o $(AR) rcs libmongoose.a mongoose.o
install: linux-libs install: linux-libs
install -Dm644 libmongoose.a libmongoose.so.$(SOVERSION) $(DESTDIR)$(PREFIX)/lib install -Dm644 libmongoose.a libmongoose.so.$(VERSION) $(DESTDIR)$(PREFIX)/lib
ln -s libmongoose.so.$(SOVERSION) $(DESTDIR)$(PREFIX)/lib/libmongoose.so ln -s libmongoose.so.$(VERSION) $(DESTDIR)$(PREFIX)/lib/libmongoose.so
install -Dm644 mongoose.h $(DESTDIR)$(PREFIX)/include/mongoose.h install -Dm644 mongoose.h $(DESTDIR)$(PREFIX)/include/mongoose.h
uninstall: uninstall:
rm -rf $(DESTDIR)$(PREFIX)/lib/libmongoose.a $(DESTDIR)$(PREFIX)/lib/libmongoose.so.$(SOVERSION) $(DESTDIR)$(PREFIX)/include/mongoose.h $(DESTDIR)$(PREFIX)/lib/libmongoose.so rm -rf $(DESTDIR)$(PREFIX)/lib/libmongoose.a $(DESTDIR)$(PREFIX)/lib/libmongoose.so.$(VERSION) $(DESTDIR)$(PREFIX)/include/mongoose.h $(DESTDIR)$(PREFIX)/lib/libmongoose.so
arm: Makefile mongoose.c mongoose.h test/unit_test.c mongoose.c: Makefile $(wildcard src/*)
$(ARM) arm-none-eabi-gcc mongoose.c -c -Itest -DMG_ARCH=MG_ARCH_CUSTOM $(OPTS) $(WARN) $(INCS) -DMG_MAX_HTTP_HEADERS=5 -DMG_ENABLE_LINES -DMG_ENABLE_DIRECTORY_LISTING=0 -DMG_ENABLE_SSI=1
mongoose.c: $(SRCS) Makefile
(cat src/license.h; echo; echo '#include "mongoose.h"' ; (for F in src/private.h src/*.c ; do echo; echo '#ifdef MG_ENABLE_LINES'; echo "#line 1 \"$$F\""; echo '#endif'; cat $$F | sed -e 's,#include ".*,,'; done))> $@ (cat src/license.h; echo; echo '#include "mongoose.h"' ; (for F in src/private.h src/*.c ; do echo; echo '#ifdef MG_ENABLE_LINES'; echo "#line 1 \"$$F\""; echo '#endif'; cat $$F | sed -e 's,#include ".*,,'; done))> $@
mongoose.h: $(HDRS) Makefile mongoose.h: $(HDRS) Makefile
(cat src/license.h src/version.h ; cat src/arch.h src/arch_*.h src/config.h src/str.h src/log.h src/timer.h src/util.h src/url.h src/iobuf.h src/base64.h src/md5.h src/sha1.h src/event.h src/net.h src/http.h src/ssi.h src/tls.h src/ws.h src/sntp.h src/mqtt.h src/dns.h | sed -e 's,#include ".*,,' -e 's,^#pragma once,,'; echo; echo '#ifdef __cplusplus'; echo '}'; echo '#endif'; echo '#endif // MONGOOSE_H')> $@ (cat src/license.h; echo; echo '#ifndef MONGOOSE_H'; echo '#define MONGOOSE_H'; echo; cat src/version.h ; echo; echo '#ifdef __cplusplus'; echo 'extern "C" {'; echo '#endif'; cat src/config.h src/arch.h src/arch_*.h src/str.h src/log.h src/timer.h src/util.h src/fs.h src/url.h src/iobuf.h src/base64.h src/md5.h src/sha1.h src/event.h src/net.h src/http.h src/ssi.h src/tls.h src/ws.h src/sntp.h src/mqtt.h src/dns.h | sed -e 's,#include ".*,,' -e 's,^#pragma once,,'; echo; echo '#ifdef __cplusplus'; echo '}'; echo '#endif'; echo '#endif // MONGOOSE_H')> $@
clean: EXAMPLE_TARGET = clean clean:
clean: ex rm -rf $(PROG) *.o *.dSYM unit_test* ut fuzzer *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb slow-unit* _CL_* infer-out data.txt crash-* test/packed_fs.c pack
rm -rf $(PROG) *.o *.dSYM unit_test* ut fuzzer *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb slow-unit* _CL_* infer-out data.txt crash-* @for X in $(EXAMPLES); do $(MAKE) -C $$X clean; done
+17 -8
View File
@@ -4,6 +4,7 @@
[![Build Status]( https://github.com/cesanta/mongoose/workflows/build/badge.svg)](https://github.com/cesanta/mongoose/actions) [![Build Status]( https://github.com/cesanta/mongoose/workflows/build/badge.svg)](https://github.com/cesanta/mongoose/actions)
[![Code Coverage](https://codecov.io/gh/cesanta/mongoose/branch/master/graph/badge.svg)](https://codecov.io/gh/cesanta/mongoose) [![Code Coverage](https://codecov.io/gh/cesanta/mongoose/branch/master/graph/badge.svg)](https://codecov.io/gh/cesanta/mongoose)
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/mongoose.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:mongoose) [![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/mongoose.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:mongoose)
[![Gitter Chat](https://badges.gitter.im/cesanta/mongoose.png)](https://gitter.im/cesanta/mongoose)
Mongoose is a networking library for C/C++. It implements event-driven Mongoose is a networking library for C/C++. It implements event-driven
non-blocking APIs for TCP, UDP, HTTP, WebSocket, MQTT. It is designed for non-blocking APIs for TCP, UDP, HTTP, WebSocket, MQTT. It is designed for
@@ -21,7 +22,8 @@ robust, and easy. Features include:
- Source code is both ISO C and ISO C++ compliant - Source code is both ISO C and ISO C++ compliant
- Works with any network stack with socket API, like LwIP or FreeRTOS-Plus-TCP - Works with any network stack with socket API, like LwIP or FreeRTOS-Plus-TCP
- Very easy to integrate: just copy `mongoose.c` and `mongoose.h` files to your build tree - Very easy to integrate: just copy `mongoose.c` and `mongoose.h` files to your build tree
- Detailed [documentation](https://cesanta.com/docs/) - Detailed [documentation](https://mongoose.ws/documentation/) and
[tutorials](https://mongoose.ws/tutorials/)
# Commercial use # Commercial use
@@ -70,20 +72,27 @@ We take security seriously:
# Supplement software # Supplement software
This software is often used together with Mongoose: This software is often used together with Mongoose:
- [mjson](https://github.com/cesanta/mjson) - a JSON parser. Used to implement - [mjson](https://github.com/cesanta/mjson) - a JSON parser, emitter and
JSON-RPC engine. Used to implement
RESTful APIs that use JSON, or implement data exchange (e.g. over MQTT RESTful APIs that use JSON, or implement data exchange (e.g. over MQTT
or Websocket) that use JSON for data encapsulation or Websocket) that use JSON for data encapsulation
- [elk](https://github.com/cesanta/elk) - a tiny JavaScript interpreter. - [elk](https://github.com/cesanta/elk) - a tiny JavaScript engine.
Used to implement scripting support for customers Used to implement scripting support
# Precompiled web server binary # Precompiled web server binary
We have built a ready-to-go, precompiled web server binary for Windows We have built a ready-to-go, precompiled web server executable application for
and Mac. It is a great tool for sharing your files or website. It has Windows and Mac. It requires no installation and no configuration to start.
a unique feature - an ability to share your local files via a global URL. Simply copy `mongoose.exe` to any directory you want to serve, and double-click
on `mongoose.exe` to start it. Mongoose will iconify to a system tray and
start serving your directory to a local network.
Interested? Go to [download](https://mongoose.ws/) It is a great tool for sharing your files, or for local web or game
development. It has a unique feature - an ability to share your local files via
a global URL.
Visit [download page](https://mongoose.ws/) to try it out.
# Contributions # Contributions
+2602 -411
View File
File diff suppressed because it is too large. Load diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

+1 -1
View File
@@ -36,7 +36,7 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
memcpy(buf + sizeof(*h) + n, answer, sizeof(answer)); // And answer memcpy(buf + sizeof(*h) + n, answer, sizeof(answer)); // And answer
mg_send(c, buf, sizeof(buf)); // And send it! mg_send(c, buf, sizeof(buf)); // And send it!
} }
mg_iobuf_delete(&c->recv, c->recv.len); mg_iobuf_del(&c->recv, 0, c->recv.len);
} }
(void) fn_data; (void) fn_data;
(void) ev_data; (void) ev_data;
+16 -3
View File
@@ -1,10 +1,23 @@
PROG ?= example PROG ?= example
SOURCES ?= ../../mongoose.c main.c mjson.c packed_fs.c
CFLAGS ?= -I../.. -DMG_ENABLE_PACKED_FS=1 $(EXTRA)
FILES_TO_EMBED ?= $(wildcard web_root/*.js) $(wildcard web_root/*.css) $(wildcard web_root/*.html) $(wildcard web_root/images/*.png) $(wildcard images/*.jpg)
all: $(PROG) all: $(PROG)
$(DEBUGGER) ./$(PROG) $(RUN) ./$(PROG)
$(PROG): $(PROG):
$(CC) ../../mongoose.c -I../.. $(CFLAGS) $(EXTRA) -o $(PROG) main.c mjson.c $(CC) ../../test/pack.c -o pack
./pack $(FILES_TO_EMBED) > packed_fs.c
$(CC) -W -Wall -Wextra -Os -g3 $(CFLAGS) -o $(PROG) $(SOURCES)
ROOT ?= $(realpath $(CURDIR)/../..)
DOCKER ?= docker run -it --rm -e Tmp=. -e WINEDEBUG=-all -v $(ROOT):$(ROOT) -w $(CURDIR) mdashnet/vc98 wine
windows:
$(DOCKER) cl.exe /nologo $(CFLAGS) ../../test/pack.c /Fepack.exe
$(DOCKER) cmd /c 'pack.exe $(FILES_TO_EMBED) > packed_fs.c'
$(DOCKER) cl.exe /nologo /O2 $(CFLAGS) $(SOURCES) ws2_32.lib /Fe$(PROG).exe
$(DOCKER) $(PROG).exe
clean: clean:
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb log.txt rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb log.txt packed_fs.c pack
+2 -2
View File
@@ -1,7 +1,7 @@
# A complete device dashboard # A complete device dashboard
This example is a demonstration of how Mongoose Library could be integrated This example is a demonstration of how Mongoose Library could be integrated
into an embedded device and provide a complete device dashbord with the into an embedded device and provide a complete device dashboard with the
following features: following features:
- Multiple logins with different permissions (admin and user) - Multiple logins with different permissions (admin and user)
@@ -14,7 +14,7 @@ following features:
- Live video stream - Live video stream
In essense, this example is a combination of several other examples In essence, this example is a combination of several other examples
pulled together (multiple-logins, dashboard, live-log, video-stream). pulled together (multiple-logins, dashboard, live-log, video-stream).
# Screenshots # Screenshots
+8 -5
View File
@@ -36,13 +36,13 @@ static bool update_config(struct mg_http_message *hm, struct config *cfg) {
char buf[256]; char buf[256];
double dv; double dv;
if (mjson_get_number(hm->body.ptr, hm->body.len, "$.value1", &dv)) { if (mjson_get_number(hm->body.ptr, hm->body.len, "$.value1", &dv)) {
s_config.value1 = dv; cfg->value1 = dv;
changed = true; changed = true;
} }
if (mjson_get_string(hm->body.ptr, hm->body.len, "$.value2", buf, if (mjson_get_string(hm->body.ptr, hm->body.len, "$.value2", buf,
sizeof(buf)) > 0) { sizeof(buf)) > 0) {
free(s_config.value2); free(cfg->value2);
s_config.value2 = strdup(buf); cfg->value2 = strdup(buf);
changed = true; changed = true;
} }
return changed; return changed;
@@ -119,7 +119,9 @@ static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
"Pragma: no-cache\r\nExpires: Thu, 01 Dec 1994 16:00:00 GMT\r\n" "Pragma: no-cache\r\nExpires: Thu, 01 Dec 1994 16:00:00 GMT\r\n"
"Content-Type: multipart/x-mixed-replace; boundary=--foo\r\n\r\n"); "Content-Type: multipart/x-mixed-replace; boundary=--foo\r\n\r\n");
} else if (mg_http_match_uri(hm, "/api/log/static")) { } else if (mg_http_match_uri(hm, "/api/log/static")) {
mg_http_serve_file(c, hm, "log.txt", "text/plain", ""); struct mg_http_serve_opts opts;
memset(&opts, 0, sizeof(opts));
mg_http_serve_file(c, hm, "log.txt", &opts);
} else if (mg_http_match_uri(hm, "/api/log/live")) { } else if (mg_http_match_uri(hm, "/api/log/live")) {
c->label[0] = 'L'; // Mark that connection as live log listener c->label[0] = 'L'; // Mark that connection as live log listener
mg_printf(c, "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"); mg_printf(c, "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
@@ -129,7 +131,8 @@ static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
u->token); u->token);
mg_http_printf_chunk(c, ""); mg_http_printf_chunk(c, "");
} else { } else {
struct mg_http_serve_opts opts = {.root_dir = "web_root"}; struct mg_http_serve_opts opts = {0};
opts.root_dir = "web_root";
mg_http_serve_dir(c, ev_data, &opts); mg_http_serve_dir(c, ev_data, &opts);
} }
} }
+5 -2
View File
@@ -3,7 +3,10 @@ ROOTDIR = $(realpath $(CURDIR)/../..)
all: example all: example
example: main/main.c Makefile example:
true
build: main/main.c Makefile
docker run --rm -v $(ROOTDIR):$(ROOTDIR) -w $(THISDIR) espressif/idf idf.py build docker run --rm -v $(ROOTDIR):$(ROOTDIR) -w $(THISDIR) espressif/idf idf.py build
COMPORT ?= /dev/cu.SLAB_USBtoUART COMPORT ?= /dev/cu.SLAB_USBtoUART
@@ -12,4 +15,4 @@ flash:
cd build && $(ESPTOOL) --chip esp32 -p $(COMPORT) -b 460800 --before=default_reset --after=hard_reset write_flash --flash_mode dio --flash_freq 40m --flash_size 2MB 0x8000 partition_table/partition-table.bin 0x1000 bootloader/bootloader.bin 0x100000 mongoose-esp32-example.bin cd build && $(ESPTOOL) --chip esp32 -p $(COMPORT) -b 460800 --before=default_reset --after=hard_reset write_flash --flash_mode dio --flash_freq 40m --flash_size 2MB 0x8000 partition_table/partition-table.bin 0x1000 bootloader/bootloader.bin 0x100000 mongoose-esp32-example.bin
clean: clean:
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb mongoose mongoose_* mongoose.* build sdkconfig rm -rf build
+1 -1
View File
@@ -2,4 +2,4 @@ idf_component_register(SRCS "main.c"
"wifi.c" "wifi.c"
"../../../mongoose.c" "../../../mongoose.c"
INCLUDE_DIRS "../../..") INCLUDE_DIRS "../../..")
component_compile_options(-DMG_ENABLE_DIRECTORY_LISTING=1 -DMG_ENABLE_LINES) component_compile_options(-DMG_ENABLE_LINES)
+5 -2
View File
@@ -3,8 +3,11 @@ ROOTDIR = $(realpath $(CURDIR)/../..)
all: example all: example
example: src/main/main.c src/main/wifi.c Makefile example:
true
build: src/main/main.c src/main/wifi.c Makefile
docker run --rm -v $(ROOTDIR):$(ROOTDIR) -w $(THISDIR) docker.io/mdashnet/8266 make -C src defconfig app docker run --rm -v $(ROOTDIR):$(ROOTDIR) -w $(THISDIR) docker.io/mdashnet/8266 make -C src defconfig app
clean: clean:
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb mongoose mongoose_* mongoose.* src/build src/sdkconfig rm -rf build
+2 -2
View File
@@ -14,7 +14,7 @@ CFLAGS += -L$(OPENSSL)/lib -lssl -lcrypto
endif endif
all: $(PROG) all: $(PROG)
$(DEBUGGER) ./$(PROG) $(ARGS) $(RUN) ./$(PROG) $(ARGS)
$(PROG): main.c $(PROG): main.c
$(CC) ../../mongoose.c -I../.. -W -Wall $(CFLAGS) -o $(PROG) main.c $(CC) ../../mongoose.c -I../.. -W -Wall $(CFLAGS) -o $(PROG) main.c
@@ -22,7 +22,7 @@ $(PROG): main.c
linux: all linux: all
linux: CFLAGS += -O2 -g -fsanitize=address,undefined,shift,null,return,bounds,alignment,object-size,bool,enum -static-libasan linux: CFLAGS += -O2 -g -fsanitize=address,undefined,shift,null,return,bounds,alignment,object-size,bool,enum -static-libasan
linux: CC = $(LIN) cc linux: CC = $(LIN) cc
linux: DEBUGGER = $(LIN) linux: RUN = $(LIN)
clean: clean:
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb
-507
View File
@@ -1,507 +0,0 @@
Subject: O=Digital Signature Trust Co., CN=DST Root CA X3
Not Before: Sep 30 21:12:19 2000 GMT
Not After : Sep 30 14:01:15 2021 GMT
-----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
-----END CERTIFICATE-----
Subject: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root
Not Before: May 12 18:46:00 2000 GMT
Not After : May 12 23:59:00 2025 GMT
-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
-----END CERTIFICATE-----
Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
Not Before: May 21 04:00:00 2002 GMT
Not After : May 21 04:00:00 2022 GMT
-----BEGIN CERTIFICATE-----
MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
-----END CERTIFICATE-----
Subject: C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec Class 3 ECC 256 bit SSL CA - G2
Not Before: May 12 00:00:00 2015 GMT
Not After : May 11 23:59:59 2025 GMT
-----BEGIN CERTIFICATE-----
MIIEajCCA1KgAwIBAgIQP5KHvp0dpKN6nfYoLndaxDANBgkqhkiG9w0BAQsFADCB
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
aG9yaXR5IC0gRzUwHhcNMTUwNTEyMDAwMDAwWhcNMjUwNTExMjM1OTU5WjCBgDEL
MAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYD
VQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMTEwLwYDVQQDEyhTeW1hbnRlYyBD
bGFzcyAzIEVDQyAyNTYgYml0IFNTTCBDQSAtIEcyMFkwEwYHKoZIzj0CAQYIKoZI
zj0DAQcDQgAEDxukkdfnrOfRTk63ZFvhj39uBNOrONtEt0Bcbb2WljffeYmGZ/ex
Hwie/WM7RoyfvVPoFdyXPiuBRq2Gfw4BOaOCAV0wggFZMC4GCCsGAQUFBwEBBCIw
IDAeBggrBgEFBQcwAYYSaHR0cDovL3Muc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYB
Af8CAQAwZQYDVR0gBF4wXDBaBgpghkgBhvhFAQc2MEwwIwYIKwYBBQUHAgEWF2h0
dHBzOi8vZC5zeW1jYi5jb20vY3BzMCUGCCsGAQUFBwICMBkaF2h0dHBzOi8vZC5z
eW1jYi5jb20vcnBhMC8GA1UdHwQoMCYwJKAioCCGHmh0dHA6Ly9zLnN5bWNiLmNv
bS9wY2EzLWc1LmNybDAOBgNVHQ8BAf8EBAMCAQYwKwYDVR0RBCQwIqQgMB4xHDAa
BgNVBAMTE1NZTUMtRUNDLUNBLXAyNTYtMjIwHQYDVR0OBBYEFCXwiuFLetkBlQrt
xlPxjHgf2fP4MB8GA1UdIwQYMBaAFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG
SIb3DQEBCwUAA4IBAQAMMGUXBaWTdaLxsTGtcB/naqjIQrLvoV9NG+7MoHpGd/69
dZ/h2zOy7sGFUHoG/0HGRA9rxT/5w5GkEVIVkxtWyIWWq6rs4CTZt8Bej/KHYRbo
jtEDUkCTZSTLiCvguPyvinXgxy+LHT+PmdtEfXsvcdbeBSWUYpOsDYvD2hNtz9dw
Od5nBosMApmdxt+z7LQyZu8wMnfI1U6IMO+RWowxZ8uy0oswdFYd32l9xe+aAE/k
y9alLu/M9pvxiUKufqHJRgDBKA6uDjHLMPX+/nxXaNCPX3SI4KVZ1stHQ/U5oNlM
dHN9umAvlU313g0IgJrjsQ2nIdf9dsdP+6lrmP7s
-----END CERTIFICATE-----
Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
Not Before: Nov 8 00:00:00 2006 GMT
Not After : Jul 16 23:59:59 2036 GMT
-----BEGIN CERTIFICATE-----
MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL
MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln
biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1
nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex
t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz
SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG
BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+
rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/
NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH
BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv
MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE
p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y
5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK
WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ
4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N
hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
-----END CERTIFICATE-----
Subject: C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification Authority
Not Before: Jun 29 17:06:20 2004 GMT
Not After : Jun 29 17:06:20 2034 GMT
-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
ReYNnyicsbkqWletNw+vHX/bvZ8=
-----END CERTIFICATE-----
# Note: Amazon ATS endpoint uses this (2018/12/18)
Subject: C=US, O=Starfield Technologies, Inc., OU=Starfield Class 2 Certification Authority
Not Before: Jun 29 17:39:16 2004 GMT
Not After : Jun 29 17:39:16 2034 GMT
-----BEGIN CERTIFICATE-----
MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl
MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp
U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw
NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE
ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp
ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3
DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf
8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN
+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0
X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa
K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA
1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G
A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR
zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0
YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD
bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w
DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3
L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D
eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp
VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY
WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=
-----END CERTIFICATE-----
Not Before: Sep 1 00:00:00 2009 GMT
Not After : Dec 31 23:59:59 2037 GMT
Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Root Certificate Authority - G2
-----BEGIN CERTIFICATE-----
MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw
MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp
Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg
nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1
HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N
Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN
dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0
HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G
CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU
sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3
4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg
8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
-----END CERTIFICATE-----
Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Services Root Certificate Authority - G2
Not Before: Sep 1 00:00:00 2009 GMT
Not After : Dec 31 23:59:59 2037 GMT
-----BEGIN CERTIFICATE-----
MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs
ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5
MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD
VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy
ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy
dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p
OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2
8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K
Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe
hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk
6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q
AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI
bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB
ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z
qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn
0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN
sSi6
-----END CERTIFICATE-----
Subject: OU=GlobalSign Root CA - R2, O=GlobalSign, CN=GlobalSign
Not Before: Dec 15 08:00:00 2006 GMT
Not After : Dec 15 08:00:00 2021 GMT
-----BEGIN CERTIFICATE-----
MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
-----END CERTIFICATE-----
Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA
Not Before: Nov 10 00:00:00 2006 GMT
Not After : Nov 10 00:00:00 2031 GMT
-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
+OkuE6N36B9K
-----END CERTIFICATE-----
Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA
Not Before: Nov 10 00:00:00 2006 GMT
Not After : Nov 10 00:00:00 2031 GMT
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----
# *.azure-devices.de use this root.
Subject: C = DE, O = D-Trust GmbH, CN = D-TRUST Root Class 3 CA 2 2009
Not Before: Nov 5 08:35:58 2009 GMT
Not After : Nov 5 08:35:58 2029 GMT
-----BEGIN CERTIFICATE-----
MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF
MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD
bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha
ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM
HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03
UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42
tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R
ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM
lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp
/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G
A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G
A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj
dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy
MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl
cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js
L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL
BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni
acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0
o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K
zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8
PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y
Johw1+qRzT65ysCQblrGXnRl11z+o+I=
-----END CERTIFICATE-----
# https://www.amazontrust.com/repository/
Subject: C = US, O = Amazon, CN = Amazon Root CA 1
Not Before: May 26 00:00:00 2015 GMT
Not After : Jan 17 00:00:00 2038 GMT
-----BEGIN CERTIFICATE-----
MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF
ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL
MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj
ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM
9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw
IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6
VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L
93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm
jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA
A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI
U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs
N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv
o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU
5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy
rqXRfboQnoZsG4q5WTP468SQvvG5
-----END CERTIFICATE-----
Subject: C = US, O = Amazon, CN = Amazon Root CA 2
Not Before: May 26 00:00:00 2015 GMT
Not After : May 26 00:00:00 2040 GMT
-----BEGIN CERTIFICATE-----
MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF
ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL
MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK
gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ
W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg
1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K
8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r
2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me
z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR
8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj
mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz
7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6
+XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI
0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB
Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm
UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2
LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY
+gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS
k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl
7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm
btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl
urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+
fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63
n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE
76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H
9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT
4PsJYGw=
-----END CERTIFICATE-----
Not Before: May 26 00:00:00 2015 GMT
Not After : May 26 00:00:00 2040 GMT
Subject: C = US, O = Amazon, CN = Amazon Root CA 3
-----BEGIN CERTIFICATE-----
MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5
MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg
Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl
ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j
QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr
ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr
BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM
YyRIHN8wfdVoOw==
-----END CERTIFICATE-----
Not Before: May 26 00:00:00 2015 GMT
Not After : May 26 00:00:00 2040 GMT
Subject: C = US, O = Amazon, CN = Amazon Root CA 4
-----BEGIN CERTIFICATE-----
MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5
MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg
Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi
9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk
M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB
/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB
MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw
CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW
1KyLa2tJElMzrdfkviT8tQp21KW8EA==
-----END CERTIFICATE-----
Not Before: Nov 10 00:00:00 2006 GMT
Not After : Nov 10 00:00:00 2031 GMT
Subject: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----
Not Before: Nov 13 00:00:00 2012 GMT
Not After : Jan 19 03:14:07 2038 GMT
Subject: OU = GlobalSign ECC Root CA - R4, O = GlobalSign, CN = GlobalSign
-----BEGIN CERTIFICATE-----
MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk
MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH
bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD
QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ
FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw
DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F
uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX
kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs
ewv4n4Q=
-----END CERTIFICATE-----
Not Before: Nov 1 00:00:42 2018 GMT
Not After : Nov 1 00:00:42 2042 GMT
Subject: C = US, O = Google Trust Services LLC, CN = GTS LTSR
-----BEGIN CERTIFICATE-----
MIIBxTCCAWugAwIBAgINAfD3nVndblD3QnNxUDAKBggqhkjOPQQDAjBEMQswCQYD
VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzERMA8G
A1UEAxMIR1RTIExUU1IwHhcNMTgxMTAxMDAwMDQyWhcNNDIxMTAxMDAwMDQyWjBE
MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM
QzERMA8GA1UEAxMIR1RTIExUU1IwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATN
8YyO2u+yCQoZdwAkUNv5c3dokfULfrA6QJgFV2XMuENtQZIG5HUOS6jFn8f0ySlV
eORCxqFyjDJyRn86d+Iko0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUw
AwEB/zAdBgNVHQ4EFgQUPv7/zFLrvzQ+PfNA0OQlsV+4u1IwCgYIKoZIzj0EAwID
SAAwRQIhAPKuf/VtBHqGw3TUwUIq7TfaExp3bH7bjCBmVXJupT9FAiBr0SmCtsuk
miGgpajjf/gFigGM34F9021bCWs1MbL0SA==
-----END CERTIFICATE-----
+1
View File
@@ -0,0 +1 @@
../../test/data/ca.pem
+1 -1
View File
@@ -12,7 +12,7 @@
#include "mongoose.h" #include "mongoose.h"
// The very first web page in history. You can replace it from command line // The very first web page in history. You can replace it from command line
static const char *s_url = "http://info.cern.ch//foo"; static const char *s_url = "http://info.cern.ch/";
// Print HTTP response and signal that we're done // Print HTTP response and signal that we're done
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
-507
View File
@@ -1,507 +0,0 @@
Subject: O=Digital Signature Trust Co., CN=DST Root CA X3
Not Before: Sep 30 21:12:19 2000 GMT
Not After : Sep 30 14:01:15 2021 GMT
-----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
-----END CERTIFICATE-----
Subject: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root
Not Before: May 12 18:46:00 2000 GMT
Not After : May 12 23:59:00 2025 GMT
-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
-----END CERTIFICATE-----
Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
Not Before: May 21 04:00:00 2002 GMT
Not After : May 21 04:00:00 2022 GMT
-----BEGIN CERTIFICATE-----
MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
-----END CERTIFICATE-----
Subject: C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec Class 3 ECC 256 bit SSL CA - G2
Not Before: May 12 00:00:00 2015 GMT
Not After : May 11 23:59:59 2025 GMT
-----BEGIN CERTIFICATE-----
MIIEajCCA1KgAwIBAgIQP5KHvp0dpKN6nfYoLndaxDANBgkqhkiG9w0BAQsFADCB
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
aG9yaXR5IC0gRzUwHhcNMTUwNTEyMDAwMDAwWhcNMjUwNTExMjM1OTU5WjCBgDEL
MAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYD
VQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMTEwLwYDVQQDEyhTeW1hbnRlYyBD
bGFzcyAzIEVDQyAyNTYgYml0IFNTTCBDQSAtIEcyMFkwEwYHKoZIzj0CAQYIKoZI
zj0DAQcDQgAEDxukkdfnrOfRTk63ZFvhj39uBNOrONtEt0Bcbb2WljffeYmGZ/ex
Hwie/WM7RoyfvVPoFdyXPiuBRq2Gfw4BOaOCAV0wggFZMC4GCCsGAQUFBwEBBCIw
IDAeBggrBgEFBQcwAYYSaHR0cDovL3Muc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYB
Af8CAQAwZQYDVR0gBF4wXDBaBgpghkgBhvhFAQc2MEwwIwYIKwYBBQUHAgEWF2h0
dHBzOi8vZC5zeW1jYi5jb20vY3BzMCUGCCsGAQUFBwICMBkaF2h0dHBzOi8vZC5z
eW1jYi5jb20vcnBhMC8GA1UdHwQoMCYwJKAioCCGHmh0dHA6Ly9zLnN5bWNiLmNv
bS9wY2EzLWc1LmNybDAOBgNVHQ8BAf8EBAMCAQYwKwYDVR0RBCQwIqQgMB4xHDAa
BgNVBAMTE1NZTUMtRUNDLUNBLXAyNTYtMjIwHQYDVR0OBBYEFCXwiuFLetkBlQrt
xlPxjHgf2fP4MB8GA1UdIwQYMBaAFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG
SIb3DQEBCwUAA4IBAQAMMGUXBaWTdaLxsTGtcB/naqjIQrLvoV9NG+7MoHpGd/69
dZ/h2zOy7sGFUHoG/0HGRA9rxT/5w5GkEVIVkxtWyIWWq6rs4CTZt8Bej/KHYRbo
jtEDUkCTZSTLiCvguPyvinXgxy+LHT+PmdtEfXsvcdbeBSWUYpOsDYvD2hNtz9dw
Od5nBosMApmdxt+z7LQyZu8wMnfI1U6IMO+RWowxZ8uy0oswdFYd32l9xe+aAE/k
y9alLu/M9pvxiUKufqHJRgDBKA6uDjHLMPX+/nxXaNCPX3SI4KVZ1stHQ/U5oNlM
dHN9umAvlU313g0IgJrjsQ2nIdf9dsdP+6lrmP7s
-----END CERTIFICATE-----
Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
Not Before: Nov 8 00:00:00 2006 GMT
Not After : Jul 16 23:59:59 2036 GMT
-----BEGIN CERTIFICATE-----
MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL
MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln
biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1
nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex
t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz
SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG
BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+
rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/
NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH
BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv
MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE
p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y
5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK
WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ
4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N
hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
-----END CERTIFICATE-----
Subject: C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification Authority
Not Before: Jun 29 17:06:20 2004 GMT
Not After : Jun 29 17:06:20 2034 GMT
-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
ReYNnyicsbkqWletNw+vHX/bvZ8=
-----END CERTIFICATE-----
# Note: Amazon ATS endpoint uses this (2018/12/18)
Subject: C=US, O=Starfield Technologies, Inc., OU=Starfield Class 2 Certification Authority
Not Before: Jun 29 17:39:16 2004 GMT
Not After : Jun 29 17:39:16 2034 GMT
-----BEGIN CERTIFICATE-----
MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl
MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp
U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw
NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE
ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp
ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3
DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf
8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN
+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0
X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa
K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA
1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G
A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR
zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0
YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD
bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w
DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3
L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D
eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp
VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY
WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=
-----END CERTIFICATE-----
Not Before: Sep 1 00:00:00 2009 GMT
Not After : Dec 31 23:59:59 2037 GMT
Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Root Certificate Authority - G2
-----BEGIN CERTIFICATE-----
MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw
MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp
Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg
nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1
HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N
Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN
dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0
HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G
CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU
sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3
4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg
8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
-----END CERTIFICATE-----
Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Services Root Certificate Authority - G2
Not Before: Sep 1 00:00:00 2009 GMT
Not After : Dec 31 23:59:59 2037 GMT
-----BEGIN CERTIFICATE-----
MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs
ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5
MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD
VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy
ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy
dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p
OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2
8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K
Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe
hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk
6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q
AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI
bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB
ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z
qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn
0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN
sSi6
-----END CERTIFICATE-----
Subject: OU=GlobalSign Root CA - R2, O=GlobalSign, CN=GlobalSign
Not Before: Dec 15 08:00:00 2006 GMT
Not After : Dec 15 08:00:00 2021 GMT
-----BEGIN CERTIFICATE-----
MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
-----END CERTIFICATE-----
Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA
Not Before: Nov 10 00:00:00 2006 GMT
Not After : Nov 10 00:00:00 2031 GMT
-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
+OkuE6N36B9K
-----END CERTIFICATE-----
Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA
Not Before: Nov 10 00:00:00 2006 GMT
Not After : Nov 10 00:00:00 2031 GMT
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----
# *.azure-devices.de use this root.
Subject: C = DE, O = D-Trust GmbH, CN = D-TRUST Root Class 3 CA 2 2009
Not Before: Nov 5 08:35:58 2009 GMT
Not After : Nov 5 08:35:58 2029 GMT
-----BEGIN CERTIFICATE-----
MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF
MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD
bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha
ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM
HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03
UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42
tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R
ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM
lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp
/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G
A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G
A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj
dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy
MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl
cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js
L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL
BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni
acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0
o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K
zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8
PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y
Johw1+qRzT65ysCQblrGXnRl11z+o+I=
-----END CERTIFICATE-----
# https://www.amazontrust.com/repository/
Subject: C = US, O = Amazon, CN = Amazon Root CA 1
Not Before: May 26 00:00:00 2015 GMT
Not After : Jan 17 00:00:00 2038 GMT
-----BEGIN CERTIFICATE-----
MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF
ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL
MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj
ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM
9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw
IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6
VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L
93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm
jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA
A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI
U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs
N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv
o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU
5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy
rqXRfboQnoZsG4q5WTP468SQvvG5
-----END CERTIFICATE-----
Subject: C = US, O = Amazon, CN = Amazon Root CA 2
Not Before: May 26 00:00:00 2015 GMT
Not After : May 26 00:00:00 2040 GMT
-----BEGIN CERTIFICATE-----
MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF
ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL
MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK
gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ
W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg
1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K
8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r
2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me
z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR
8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj
mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz
7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6
+XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI
0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB
Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm
UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2
LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY
+gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS
k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl
7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm
btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl
urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+
fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63
n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE
76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H
9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT
4PsJYGw=
-----END CERTIFICATE-----
Not Before: May 26 00:00:00 2015 GMT
Not After : May 26 00:00:00 2040 GMT
Subject: C = US, O = Amazon, CN = Amazon Root CA 3
-----BEGIN CERTIFICATE-----
MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5
MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg
Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl
ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j
QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr
ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr
BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM
YyRIHN8wfdVoOw==
-----END CERTIFICATE-----
Not Before: May 26 00:00:00 2015 GMT
Not After : May 26 00:00:00 2040 GMT
Subject: C = US, O = Amazon, CN = Amazon Root CA 4
-----BEGIN CERTIFICATE-----
MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5
MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg
Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi
9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk
M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB
/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB
MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw
CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW
1KyLa2tJElMzrdfkviT8tQp21KW8EA==
-----END CERTIFICATE-----
Not Before: Nov 10 00:00:00 2006 GMT
Not After : Nov 10 00:00:00 2031 GMT
Subject: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----
Not Before: Nov 13 00:00:00 2012 GMT
Not After : Jan 19 03:14:07 2038 GMT
Subject: OU = GlobalSign ECC Root CA - R4, O = GlobalSign, CN = GlobalSign
-----BEGIN CERTIFICATE-----
MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk
MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH
bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD
QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ
FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw
DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F
uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX
kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs
ewv4n4Q=
-----END CERTIFICATE-----
Not Before: Nov 1 00:00:42 2018 GMT
Not After : Nov 1 00:00:42 2042 GMT
Subject: C = US, O = Google Trust Services LLC, CN = GTS LTSR
-----BEGIN CERTIFICATE-----
MIIBxTCCAWugAwIBAgINAfD3nVndblD3QnNxUDAKBggqhkjOPQQDAjBEMQswCQYD
VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzERMA8G
A1UEAxMIR1RTIExUU1IwHhcNMTgxMTAxMDAwMDQyWhcNNDIxMTAxMDAwMDQyWjBE
MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM
QzERMA8GA1UEAxMIR1RTIExUU1IwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATN
8YyO2u+yCQoZdwAkUNv5c3dokfULfrA6QJgFV2XMuENtQZIG5HUOS6jFn8f0ySlV
eORCxqFyjDJyRn86d+Iko0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUw
AwEB/zAdBgNVHQ4EFgQUPv7/zFLrvzQ+PfNA0OQlsV+4u1IwCgYIKoZIzj0EAwID
SAAwRQIhAPKuf/VtBHqGw3TUwUIq7TfaExp3bH7bjCBmVXJupT9FAiBr0SmCtsuk
miGgpajjf/gFigGM34F9021bCWs1MbL0SA==
-----END CERTIFICATE-----
+1
View File
@@ -0,0 +1 @@
../../test/data/ca.pem
+1 -1
View File
@@ -39,7 +39,7 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
connected = true; connected = true;
LOG(LL_DEBUG, LOG(LL_DEBUG,
("Connected to proxy, status: %.*s", (int) hm.uri.len, hm.uri.ptr)); ("Connected to proxy, status: %.*s", (int) hm.uri.len, hm.uri.ptr));
mg_iobuf_delete(&c->recv, n); mg_iobuf_del(&c->recv, 0, n);
// Send request to the target server // Send request to the target server
mg_printf(c, "GET / HTTP/1.0\r\nHost: %.*s\r\n\r\n", (int) host.len, mg_printf(c, "GET / HTTP/1.0\r\nHost: %.*s\r\n\r\n", (int) host.len,
host.ptr); host.ptr);
+1 -1
View File
@@ -12,7 +12,7 @@ all: $(PROG)
$(DEBUGGER) ./$(PROG) $(ARGS) $(DEBUGGER) ./$(PROG) $(ARGS)
$(PROG): main.c $(PROG): main.c
$(CC) ../../mongoose.c -I../.. -W -Wall -DMG_ENABLE_LINES=1 -DMG_ENABLE_DIRECTORY_LISTING=1 $(CFLAGS) -o $(PROG) main.c $(CC) ../../mongoose.c -I../.. -W -Wall -DMG_ENABLE_LINES=1 $(CFLAGS) -o $(PROG) main.c
clean: clean:
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb
-43
View File
@@ -1,43 +0,0 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
11:2a:0e:3c:6a:8c:85:ff:6e:6a:bc:db:95:51:70:ce:b4:30:78:c7
Signature Algorithm: ecdsa-with-SHA256
Issuer: C = IE, L = Dublin, O = Cesanta, CN = Test Root
Validity
Not Before: May 9 21:51:44 2020 GMT
Not After : May 9 21:51:44 2050 GMT
Subject: C = IE, L = Dublin, O = Cesanta, CN = Test Root
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:2c:ab:d1:02:66:24:96:d7:12:3e:09:50:4f:f1:
50:ee:51:e8:55:03:5e:ba:b1:1d:98:b2:72:79:27:
a8:1b:31:0d:5d:50:21:ff:42:f2:da:74:17:5e:53:
b2:65:41:c1:fc:84:de:4a:11:b9:8c:f4:19:d9:c4:
ca:2b:ea:eb:2c
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
X509v3 Basic Constraints:
CA:TRUE
X509v3 Key Usage:
Digital Signature, Key Encipherment, Key Agreement, Certificate Sign, CRL Sign
Signature Algorithm: ecdsa-with-SHA256
30:46:02:21:00:9c:71:6c:00:8c:06:41:0c:91:2f:cd:41:d3:
87:47:e9:df:3a:22:ad:25:7c:bf:0e:2b:39:dd:7a:0c:4e:68:
1d:02:21:00:8f:c1:22:30:10:61:5d:51:10:ea:08:2d:02:63:
67:67:32:b5:06:63:96:57:bb:78:47:0a:88:d9:19:2e:f3:be
-----BEGIN CERTIFICATE-----
MIIBqjCCAU+gAwIBAgIUESoOPGqMhf9uarzblVFwzrQweMcwCgYIKoZIzj0EAwIw
RDELMAkGA1UEBhMCSUUxDzANBgNVBAcMBkR1YmxpbjEQMA4GA1UECgwHQ2VzYW50
YTESMBAGA1UEAwwJVGVzdCBSb290MCAXDTIwMDUwOTIxNTE0NFoYDzIwNTAwNTA5
MjE1MTQ0WjBEMQswCQYDVQQGEwJJRTEPMA0GA1UEBwwGRHVibGluMRAwDgYDVQQK
DAdDZXNhbnRhMRIwEAYDVQQDDAlUZXN0IFJvb3QwWTATBgcqhkjOPQIBBggqhkjO
PQMBBwNCAAQsq9ECZiSW1xI+CVBP8VDuUehVA166sR2YsnJ5J6gbMQ1dUCH/QvLa
dBdeU7JlQcH8hN5KEbmM9BnZxMor6ussox0wGzAMBgNVHRMEBTADAQH/MAsGA1Ud
DwQEAwIBrjAKBggqhkjOPQQDAgNJADBGAiEAnHFsAIwGQQyRL81B04dH6d86Iq0l
fL8OKzndegxOaB0CIQCPwSIwEGFdURDqCC0CY2dnMrUGY5ZXu3hHCojZGS7zvg==
-----END CERTIFICATE-----
+1
View File
@@ -0,0 +1 @@
../../test/data/ca.pem
+1 -1
View File
@@ -25,7 +25,7 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
struct mg_tls_opts opts = { struct mg_tls_opts opts = {
//.ca = "ca.pem", // Uncomment to enable two-way SSL //.ca = "ca.pem", // Uncomment to enable two-way SSL
.cert = "server.pem", // Certificate PEM file .cert = "server.pem", // Certificate PEM file
.certkey = "server.pem", // This pem conains both cert and key .certkey = "server.pem", // This pem contains both cert and key
}; };
mg_tls_init(c, &opts); mg_tls_init(c, &opts);
} else if (ev == MG_EV_HTTP_MSG) { } else if (ev == MG_EV_HTTP_MSG) {
-507
View File
@@ -1,507 +0,0 @@
Subject: O=Digital Signature Trust Co., CN=DST Root CA X3
Not Before: Sep 30 21:12:19 2000 GMT
Not After : Sep 30 14:01:15 2021 GMT
-----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
-----END CERTIFICATE-----
Subject: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root
Not Before: May 12 18:46:00 2000 GMT
Not After : May 12 23:59:00 2025 GMT
-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
-----END CERTIFICATE-----
Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
Not Before: May 21 04:00:00 2002 GMT
Not After : May 21 04:00:00 2022 GMT
-----BEGIN CERTIFICATE-----
MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
-----END CERTIFICATE-----
Subject: C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec Class 3 ECC 256 bit SSL CA - G2
Not Before: May 12 00:00:00 2015 GMT
Not After : May 11 23:59:59 2025 GMT
-----BEGIN CERTIFICATE-----
MIIEajCCA1KgAwIBAgIQP5KHvp0dpKN6nfYoLndaxDANBgkqhkiG9w0BAQsFADCB
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
aG9yaXR5IC0gRzUwHhcNMTUwNTEyMDAwMDAwWhcNMjUwNTExMjM1OTU5WjCBgDEL
MAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYD
VQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMTEwLwYDVQQDEyhTeW1hbnRlYyBD
bGFzcyAzIEVDQyAyNTYgYml0IFNTTCBDQSAtIEcyMFkwEwYHKoZIzj0CAQYIKoZI
zj0DAQcDQgAEDxukkdfnrOfRTk63ZFvhj39uBNOrONtEt0Bcbb2WljffeYmGZ/ex
Hwie/WM7RoyfvVPoFdyXPiuBRq2Gfw4BOaOCAV0wggFZMC4GCCsGAQUFBwEBBCIw
IDAeBggrBgEFBQcwAYYSaHR0cDovL3Muc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYB
Af8CAQAwZQYDVR0gBF4wXDBaBgpghkgBhvhFAQc2MEwwIwYIKwYBBQUHAgEWF2h0
dHBzOi8vZC5zeW1jYi5jb20vY3BzMCUGCCsGAQUFBwICMBkaF2h0dHBzOi8vZC5z
eW1jYi5jb20vcnBhMC8GA1UdHwQoMCYwJKAioCCGHmh0dHA6Ly9zLnN5bWNiLmNv
bS9wY2EzLWc1LmNybDAOBgNVHQ8BAf8EBAMCAQYwKwYDVR0RBCQwIqQgMB4xHDAa
BgNVBAMTE1NZTUMtRUNDLUNBLXAyNTYtMjIwHQYDVR0OBBYEFCXwiuFLetkBlQrt
xlPxjHgf2fP4MB8GA1UdIwQYMBaAFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG
SIb3DQEBCwUAA4IBAQAMMGUXBaWTdaLxsTGtcB/naqjIQrLvoV9NG+7MoHpGd/69
dZ/h2zOy7sGFUHoG/0HGRA9rxT/5w5GkEVIVkxtWyIWWq6rs4CTZt8Bej/KHYRbo
jtEDUkCTZSTLiCvguPyvinXgxy+LHT+PmdtEfXsvcdbeBSWUYpOsDYvD2hNtz9dw
Od5nBosMApmdxt+z7LQyZu8wMnfI1U6IMO+RWowxZ8uy0oswdFYd32l9xe+aAE/k
y9alLu/M9pvxiUKufqHJRgDBKA6uDjHLMPX+/nxXaNCPX3SI4KVZ1stHQ/U5oNlM
dHN9umAvlU313g0IgJrjsQ2nIdf9dsdP+6lrmP7s
-----END CERTIFICATE-----
Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
Not Before: Nov 8 00:00:00 2006 GMT
Not After : Jul 16 23:59:59 2036 GMT
-----BEGIN CERTIFICATE-----
MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL
MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln
biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1
nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex
t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz
SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG
BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+
rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/
NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH
BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv
MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE
p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y
5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK
WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ
4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N
hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
-----END CERTIFICATE-----
Subject: C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification Authority
Not Before: Jun 29 17:06:20 2004 GMT
Not After : Jun 29 17:06:20 2034 GMT
-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
ReYNnyicsbkqWletNw+vHX/bvZ8=
-----END CERTIFICATE-----
# Note: Amazon ATS endpoint uses this (2018/12/18)
Subject: C=US, O=Starfield Technologies, Inc., OU=Starfield Class 2 Certification Authority
Not Before: Jun 29 17:39:16 2004 GMT
Not After : Jun 29 17:39:16 2034 GMT
-----BEGIN CERTIFICATE-----
MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl
MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp
U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw
NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE
ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp
ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3
DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf
8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN
+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0
X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa
K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA
1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G
A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR
zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0
YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD
bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w
DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3
L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D
eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp
VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY
WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=
-----END CERTIFICATE-----
Not Before: Sep 1 00:00:00 2009 GMT
Not After : Dec 31 23:59:59 2037 GMT
Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Root Certificate Authority - G2
-----BEGIN CERTIFICATE-----
MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw
MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp
Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg
nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1
HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N
Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN
dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0
HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G
CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU
sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3
4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg
8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
-----END CERTIFICATE-----
Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Services Root Certificate Authority - G2
Not Before: Sep 1 00:00:00 2009 GMT
Not After : Dec 31 23:59:59 2037 GMT
-----BEGIN CERTIFICATE-----
MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs
ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5
MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD
VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy
ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy
dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p
OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2
8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K
Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe
hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk
6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q
AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI
bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB
ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z
qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn
0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN
sSi6
-----END CERTIFICATE-----
Subject: OU=GlobalSign Root CA - R2, O=GlobalSign, CN=GlobalSign
Not Before: Dec 15 08:00:00 2006 GMT
Not After : Dec 15 08:00:00 2021 GMT
-----BEGIN CERTIFICATE-----
MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
-----END CERTIFICATE-----
Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA
Not Before: Nov 10 00:00:00 2006 GMT
Not After : Nov 10 00:00:00 2031 GMT
-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
+OkuE6N36B9K
-----END CERTIFICATE-----
Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA
Not Before: Nov 10 00:00:00 2006 GMT
Not After : Nov 10 00:00:00 2031 GMT
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----
# *.azure-devices.de use this root.
Subject: C = DE, O = D-Trust GmbH, CN = D-TRUST Root Class 3 CA 2 2009
Not Before: Nov 5 08:35:58 2009 GMT
Not After : Nov 5 08:35:58 2029 GMT
-----BEGIN CERTIFICATE-----
MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF
MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD
bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha
ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM
HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03
UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42
tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R
ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM
lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp
/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G
A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G
A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj
dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy
MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl
cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js
L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL
BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni
acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0
o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K
zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8
PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y
Johw1+qRzT65ysCQblrGXnRl11z+o+I=
-----END CERTIFICATE-----
# https://www.amazontrust.com/repository/
Subject: C = US, O = Amazon, CN = Amazon Root CA 1
Not Before: May 26 00:00:00 2015 GMT
Not After : Jan 17 00:00:00 2038 GMT
-----BEGIN CERTIFICATE-----
MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF
ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL
MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj
ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM
9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw
IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6
VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L
93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm
jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA
A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI
U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs
N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv
o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU
5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy
rqXRfboQnoZsG4q5WTP468SQvvG5
-----END CERTIFICATE-----
Subject: C = US, O = Amazon, CN = Amazon Root CA 2
Not Before: May 26 00:00:00 2015 GMT
Not After : May 26 00:00:00 2040 GMT
-----BEGIN CERTIFICATE-----
MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF
ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL
MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK
gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ
W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg
1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K
8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r
2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me
z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR
8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj
mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz
7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6
+XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI
0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB
Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm
UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2
LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY
+gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS
k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl
7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm
btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl
urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+
fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63
n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE
76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H
9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT
4PsJYGw=
-----END CERTIFICATE-----
Not Before: May 26 00:00:00 2015 GMT
Not After : May 26 00:00:00 2040 GMT
Subject: C = US, O = Amazon, CN = Amazon Root CA 3
-----BEGIN CERTIFICATE-----
MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5
MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg
Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl
ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j
QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr
ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr
BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM
YyRIHN8wfdVoOw==
-----END CERTIFICATE-----
Not Before: May 26 00:00:00 2015 GMT
Not After : May 26 00:00:00 2040 GMT
Subject: C = US, O = Amazon, CN = Amazon Root CA 4
-----BEGIN CERTIFICATE-----
MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5
MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg
Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi
9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk
M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB
/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB
MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw
CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW
1KyLa2tJElMzrdfkviT8tQp21KW8EA==
-----END CERTIFICATE-----
Not Before: Nov 10 00:00:00 2006 GMT
Not After : Nov 10 00:00:00 2031 GMT
Subject: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----
Not Before: Nov 13 00:00:00 2012 GMT
Not After : Jan 19 03:14:07 2038 GMT
Subject: OU = GlobalSign ECC Root CA - R4, O = GlobalSign, CN = GlobalSign
-----BEGIN CERTIFICATE-----
MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk
MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH
bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD
QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ
FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw
DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F
uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX
kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs
ewv4n4Q=
-----END CERTIFICATE-----
Not Before: Nov 1 00:00:42 2018 GMT
Not After : Nov 1 00:00:42 2042 GMT
Subject: C = US, O = Google Trust Services LLC, CN = GTS LTSR
-----BEGIN CERTIFICATE-----
MIIBxTCCAWugAwIBAgINAfD3nVndblD3QnNxUDAKBggqhkjOPQQDAjBEMQswCQYD
VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzERMA8G
A1UEAxMIR1RTIExUU1IwHhcNMTgxMTAxMDAwMDQyWhcNNDIxMTAxMDAwMDQyWjBE
MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM
QzERMA8GA1UEAxMIR1RTIExUU1IwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATN
8YyO2u+yCQoZdwAkUNv5c3dokfULfrA6QJgFV2XMuENtQZIG5HUOS6jFn8f0ySlV
eORCxqFyjDJyRn86d+Iko0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUw
AwEB/zAdBgNVHQ4EFgQUPv7/zFLrvzQ+PfNA0OQlsV+4u1IwCgYIKoZIzj0EAwID
SAAwRQIhAPKuf/VtBHqGw3TUwUIq7TfaExp3bH7bjCBmVXJupT9FAiBr0SmCtsuk
miGgpajjf/gFigGM34F9021bCWs1MbL0SA==
-----END CERTIFICATE-----
+1
View File
@@ -0,0 +1 @@
../../test/data/ca.pem
+27 -22
View File
@@ -32,31 +32,36 @@ static void forward_request(struct mg_http_message *hm,
(int) hm->uri.len, hm->uri.ptr)); (int) hm->uri.len, hm->uri.ptr));
} }
static void forward_fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
struct mg_connection *c2 = fn_data;
if (ev == MG_EV_READ) {
if (c2 != NULL) {
// All incoming data from the backend, forward to the client
mg_send(c2, c->recv.buf, c->recv.len);
mg_iobuf_del(&c->recv, 0, c->recv.len);
}
} else if (ev == MG_EV_CONNECT) {
if (mg_url_is_ssl(s_backend_url)) {
struct mg_tls_opts opts = {.ca = "ca.pem"};
mg_tls_init(c, &opts);
}
}
(void)ev_data;
}
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
struct mg_connection *c2 = fn_data; struct mg_connection *c2 = fn_data;
if (ev == MG_EV_HTTP_MSG) { if (ev == MG_EV_HTTP_MSG) {
struct mg_http_message *hm = (struct mg_http_message *) ev_data; struct mg_http_message *hm = (struct mg_http_message *) ev_data;
if (c->label[0] != 'B' && c2 == NULL) { // Client request, create backend connection Note that we're passing
// Client request, create backend connection Note that we're passing // client connection `c` as fn_data for the created backend connection.
// client connection `c` as fn_data for the created backend connection. c2 = mg_connect(c->mgr, s_backend_url, forward_fn, c);
// This way, we tie together these two connections via `fn_data` pointer: c->fn_data = c2;
// client's c->fn_data points to the backend connection, and backend's
// c->fn_data points to the client connection if (c2 != NULL) {
c2 = mg_connect(c->mgr, s_backend_url, fn, c); forward_request(hm, c2);
c->fn_data = c2; } else {
if (c2 != NULL) { c->is_closing = 1;
c2->is_hexdumping = 1;
c2->label[0] = 'B'; // Mark this connection as backend
} else {
c->is_closing = 1;
}
}
if (c2 != NULL && c2->label[0] == 'B') forward_request(hm, c2);
} else if (ev == MG_EV_READ) {
if (c->label[0] == 'B' && c2 != NULL) {
// All incoming data from the backend, forward to the client
mg_send(c2, c->recv.buf, c->recv.len);
mg_iobuf_delete(&c->recv, c->recv.len);
} }
} else if (ev == MG_EV_CONNECT) { } else if (ev == MG_EV_CONNECT) {
if (mg_url_is_ssl(s_backend_url)) { if (mg_url_is_ssl(s_backend_url)) {
@@ -64,7 +69,7 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
mg_tls_init(c, &opts); mg_tls_init(c, &opts);
} }
} else if (ev == MG_EV_CLOSE) { } else if (ev == MG_EV_CLOSE) {
if (c->label[0] != 'B' && c2 != NULL) c2->is_closing = 1; if (c2 != NULL) c2->is_closing = 1;
c->fn_data = NULL; c->fn_data = NULL;
} }
} }
+1 -1
View File
@@ -1,6 +1,6 @@
PROG ?= example PROG ?= example
ROOT ?= $(realpath $(CURDIR)/../..) ROOT ?= $(realpath $(CURDIR)/../..)
DEFS ?= -DMG_ENABLE_LINES=1 -DMG_ENABLE_DIRECTORY_LISTING=1 -DMG_ENABLE_SSI=1 DEFS ?= -DMG_ENABLE_LINES=1
CFLAGS ?= -I../.. -W -Wall -DMG_ENABLE_IPV6=1 $(DEFS) $(EXTRA) CFLAGS ?= -I../.. -W -Wall -DMG_ENABLE_IPV6=1 $(DEFS) $(EXTRA)
VCFLAGS = /nologo /W3 /O2 /I../.. $(DEFS) $(EXTRA) /link /incremental:no /machine:IX86 VCFLAGS = /nologo /W3 /O2 /I../.. $(DEFS) $(EXTRA) /link /incremental:no /machine:IX86
VC98 = docker run -it --rm -e Tmp=. -v $(ROOT):$(ROOT) -w $(CURDIR) mdashnet/vc98 VC98 = docker run -it --rm -e Tmp=. -v $(ROOT):$(ROOT) -w $(CURDIR) mdashnet/vc98
-507
View File
@@ -1,507 +0,0 @@
Subject: O=Digital Signature Trust Co., CN=DST Root CA X3
Not Before: Sep 30 21:12:19 2000 GMT
Not After : Sep 30 14:01:15 2021 GMT
-----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
-----END CERTIFICATE-----
Subject: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root
Not Before: May 12 18:46:00 2000 GMT
Not After : May 12 23:59:00 2025 GMT
-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
-----END CERTIFICATE-----
Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
Not Before: May 21 04:00:00 2002 GMT
Not After : May 21 04:00:00 2022 GMT
-----BEGIN CERTIFICATE-----
MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
-----END CERTIFICATE-----
Subject: C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec Class 3 ECC 256 bit SSL CA - G2
Not Before: May 12 00:00:00 2015 GMT
Not After : May 11 23:59:59 2025 GMT
-----BEGIN CERTIFICATE-----
MIIEajCCA1KgAwIBAgIQP5KHvp0dpKN6nfYoLndaxDANBgkqhkiG9w0BAQsFADCB
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
aG9yaXR5IC0gRzUwHhcNMTUwNTEyMDAwMDAwWhcNMjUwNTExMjM1OTU5WjCBgDEL
MAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYD
VQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMTEwLwYDVQQDEyhTeW1hbnRlYyBD
bGFzcyAzIEVDQyAyNTYgYml0IFNTTCBDQSAtIEcyMFkwEwYHKoZIzj0CAQYIKoZI
zj0DAQcDQgAEDxukkdfnrOfRTk63ZFvhj39uBNOrONtEt0Bcbb2WljffeYmGZ/ex
Hwie/WM7RoyfvVPoFdyXPiuBRq2Gfw4BOaOCAV0wggFZMC4GCCsGAQUFBwEBBCIw
IDAeBggrBgEFBQcwAYYSaHR0cDovL3Muc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYB
Af8CAQAwZQYDVR0gBF4wXDBaBgpghkgBhvhFAQc2MEwwIwYIKwYBBQUHAgEWF2h0
dHBzOi8vZC5zeW1jYi5jb20vY3BzMCUGCCsGAQUFBwICMBkaF2h0dHBzOi8vZC5z
eW1jYi5jb20vcnBhMC8GA1UdHwQoMCYwJKAioCCGHmh0dHA6Ly9zLnN5bWNiLmNv
bS9wY2EzLWc1LmNybDAOBgNVHQ8BAf8EBAMCAQYwKwYDVR0RBCQwIqQgMB4xHDAa
BgNVBAMTE1NZTUMtRUNDLUNBLXAyNTYtMjIwHQYDVR0OBBYEFCXwiuFLetkBlQrt
xlPxjHgf2fP4MB8GA1UdIwQYMBaAFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG
SIb3DQEBCwUAA4IBAQAMMGUXBaWTdaLxsTGtcB/naqjIQrLvoV9NG+7MoHpGd/69
dZ/h2zOy7sGFUHoG/0HGRA9rxT/5w5GkEVIVkxtWyIWWq6rs4CTZt8Bej/KHYRbo
jtEDUkCTZSTLiCvguPyvinXgxy+LHT+PmdtEfXsvcdbeBSWUYpOsDYvD2hNtz9dw
Od5nBosMApmdxt+z7LQyZu8wMnfI1U6IMO+RWowxZ8uy0oswdFYd32l9xe+aAE/k
y9alLu/M9pvxiUKufqHJRgDBKA6uDjHLMPX+/nxXaNCPX3SI4KVZ1stHQ/U5oNlM
dHN9umAvlU313g0IgJrjsQ2nIdf9dsdP+6lrmP7s
-----END CERTIFICATE-----
Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
Not Before: Nov 8 00:00:00 2006 GMT
Not After : Jul 16 23:59:59 2036 GMT
-----BEGIN CERTIFICATE-----
MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL
MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln
biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1
nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex
t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz
SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG
BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+
rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/
NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH
BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv
MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE
p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y
5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK
WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ
4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N
hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
-----END CERTIFICATE-----
Subject: C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification Authority
Not Before: Jun 29 17:06:20 2004 GMT
Not After : Jun 29 17:06:20 2034 GMT
-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
ReYNnyicsbkqWletNw+vHX/bvZ8=
-----END CERTIFICATE-----
# Note: Amazon ATS endpoint uses this (2018/12/18)
Subject: C=US, O=Starfield Technologies, Inc., OU=Starfield Class 2 Certification Authority
Not Before: Jun 29 17:39:16 2004 GMT
Not After : Jun 29 17:39:16 2034 GMT
-----BEGIN CERTIFICATE-----
MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl
MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp
U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw
NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE
ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp
ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3
DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf
8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN
+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0
X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa
K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA
1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G
A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR
zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0
YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD
bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w
DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3
L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D
eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp
VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY
WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=
-----END CERTIFICATE-----
Not Before: Sep 1 00:00:00 2009 GMT
Not After : Dec 31 23:59:59 2037 GMT
Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Root Certificate Authority - G2
-----BEGIN CERTIFICATE-----
MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw
MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp
Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg
nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1
HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N
Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN
dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0
HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G
CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU
sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3
4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg
8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
-----END CERTIFICATE-----
Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Services Root Certificate Authority - G2
Not Before: Sep 1 00:00:00 2009 GMT
Not After : Dec 31 23:59:59 2037 GMT
-----BEGIN CERTIFICATE-----
MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs
ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5
MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD
VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy
ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy
dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p
OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2
8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K
Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe
hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk
6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q
AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI
bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB
ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z
qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn
0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN
sSi6
-----END CERTIFICATE-----
Subject: OU=GlobalSign Root CA - R2, O=GlobalSign, CN=GlobalSign
Not Before: Dec 15 08:00:00 2006 GMT
Not After : Dec 15 08:00:00 2021 GMT
-----BEGIN CERTIFICATE-----
MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
-----END CERTIFICATE-----
Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA
Not Before: Nov 10 00:00:00 2006 GMT
Not After : Nov 10 00:00:00 2031 GMT
-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
+OkuE6N36B9K
-----END CERTIFICATE-----
Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA
Not Before: Nov 10 00:00:00 2006 GMT
Not After : Nov 10 00:00:00 2031 GMT
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----
# *.azure-devices.de use this root.
Subject: C = DE, O = D-Trust GmbH, CN = D-TRUST Root Class 3 CA 2 2009
Not Before: Nov 5 08:35:58 2009 GMT
Not After : Nov 5 08:35:58 2029 GMT
-----BEGIN CERTIFICATE-----
MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF
MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD
bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha
ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM
HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03
UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42
tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R
ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM
lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp
/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G
A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G
A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj
dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy
MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl
cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js
L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL
BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni
acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0
o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K
zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8
PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y
Johw1+qRzT65ysCQblrGXnRl11z+o+I=
-----END CERTIFICATE-----
# https://www.amazontrust.com/repository/
Subject: C = US, O = Amazon, CN = Amazon Root CA 1
Not Before: May 26 00:00:00 2015 GMT
Not After : Jan 17 00:00:00 2038 GMT
-----BEGIN CERTIFICATE-----
MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF
ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL
MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj
ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM
9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw
IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6
VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L
93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm
jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA
A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI
U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs
N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv
o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU
5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy
rqXRfboQnoZsG4q5WTP468SQvvG5
-----END CERTIFICATE-----
Subject: C = US, O = Amazon, CN = Amazon Root CA 2
Not Before: May 26 00:00:00 2015 GMT
Not After : May 26 00:00:00 2040 GMT
-----BEGIN CERTIFICATE-----
MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF
ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL
MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK
gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ
W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg
1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K
8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r
2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me
z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR
8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj
mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz
7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6
+XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI
0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB
Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm
UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2
LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY
+gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS
k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl
7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm
btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl
urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+
fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63
n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE
76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H
9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT
4PsJYGw=
-----END CERTIFICATE-----
Not Before: May 26 00:00:00 2015 GMT
Not After : May 26 00:00:00 2040 GMT
Subject: C = US, O = Amazon, CN = Amazon Root CA 3
-----BEGIN CERTIFICATE-----
MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5
MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg
Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl
ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j
QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr
ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr
BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM
YyRIHN8wfdVoOw==
-----END CERTIFICATE-----
Not Before: May 26 00:00:00 2015 GMT
Not After : May 26 00:00:00 2040 GMT
Subject: C = US, O = Amazon, CN = Amazon Root CA 4
-----BEGIN CERTIFICATE-----
MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5
MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg
Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi
9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk
M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB
/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB
MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw
CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW
1KyLa2tJElMzrdfkviT8tQp21KW8EA==
-----END CERTIFICATE-----
Not Before: Nov 10 00:00:00 2006 GMT
Not After : Nov 10 00:00:00 2031 GMT
Subject: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----
Not Before: Nov 13 00:00:00 2012 GMT
Not After : Jan 19 03:14:07 2038 GMT
Subject: OU = GlobalSign ECC Root CA - R4, O = GlobalSign, CN = GlobalSign
-----BEGIN CERTIFICATE-----
MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk
MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH
bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD
QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ
FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw
DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F
uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX
kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs
ewv4n4Q=
-----END CERTIFICATE-----
Not Before: Nov 1 00:00:42 2018 GMT
Not After : Nov 1 00:00:42 2042 GMT
Subject: C = US, O = Google Trust Services LLC, CN = GTS LTSR
-----BEGIN CERTIFICATE-----
MIIBxTCCAWugAwIBAgINAfD3nVndblD3QnNxUDAKBggqhkjOPQQDAjBEMQswCQYD
VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzERMA8G
A1UEAxMIR1RTIExUU1IwHhcNMTgxMTAxMDAwMDQyWhcNNDIxMTAxMDAwMDQyWjBE
MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM
QzERMA8GA1UEAxMIR1RTIExUU1IwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATN
8YyO2u+yCQoZdwAkUNv5c3dokfULfrA6QJgFV2XMuENtQZIG5HUOS6jFn8f0ySlV
eORCxqFyjDJyRn86d+Iko0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUw
AwEB/zAdBgNVHQ4EFgQUPv7/zFLrvzQ+PfNA0OQlsV+4u1IwCgYIKoZIzj0EAwID
SAAwRQIhAPKuf/VtBHqGw3TUwUIq7TfaExp3bH7bjCBmVXJupT9FAiBr0SmCtsuk
miGgpajjf/gFigGM34F9021bCWs1MbL0SA==
-----END CERTIFICATE-----
+1
View File
@@ -0,0 +1 @@
../../test/data/ca.pem
+2 -1
View File
@@ -11,7 +11,8 @@ static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
if (ev == MG_EV_HTTP_MSG) { if (ev == MG_EV_HTTP_MSG) {
struct mg_http_message *hm = (struct mg_http_message *) ev_data; struct mg_http_message *hm = (struct mg_http_message *) ev_data;
if (mg_http_match_uri(hm, "/api/log/static")) { if (mg_http_match_uri(hm, "/api/log/static")) {
mg_http_serve_file(c, hm, "log.txt", "text/plain", ""); struct mg_http_serve_opts opts = {.root_dir = NULL};
mg_http_serve_file(c, hm, "log.txt", &opts);
} else if (mg_http_match_uri(hm, "/api/log/live")) { } else if (mg_http_match_uri(hm, "/api/log/live")) {
c->label[0] = 'L'; // Mark that connection as live log listener c->label[0] = 'L'; // Mark that connection as live log listener
mg_printf(c, "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"); mg_printf(c, "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
-507
View File
@@ -1,507 +0,0 @@
Subject: O=Digital Signature Trust Co., CN=DST Root CA X3
Not Before: Sep 30 21:12:19 2000 GMT
Not After : Sep 30 14:01:15 2021 GMT
-----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
-----END CERTIFICATE-----
Subject: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root
Not Before: May 12 18:46:00 2000 GMT
Not After : May 12 23:59:00 2025 GMT
-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
-----END CERTIFICATE-----
Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
Not Before: May 21 04:00:00 2002 GMT
Not After : May 21 04:00:00 2022 GMT
-----BEGIN CERTIFICATE-----
MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
-----END CERTIFICATE-----
Subject: C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec Class 3 ECC 256 bit SSL CA - G2
Not Before: May 12 00:00:00 2015 GMT
Not After : May 11 23:59:59 2025 GMT
-----BEGIN CERTIFICATE-----
MIIEajCCA1KgAwIBAgIQP5KHvp0dpKN6nfYoLndaxDANBgkqhkiG9w0BAQsFADCB
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
aG9yaXR5IC0gRzUwHhcNMTUwNTEyMDAwMDAwWhcNMjUwNTExMjM1OTU5WjCBgDEL
MAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYD
VQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMTEwLwYDVQQDEyhTeW1hbnRlYyBD
bGFzcyAzIEVDQyAyNTYgYml0IFNTTCBDQSAtIEcyMFkwEwYHKoZIzj0CAQYIKoZI
zj0DAQcDQgAEDxukkdfnrOfRTk63ZFvhj39uBNOrONtEt0Bcbb2WljffeYmGZ/ex
Hwie/WM7RoyfvVPoFdyXPiuBRq2Gfw4BOaOCAV0wggFZMC4GCCsGAQUFBwEBBCIw
IDAeBggrBgEFBQcwAYYSaHR0cDovL3Muc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYB
Af8CAQAwZQYDVR0gBF4wXDBaBgpghkgBhvhFAQc2MEwwIwYIKwYBBQUHAgEWF2h0
dHBzOi8vZC5zeW1jYi5jb20vY3BzMCUGCCsGAQUFBwICMBkaF2h0dHBzOi8vZC5z
eW1jYi5jb20vcnBhMC8GA1UdHwQoMCYwJKAioCCGHmh0dHA6Ly9zLnN5bWNiLmNv
bS9wY2EzLWc1LmNybDAOBgNVHQ8BAf8EBAMCAQYwKwYDVR0RBCQwIqQgMB4xHDAa
BgNVBAMTE1NZTUMtRUNDLUNBLXAyNTYtMjIwHQYDVR0OBBYEFCXwiuFLetkBlQrt
xlPxjHgf2fP4MB8GA1UdIwQYMBaAFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG
SIb3DQEBCwUAA4IBAQAMMGUXBaWTdaLxsTGtcB/naqjIQrLvoV9NG+7MoHpGd/69
dZ/h2zOy7sGFUHoG/0HGRA9rxT/5w5GkEVIVkxtWyIWWq6rs4CTZt8Bej/KHYRbo
jtEDUkCTZSTLiCvguPyvinXgxy+LHT+PmdtEfXsvcdbeBSWUYpOsDYvD2hNtz9dw
Od5nBosMApmdxt+z7LQyZu8wMnfI1U6IMO+RWowxZ8uy0oswdFYd32l9xe+aAE/k
y9alLu/M9pvxiUKufqHJRgDBKA6uDjHLMPX+/nxXaNCPX3SI4KVZ1stHQ/U5oNlM
dHN9umAvlU313g0IgJrjsQ2nIdf9dsdP+6lrmP7s
-----END CERTIFICATE-----
Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
Not Before: Nov 8 00:00:00 2006 GMT
Not After : Jul 16 23:59:59 2036 GMT
-----BEGIN CERTIFICATE-----
MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL
MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln
biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1
nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex
t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz
SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG
BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+
rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/
NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH
BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv
MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE
p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y
5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK
WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ
4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N
hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
-----END CERTIFICATE-----
Subject: C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification Authority
Not Before: Jun 29 17:06:20 2004 GMT
Not After : Jun 29 17:06:20 2034 GMT
-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
ReYNnyicsbkqWletNw+vHX/bvZ8=
-----END CERTIFICATE-----
# Note: Amazon ATS endpoint uses this (2018/12/18)
Subject: C=US, O=Starfield Technologies, Inc., OU=Starfield Class 2 Certification Authority
Not Before: Jun 29 17:39:16 2004 GMT
Not After : Jun 29 17:39:16 2034 GMT
-----BEGIN CERTIFICATE-----
MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl
MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp
U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw
NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE
ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp
ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3
DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf
8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN
+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0
X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa
K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA
1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G
A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR
zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0
YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD
bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w
DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3
L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D
eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp
VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY
WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=
-----END CERTIFICATE-----
Not Before: Sep 1 00:00:00 2009 GMT
Not After : Dec 31 23:59:59 2037 GMT
Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Root Certificate Authority - G2
-----BEGIN CERTIFICATE-----
MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw
MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp
Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg
nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1
HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N
Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN
dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0
HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G
CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU
sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3
4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg
8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
-----END CERTIFICATE-----
Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Services Root Certificate Authority - G2
Not Before: Sep 1 00:00:00 2009 GMT
Not After : Dec 31 23:59:59 2037 GMT
-----BEGIN CERTIFICATE-----
MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs
ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5
MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD
VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy
ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy
dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p
OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2
8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K
Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe
hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk
6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q
AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI
bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB
ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z
qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn
0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN
sSi6
-----END CERTIFICATE-----
Subject: OU=GlobalSign Root CA - R2, O=GlobalSign, CN=GlobalSign
Not Before: Dec 15 08:00:00 2006 GMT
Not After : Dec 15 08:00:00 2021 GMT
-----BEGIN CERTIFICATE-----
MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
-----END CERTIFICATE-----
Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA
Not Before: Nov 10 00:00:00 2006 GMT
Not After : Nov 10 00:00:00 2031 GMT
-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
+OkuE6N36B9K
-----END CERTIFICATE-----
Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA
Not Before: Nov 10 00:00:00 2006 GMT
Not After : Nov 10 00:00:00 2031 GMT
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----
# *.azure-devices.de use this root.
Subject: C = DE, O = D-Trust GmbH, CN = D-TRUST Root Class 3 CA 2 2009
Not Before: Nov 5 08:35:58 2009 GMT
Not After : Nov 5 08:35:58 2029 GMT
-----BEGIN CERTIFICATE-----
MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF
MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD
bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha
ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM
HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03
UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42
tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R
ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM
lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp
/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G
A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G
A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj
dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy
MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl
cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js
L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL
BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni
acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0
o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K
zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8
PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y
Johw1+qRzT65ysCQblrGXnRl11z+o+I=
-----END CERTIFICATE-----
# https://www.amazontrust.com/repository/
Subject: C = US, O = Amazon, CN = Amazon Root CA 1
Not Before: May 26 00:00:00 2015 GMT
Not After : Jan 17 00:00:00 2038 GMT
-----BEGIN CERTIFICATE-----
MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF
ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL
MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj
ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM
9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw
IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6
VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L
93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm
jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA
A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI
U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs
N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv
o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU
5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy
rqXRfboQnoZsG4q5WTP468SQvvG5
-----END CERTIFICATE-----
Subject: C = US, O = Amazon, CN = Amazon Root CA 2
Not Before: May 26 00:00:00 2015 GMT
Not After : May 26 00:00:00 2040 GMT
-----BEGIN CERTIFICATE-----
MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF
ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL
MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK
gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ
W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg
1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K
8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r
2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me
z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR
8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj
mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz
7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6
+XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI
0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB
Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm
UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2
LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY
+gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS
k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl
7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm
btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl
urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+
fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63
n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE
76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H
9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT
4PsJYGw=
-----END CERTIFICATE-----
Not Before: May 26 00:00:00 2015 GMT
Not After : May 26 00:00:00 2040 GMT
Subject: C = US, O = Amazon, CN = Amazon Root CA 3
-----BEGIN CERTIFICATE-----
MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5
MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg
Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl
ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j
QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr
ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr
BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM
YyRIHN8wfdVoOw==
-----END CERTIFICATE-----
Not Before: May 26 00:00:00 2015 GMT
Not After : May 26 00:00:00 2040 GMT
Subject: C = US, O = Amazon, CN = Amazon Root CA 4
-----BEGIN CERTIFICATE-----
MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5
MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg
Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi
9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk
M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB
/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB
MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw
CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW
1KyLa2tJElMzrdfkviT8tQp21KW8EA==
-----END CERTIFICATE-----
Not Before: Nov 10 00:00:00 2006 GMT
Not After : Nov 10 00:00:00 2031 GMT
Subject: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----
Not Before: Nov 13 00:00:00 2012 GMT
Not After : Jan 19 03:14:07 2038 GMT
Subject: OU = GlobalSign ECC Root CA - R4, O = GlobalSign, CN = GlobalSign
-----BEGIN CERTIFICATE-----
MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk
MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH
bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD
QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ
FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw
DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F
uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX
kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs
ewv4n4Q=
-----END CERTIFICATE-----
Not Before: Nov 1 00:00:42 2018 GMT
Not After : Nov 1 00:00:42 2042 GMT
Subject: C = US, O = Google Trust Services LLC, CN = GTS LTSR
-----BEGIN CERTIFICATE-----
MIIBxTCCAWugAwIBAgINAfD3nVndblD3QnNxUDAKBggqhkjOPQQDAjBEMQswCQYD
VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzERMA8G
A1UEAxMIR1RTIExUU1IwHhcNMTgxMTAxMDAwMDQyWhcNNDIxMTAxMDAwMDQyWjBE
MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM
QzERMA8GA1UEAxMIR1RTIExUU1IwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATN
8YyO2u+yCQoZdwAkUNv5c3dokfULfrA6QJgFV2XMuENtQZIG5HUOS6jFn8f0ySlV
eORCxqFyjDJyRn86d+Iko0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUw
AwEB/zAdBgNVHQ4EFgQUPv7/zFLrvzQ+PfNA0OQlsV+4u1IwCgYIKoZIzj0EAwID
SAAwRQIhAPKuf/VtBHqGw3TUwUIq7TfaExp3bH7bjCBmVXJupT9FAiBr0SmCtsuk
miGgpajjf/gFigGM34F9021bCWs1MbL0SA==
-----END CERTIFICATE-----
+1
View File
@@ -0,0 +1 @@
../../test/data/ca.pem
+18
View File
@@ -0,0 +1,18 @@
PROG ?= example
MBEDTLS_DIR ?=
ifeq "$(MBEDTLS_DIR)" ""
else
CFLAGS += -DMG_ENABLE_MBEDTLS=1 -I$(MBEDTLS_DIR)/include -I/usr/include
CFLAGS += -L$(MBEDTLS_DIR)/lib -lmbedtls -lmbedcrypto -lmbedx509
endif
all: $(PROG)
$(DEBUGGER) ./$(PROG) $(ARGS)
$(PROG): main.c
$(CC) ../../mongoose.c -I../.. -W -Wall $(CFLAGS) -o $(PROG) main.c
clean:
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb
+1
View File
@@ -0,0 +1 @@
../../test/data/ca.pem
+88
View File
@@ -0,0 +1,88 @@
// Copyright (c) 2020 Cesanta Software Limited
// All rights reserved
//
// Example MQTT client. It performs the following steps:
// 1. Connects to the MQTT server specified by `s_url` variable
// 2. When connected, subscribes to the topic `s_topic`
// 3. Publishes message `hello` to the `s_topic`
// 4. Receives that message back from the subscribed topic and exits
//
// To enable SSL/TLS for this client, build it like this:
// make MBEDTLS_DIR=/path/to/your/mbedtls/installation
#include "mongoose.h"
static const char *s_url = "ws://broker.hivemq.com:8000/mqtt";
static const char *s_topic = "mg/test";
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
if (ev == MG_EV_ERROR) {
// On error, log error message
LOG(LL_ERROR, ("%p %s", c->fd, (char *) ev_data));
} else if (ev == MG_EV_CONNECT) {
// If target URL is SSL/TLS, command client connection to use TLS
if (mg_url_is_ssl(s_url)) {
struct mg_tls_opts opts = {.ca = "ca.pem"};
mg_tls_init(c, &opts);
}
} else if (ev == MG_EV_WS_OPEN) {
// WS connection established. Perform MQTT login
LOG(LL_INFO, ("Connected to WS. Logging in to MQTT..."));
struct mg_mqtt_opts opts = {.qos = 1,
.will_topic = mg_str(s_topic),
.will_message = mg_str("goodbye")};
size_t len = c->send.len;
mg_mqtt_login(c, s_url, &opts);
mg_ws_wrap(c, c->send.len - len, WEBSOCKET_OP_BINARY);
} else if (ev == MG_EV_WS_MSG) {
struct mg_mqtt_message mm;
struct mg_ws_message *wm = (struct mg_ws_message *) ev_data;
LOG(LL_INFO, ("GOT %d bytes WS msg", (int) wm->data.len));
while ((mg_mqtt_parse((uint8_t *) wm->data.ptr, wm->data.len, &mm)) == 0) {
switch (mm.cmd) {
case MQTT_CMD_CONNACK:
mg_call(c, MG_EV_MQTT_OPEN, &mm.ack);
if (mm.ack == 0) {
struct mg_str topic = mg_str(s_topic), data = mg_str("hello");
size_t len = c->send.len;
LOG(LL_INFO, ("CONNECTED to %s", s_url));
mg_mqtt_sub(c, &topic, 1);
mg_ws_wrap(c, len, WEBSOCKET_OP_BINARY);
LOG(LL_INFO, ("SUBSCRIBED to %.*s", (int) topic.len, topic.ptr));
mg_mqtt_pub(c, &topic, &data, 1, false);
LOG(LL_INFO, ("PUBSLISHED %.*s -> %.*s", (int) data.len, data.ptr,
(int) topic.len, topic.ptr));
len = mg_ws_wrap(c, c->send.len - len, WEBSOCKET_OP_BINARY);
} else {
LOG(LL_ERROR, ("%lu MQTT auth failed, code %d", c->id, mm.ack));
c->is_closing = 1;
}
break;
case MQTT_CMD_PUBLISH: {
LOG(LL_DEBUG, ("%lu [%.*s] -> [%.*s]", c->id, (int) mm.topic.len,
mm.topic.ptr, (int) mm.data.len, mm.data.ptr));
LOG(LL_INFO, ("RECEIVED %.*s <- %.*s", (int) mm.data.len, mm.data.ptr,
(int) mm.topic.len, mm.topic.ptr));
c->is_closing = 1;
break;
}
}
wm->data.ptr += mm.dgram.len;
wm->data.len -= mm.dgram.len;
}
}
if (ev == MG_EV_ERROR || ev == MG_EV_CLOSE) {
*(bool *) fn_data = true; // Signal that we're done
}
}
int main(void) {
struct mg_mgr mgr; // Event manager
bool done = false; // Event handler flips it to true when done
mg_mgr_init(&mgr); // Initialise event manager
mg_ws_connect(&mgr, s_url, fn, &done, NULL); // Create client connection
while (done == false) mg_mgr_poll(&mgr, 1000); // Event loop
mg_mgr_free(&mgr); // Finished, cleanup
return 0;
}
+1 -1
View File
@@ -1,7 +1,7 @@
PROG ?= example PROG ?= example
all: $(PROG) all: $(PROG)
$(DEBUGGER) ./$(PROG) $(ARGS) $(RUN) ./$(PROG) $(ARGS)
$(PROG): main.c $(PROG): main.c
$(CC) ../../mongoose.c -I../.. -W -Wall -DMG_ENABLE_LINES=1 $(CFLAGS) -o $(PROG) main.c $(CC) ../../mongoose.c -I../.. -W -Wall -DMG_ENABLE_LINES=1 $(CFLAGS) -o $(PROG) main.c
+20 -6
View File
@@ -27,17 +27,24 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
LOG(LL_DEBUG, ("cmd %d qos %d", mm->cmd, mm->qos)); LOG(LL_DEBUG, ("cmd %d qos %d", mm->cmd, mm->qos));
switch (mm->cmd) { switch (mm->cmd) {
case MQTT_CMD_CONNECT: { case MQTT_CMD_CONNECT: {
// Client connects. Return success, do not check user/password // Client connects
uint8_t response[] = {0, 0}; if (mm->dgram.len < 9) {
mg_mqtt_send_header(c, MQTT_CMD_CONNACK, 0, sizeof(response)); mg_error(c, "Malformed MQTT frame");
mg_send(c, response, sizeof(response)); } else if (mm->dgram.ptr[8] != 4) {
mg_error(c, "Unsupported MQTT version %d", mm->dgram.ptr[8]);
} else {
uint8_t response[] = {0, 0};
mg_mqtt_send_header(c, MQTT_CMD_CONNACK, 0, sizeof(response));
mg_send(c, response, sizeof(response));
}
break; break;
} }
case MQTT_CMD_SUBSCRIBE: { case MQTT_CMD_SUBSCRIBE: {
// Client subscribes // Client subscribes
int pos = 4; // Initial topic offset, where ID ends size_t pos = 4; // Initial topic offset, where ID ends
uint8_t qos; uint8_t qos, resp[256];
struct mg_str topic; struct mg_str topic;
int num_topics = 0;
while ((pos = mg_mqtt_next_sub(mm, &topic, &qos, pos)) > 0) { while ((pos = mg_mqtt_next_sub(mm, &topic, &qos, pos)) > 0) {
struct sub *sub = calloc(1, sizeof(*sub)); struct sub *sub = calloc(1, sizeof(*sub));
sub->c = c; sub->c = c;
@@ -46,7 +53,12 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
LIST_ADD_HEAD(struct sub, &s_subs, sub); LIST_ADD_HEAD(struct sub, &s_subs, sub);
LOG(LL_INFO, LOG(LL_INFO,
("SUB %p [%.*s]", c->fd, (int) sub->topic.len, sub->topic.ptr)); ("SUB %p [%.*s]", c->fd, (int) sub->topic.len, sub->topic.ptr));
resp[num_topics++] = qos;
} }
mg_mqtt_send_header(c, MQTT_CMD_SUBACK, 0, num_topics + 2);
uint16_t id = mg_htons(mm->id);
mg_send(c, &id, 2);
mg_send(c, resp, num_topics);
break; break;
} }
case MQTT_CMD_PUBLISH: { case MQTT_CMD_PUBLISH: {
@@ -60,6 +72,8 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
break; break;
} }
} }
} else if (ev == MG_EV_ACCEPT) {
// c->is_hexdumping = 1;
} else if (ev == MG_EV_CLOSE) { } else if (ev == MG_EV_CLOSE) {
// Client disconnects. Remove from the subscription list // Client disconnects. Remove from the subscription list
for (struct sub *next, *sub = s_subs; sub != NULL; sub = next) { for (struct sub *next, *sub = s_subs; sub != NULL; sub = next) {
+6 -7
View File
@@ -1,18 +1,17 @@
PROG ?= example PROG ?= example
CFLAGS += -DMG_ENABLE_SOCKETPAIR=1
CDIR ?= $(realpath $(CURDIR))
ROOT ?= $(realpath $(CURDIR)/../..) ROOT ?= $(realpath $(CURDIR)/../..)
VC2017 = docker run --rm -e WINEDEBUG=-all -v $(ROOT):$(ROOT) -w $(CDIR) docker.io/mdashnet/vc2017 CWD ?= $(realpath $(CURDIR))
DOCKER ?= docker run --rm -it -e Tmp=. -e WINEDEBUG=-all -v $(ROOT):$(ROOT) -w $(CWD)
all: $(PROG) all: $(PROG)
$(DEBUGGER) ./$(PROG) $(RUN) ./$(PROG)
$(PROG): $(PROG):
$(CC) ../../mongoose.c -I../.. -pthread $(CFLAGS) -o $(PROG) main.c $(CC) ../../mongoose.c -I../.. -pthread $(CFLAGS) -o $(PROG) main.c
vc2017: $(PROG).exe:
$(VC2017) wine64 cl ../../mongoose.c main.c -I../.. $(CFLAGS) ws2_32.lib /Fe$@.exe $(DOCKER) mdashnet/vc98 wine cl ../../mongoose.c main.c -I../.. /MD ws2_32.lib /Fe$@
$(VC2017) wine64 $@.exe $(DOCKER) mdashnet/vc98 wine $@
clean: clean:
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb log.txt rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb log.txt
+27 -52
View File
@@ -6,8 +6,6 @@
// some time to simulate long processing time, produces an output and // some time to simulate long processing time, produces an output and
// hands over that output to the request handler function. // hands over that output to the request handler function.
// //
// IMPORTANT: this program must be compiled with -DMG_ENABLE_SOCKETPAIR=1
//
// The following procedure is used to benchmark the multi-threaded codepath // The following procedure is used to benchmark the multi-threaded codepath
// against the single-threaded codepath on MacOS: // against the single-threaded codepath on MacOS:
// $ make clean all CFLAGS="-DSLEEP_TIME=0 -DMG_ENABLE_SOCKETPAIR=1" // $ make clean all CFLAGS="-DSLEEP_TIME=0 -DMG_ENABLE_SOCKETPAIR=1"
@@ -21,16 +19,6 @@
#include "mongoose.h" #include "mongoose.h"
// thread_function() sends this structure back to the request handler
struct response {
char *data;
int len;
};
#ifndef SLEEP_TIME
#define SLEEP_TIME 3 // Seconds to sleep to simulate calculation
#endif
static void start_thread(void (*f)(void *), void *p) { static void start_thread(void (*f)(void *), void *p) {
#ifdef _WIN32 #ifdef _WIN32
_beginthread((void(__cdecl *)(void *)) f, 0, p); _beginthread((void(__cdecl *)(void *)) f, 0, p);
@@ -47,60 +35,47 @@ static void start_thread(void (*f)(void *), void *p) {
} }
static void thread_function(void *param) { static void thread_function(void *param) {
int sock = (long) param; // Grab our blocking socket struct mg_connection *c = param; // Pipe connection
struct response r = {strdup("hello\n"), 6}; // Create response mg_usleep(2 * 1000000); // Simulate long execution
mg_usleep(SLEEP_TIME * 1000000); // Simulate long execution mg_mgr_wakeup(c); // Wakeup event manager
LOG(LL_INFO, ("got sock %d", sock)); // For debugging
send(sock, (void *) &r, sizeof(r), 0); // Send to request handler
closesocket(sock); // Done, close socket, end thread
} }
// HTTP request callback // HTTP request callback
static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
if (ev == MG_EV_HTTP_MSG) { if (ev == MG_EV_HTTP_MSG) {
// Incoming request. Create socket pair.
// Pass blocking socket to the thread, and keep the non-blocking socket.
struct mg_http_message *hm = (struct mg_http_message *) ev_data; struct mg_http_message *hm = (struct mg_http_message *) ev_data;
if (mg_http_match_uri(hm, "/fast")) { if (mg_http_match_uri(hm, "/fast")) {
// The /fast URI is for performance impact of the multithreading codepath // Single-threaded code path, for performance comparison
mg_printf(c, // The /fast URI responds immediately
"HTTP/1.1 200 OK\r\n" // Reply success mg_http_reply(c, 200, "Host: foo.com\r\n", "hi\n");
"Host: foo\r\n" // Mandatory header
"Content-Length: 3\r\n\r\n" // Set to allow keep-alive
"hi\n");
} else { } else {
int blocking = -1, non_blocking = -1; // Multithreading code path
mg_socketpair(&blocking, &non_blocking); // Create connected pair c->label[0] = 'W'; // Mark us as waiting for data
start_thread(thread_function, fn_data); // Start handling thread
// Pass blocking socket to the thread_function.
start_thread(thread_function, (void *) (long) blocking);
// Non-blocking is ours. Store it in the fn_data, in
// order to use it in the subsequent invocations
c->fn_data = (void *) (long) non_blocking;
} }
} else if (ev == MG_EV_POLL && c->fn_data != NULL) { }
// On each poll iteration, try to receive response data }
int sock = (int) (long) c->fn_data;
struct response response = {NULL, 0}; // Pipe event handler
if (recv(sock, (void *) &response, sizeof(response), 0) == static void pcb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
sizeof(response)) { if (ev == MG_EV_READ) {
// Yeah! Got the response. struct mg_connection *t;
mg_printf(c, "HTTP/1.0 200 OK\r\nContent-Length: %d\r\n\r\n%.*s", for (t = c->mgr->conns; t != NULL; t = t->next) {
response.len, response.len, response.data); if (t->label[0] != 'W') continue; // Ignore un-marked connections
free(response.data); // We can free produced data now mg_http_reply(t, 200, "Host: foo.com\r\n", "hi\n"); // Respond!
closesocket(sock); // And close our end of the socket pair t->label[0] = 0; // Clear mark
c->fn_data = NULL;
} }
} }
} }
int main(void) { int main(void) {
struct mg_mgr mgr; struct mg_mgr mgr;
struct mg_connection *pipe; // Used to wake up event manager
mg_mgr_init(&mgr); mg_mgr_init(&mgr);
mg_http_listen(&mgr, "http://localhost:8000", cb, NULL); mg_log_set("3");
for (;;) mg_mgr_poll(&mgr, 50); pipe = mg_mkpipe(&mgr, pcb, NULL); // Create pipe
mg_mgr_free(&mgr); mg_http_listen(&mgr, "http://localhost:8000", fn, pipe); // Create listener
for (;;) mg_mgr_poll(&mgr, 1000); // Event loop
mg_mgr_free(&mgr); // Cleanup
return 0; return 0;
} }
@@ -0,0 +1,8 @@
NAME ?= $(notdir $(CURDIR))
build:
git clone --depth 1 https://github.com/mongoose-examples/$(NAME)
make -C $(NAME) build
clean:
rm -rf $(NAME)
+3 -3
View File
@@ -53,7 +53,7 @@ static void handshake(struct mg_connection *c) {
// TODO(lsm): support other auth methods // TODO(lsm): support other auth methods
if (r->buf[i] == HANDSHAKE_NOAUTH) reply[1] = r->buf[i]; if (r->buf[i] == HANDSHAKE_NOAUTH) reply[1] = r->buf[i];
} }
mg_iobuf_delete(r, 2 + r->buf[1]); mg_iobuf_del(r, 0, 2 + r->buf[1]);
mg_send(c, reply, sizeof(reply)); mg_send(c, reply, sizeof(reply));
c->label[0] = STATE_REQUEST; c->label[0] = STATE_REQUEST;
} }
@@ -73,7 +73,7 @@ static void exchange(struct mg_connection *c) {
struct mg_connection *c2 = (struct mg_connection *) c->fn_data; struct mg_connection *c2 = (struct mg_connection *) c->fn_data;
if (c2 != NULL) { if (c2 != NULL) {
mg_send(c2, c->recv.buf, c->recv.len); mg_send(c2, c->recv.buf, c->recv.len);
mg_iobuf_delete(&c->recv, c->recv.len); mg_iobuf_del(&c->recv, 0, c->recv.len);
} else { } else {
c->is_draining = 1; c->is_draining = 1;
} }
@@ -145,7 +145,7 @@ static void request(struct mg_connection *c) {
mg_send(c, buf, sizeof(buf)); mg_send(c, buf, sizeof(buf));
} }
mg_send(c, r->buf + 3, addr_len + 1 + 2); mg_send(c, r->buf + 3, addr_len + 1 + 2);
mg_iobuf_delete(r, 6 + addr_len); // Remove request from the input stream mg_iobuf_del(r, 0, 6 + addr_len); // Remove request from the input stream
c->label[0] = STATE_ESTABLISHED; // Mark ourselves as connected c->label[0] = STATE_ESTABLISHED; // Mark ourselves as connected
} }
+6 -3
View File
@@ -2,11 +2,11 @@
PROG = firmware PROG = firmware
ARCH = stm32f7 ARCH = stm32f7
PROJECT_ROOT_PATH = $(realpath $(CURDIR)/../..) PROJECT_ROOT_PATH = $(realpath $(CURDIR)/../..)
DOCKER ?= docker run -it --rm -v $(PROJECT_ROOT_PATH):$(PROJECT_ROOT_PATH) -w $(CURDIR) mdashnet/armgcc DOCKER ?= docker run --rm -v $(PROJECT_ROOT_PATH):$(PROJECT_ROOT_PATH) -w $(CURDIR) mdashnet/armgcc
FREERTOS_KERNEL_PATH ?= $(PROJECT_ROOT_PATH)/test/freertos-kernel FREERTOS_KERNEL_PATH ?= $(PROJECT_ROOT_PATH)/test/freertos-kernel
FREERTOS_PLUS_TCP_PATH ?= $(PROJECT_ROOT_PATH)/test/freertos-tcp FREERTOS_PLUS_TCP_PATH ?= $(PROJECT_ROOT_PATH)/test/freertos-tcp
MONGOOSE_FLAGS = -DMG_ARCH=MG_ARCH_FREERTOS_TCP -DMG_ENABLE_FS=1 MONGOOSE_FLAGS = -DMG_ARCH=MG_ARCH_FREERTOS_TCP
MCU_FLAGS = -mcpu=cortex-m7 -mthumb -mfloat-abi=softfp -mfpu=vfpv4 MCU_FLAGS = -mcpu=cortex-m7 -mthumb -mfloat-abi=softfp -mfpu=vfpv4
#-mcpu=cortex-m7 -mthumb -mfpu=fpv5-sp-d16 -mfloat-abi=hard #-mcpu=cortex-m7 -mthumb -mfpu=fpv5-sp-d16 -mfloat-abi=hard
@@ -52,7 +52,10 @@ SOURCES += $(FREERTOS_PLUS_TCP_PATH)/portable/NetworkInterface/STM32Fxx/stm32fxx
OBJECTS = obj/boot.o $(SOURCES:%.c=obj/%.o) OBJECTS = obj/boot.o $(SOURCES:%.c=obj/%.o)
all: $(PROG).hex example:
true
build: $(PROG).hex
$(PROG).bin: $(PROG).elf $(PROG).bin: $(PROG).elf
$(DOCKER) arm-none-eabi-objcopy -O binary $< $@ $(DOCKER) arm-none-eabi-objcopy -O binary $< $@
+22 -26
View File
@@ -10,12 +10,7 @@ static const char *s_listening_address = "http://0.0.0.0:80";
// Event handler for the listening connection. // Event handler for the listening connection.
static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
if (ev == MG_EV_HTTP_MSG) { if (ev == MG_EV_HTTP_MSG) {
#if MG_ENABLE_FS
struct mg_http_serve_opts opts = {.root_dir = "/"};
mg_http_serve_dir(c, ev_data, &opts);
#else
mg_http_reply(c, 200, "", "hello, %s!\n", "world"); mg_http_reply(c, 200, "", "hello, %s!\n", "world");
#endif
} }
(void) fn_data; (void) fn_data;
(void) ev_data; (void) ev_data;
@@ -99,32 +94,33 @@ uint32_t HAL_GetTick(void) {
#include "stm32f7xx_hal_conf.h" #include "stm32f7xx_hal_conf.h"
#include "stm32fxx_hal_eth.h" #include "stm32fxx_hal_eth.h"
void HAL_ETH_MspInit( ETH_HandleTypeDef* heth ) { void HAL_ETH_MspInit(ETH_HandleTypeDef *heth) {
GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;
if (heth->Instance == ETH) { if (heth->Instance == ETH) {
__HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE();
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL; GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Alternate = GPIO_AF11_ETH; GPIO_InitStructure.Alternate = GPIO_AF11_ETH;
GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7; GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7;
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5; GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5;
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure); HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.Pin = GPIO_PIN_2 | GPIO_PIN_11 | GPIO_PIN_13 | GPIO_PIN_14; GPIO_InitStructure.Pin =
HAL_GPIO_Init(GPIOG, &GPIO_InitStructure); GPIO_PIN_2 | GPIO_PIN_11 | GPIO_PIN_13 | GPIO_PIN_14;
HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
HAL_NVIC_SetPriority(ETH_IRQn, 0x7, 0); HAL_NVIC_SetPriority(ETH_IRQn, 0x7, 0);
HAL_NVIC_EnableIRQ(ETH_IRQn); HAL_NVIC_EnableIRQ(ETH_IRQn);
__HAL_RCC_ETH_CLK_ENABLE(); __HAL_RCC_ETH_CLK_ENABLE();
HAL_NVIC_SetPriorityGrouping( NVIC_PRIORITYGROUP_4 ); HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
} }
} }
int vLoggingPrintf(const char *fmt, ...) { int vLoggingPrintf(const char *fmt, ...) {
@@ -1810,7 +1810,7 @@ __STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */
reg_value = (reg_value | reg_value = (reg_value |
((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
(PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ (PriorityGroupTmp << 8U) ); /* Insert write key and priority group */
SCB->AIRCR = reg_value; SCB->AIRCR = reg_value;
} }
+8
View File
@@ -0,0 +1,8 @@
NAME ?= $(notdir $(CURDIR))
build:
git clone --depth 1 https://github.com/mongoose-examples/$(NAME)
make -C $(NAME) build
clean:
rm -rf $(NAME)
+8
View File
@@ -0,0 +1,8 @@
NAME ?= $(notdir $(CURDIR))
build:
git clone --depth 1 https://github.com/mongoose-examples/$(NAME)
make -C $(NAME) build
clean:
rm -rf $(NAME)
+8
View File
@@ -0,0 +1,8 @@
NAME ?= $(notdir $(CURDIR))
build:
git clone --depth 1 https://github.com/mongoose-examples/$(NAME)
make -C $(NAME) build
clean:
rm -rf $(NAME)
+1 -1
View File
@@ -4,7 +4,7 @@ all: $(PROG)
$(DEBUGGER) ./$(PROG) $(ARGS) $(DEBUGGER) ./$(PROG) $(ARGS)
$(PROG): main.c $(PROG): main.c
$(CC) ../../mongoose.c -I../.. -W -Wall -DMG_ENABLE_LINES=1 -DMG_ENABLE_DIRECTORY_LISTING=1 $(CFLAGS) -o $(PROG) main.c $(CC) ../../mongoose.c -I../.. -W -Wall -DMG_ENABLE_LINES=1 $(CFLAGS) -o $(PROG) main.c
clean: clean:
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb
+5 -7
View File
@@ -19,25 +19,23 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
if (ev == MG_EV_HTTP_MSG) { if (ev == MG_EV_HTTP_MSG) {
struct mg_http_message *hm = (struct mg_http_message *) ev_data; struct mg_http_message *hm = (struct mg_http_message *) ev_data;
mg_ws_upgrade(c, hm, NULL); mg_ws_upgrade(c, hm, NULL);
c->label[0] = 'W'; // Set some unique mark on a connection
} else if (ev == MG_EV_WS_MSG) { } else if (ev == MG_EV_WS_MSG) {
// Got websocket frame. Received data is wm->data. Echo it back! // Got websocket frame. Received data is wm->data. Echo it back!
struct mg_ws_message *wm = (struct mg_ws_message *) ev_data; struct mg_ws_message *wm = (struct mg_ws_message *) ev_data;
mg_ws_send(c, wm->data.ptr, wm->data.len, WEBSOCKET_OP_TEXT); mg_ws_send(c, wm->data.ptr, wm->data.len, WEBSOCKET_OP_TEXT);
mg_iobuf_delete(&c->recv, c->recv.len); mg_iobuf_del(&c->recv, 0, c->recv.len);
} }
(void) fn_data; (void) fn_data;
} }
static void timer_fn(void *arg) { static void timer_fn(void *arg) {
struct mg_mgr *mgr = (struct mg_mgr *) arg; struct mg_mgr *mgr = (struct mg_mgr *) arg;
struct mg_connection *c;
// Broadcast "hi" message to all connected websocket clients. // Broadcast "hi" message to all connected websocket clients.
// Traverse over all connections // Traverse over all connections
for (c = mgr->conns; c != NULL; c = c->next) { for (struct mg_connection *c = mgr->conns; c != NULL; c = c->next) {
// Send only to accepted websocket connections // Send only to marked connections
if (c->is_accepted && c->is_websocket) { if (c->label[0] == 'W') mg_ws_send(c, "hi", 2, WEBSOCKET_OP_TEXT);
mg_ws_send(c, "hi", 2, WEBSOCKET_OP_TEXT);
}
} }
} }
-507
View File
@@ -1,507 +0,0 @@
Subject: O=Digital Signature Trust Co., CN=DST Root CA X3
Not Before: Sep 30 21:12:19 2000 GMT
Not After : Sep 30 14:01:15 2021 GMT
-----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
-----END CERTIFICATE-----
Subject: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root
Not Before: May 12 18:46:00 2000 GMT
Not After : May 12 23:59:00 2025 GMT
-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
-----END CERTIFICATE-----
Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
Not Before: May 21 04:00:00 2002 GMT
Not After : May 21 04:00:00 2022 GMT
-----BEGIN CERTIFICATE-----
MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
-----END CERTIFICATE-----
Subject: C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec Class 3 ECC 256 bit SSL CA - G2
Not Before: May 12 00:00:00 2015 GMT
Not After : May 11 23:59:59 2025 GMT
-----BEGIN CERTIFICATE-----
MIIEajCCA1KgAwIBAgIQP5KHvp0dpKN6nfYoLndaxDANBgkqhkiG9w0BAQsFADCB
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
aG9yaXR5IC0gRzUwHhcNMTUwNTEyMDAwMDAwWhcNMjUwNTExMjM1OTU5WjCBgDEL
MAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYD
VQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMTEwLwYDVQQDEyhTeW1hbnRlYyBD
bGFzcyAzIEVDQyAyNTYgYml0IFNTTCBDQSAtIEcyMFkwEwYHKoZIzj0CAQYIKoZI
zj0DAQcDQgAEDxukkdfnrOfRTk63ZFvhj39uBNOrONtEt0Bcbb2WljffeYmGZ/ex
Hwie/WM7RoyfvVPoFdyXPiuBRq2Gfw4BOaOCAV0wggFZMC4GCCsGAQUFBwEBBCIw
IDAeBggrBgEFBQcwAYYSaHR0cDovL3Muc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYB
Af8CAQAwZQYDVR0gBF4wXDBaBgpghkgBhvhFAQc2MEwwIwYIKwYBBQUHAgEWF2h0
dHBzOi8vZC5zeW1jYi5jb20vY3BzMCUGCCsGAQUFBwICMBkaF2h0dHBzOi8vZC5z
eW1jYi5jb20vcnBhMC8GA1UdHwQoMCYwJKAioCCGHmh0dHA6Ly9zLnN5bWNiLmNv
bS9wY2EzLWc1LmNybDAOBgNVHQ8BAf8EBAMCAQYwKwYDVR0RBCQwIqQgMB4xHDAa
BgNVBAMTE1NZTUMtRUNDLUNBLXAyNTYtMjIwHQYDVR0OBBYEFCXwiuFLetkBlQrt
xlPxjHgf2fP4MB8GA1UdIwQYMBaAFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG
SIb3DQEBCwUAA4IBAQAMMGUXBaWTdaLxsTGtcB/naqjIQrLvoV9NG+7MoHpGd/69
dZ/h2zOy7sGFUHoG/0HGRA9rxT/5w5GkEVIVkxtWyIWWq6rs4CTZt8Bej/KHYRbo
jtEDUkCTZSTLiCvguPyvinXgxy+LHT+PmdtEfXsvcdbeBSWUYpOsDYvD2hNtz9dw
Od5nBosMApmdxt+z7LQyZu8wMnfI1U6IMO+RWowxZ8uy0oswdFYd32l9xe+aAE/k
y9alLu/M9pvxiUKufqHJRgDBKA6uDjHLMPX+/nxXaNCPX3SI4KVZ1stHQ/U5oNlM
dHN9umAvlU313g0IgJrjsQ2nIdf9dsdP+6lrmP7s
-----END CERTIFICATE-----
Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
Not Before: Nov 8 00:00:00 2006 GMT
Not After : Jul 16 23:59:59 2036 GMT
-----BEGIN CERTIFICATE-----
MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL
MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln
biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1
nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex
t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz
SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG
BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+
rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/
NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH
BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv
MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE
p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y
5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK
WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ
4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N
hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
-----END CERTIFICATE-----
Subject: C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification Authority
Not Before: Jun 29 17:06:20 2004 GMT
Not After : Jun 29 17:06:20 2034 GMT
-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
ReYNnyicsbkqWletNw+vHX/bvZ8=
-----END CERTIFICATE-----
# Note: Amazon ATS endpoint uses this (2018/12/18)
Subject: C=US, O=Starfield Technologies, Inc., OU=Starfield Class 2 Certification Authority
Not Before: Jun 29 17:39:16 2004 GMT
Not After : Jun 29 17:39:16 2034 GMT
-----BEGIN CERTIFICATE-----
MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl
MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp
U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw
NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE
ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp
ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3
DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf
8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN
+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0
X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa
K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA
1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G
A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR
zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0
YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD
bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w
DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3
L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D
eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp
VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY
WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=
-----END CERTIFICATE-----
Not Before: Sep 1 00:00:00 2009 GMT
Not After : Dec 31 23:59:59 2037 GMT
Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Root Certificate Authority - G2
-----BEGIN CERTIFICATE-----
MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw
MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp
Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg
nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1
HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N
Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN
dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0
HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G
CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU
sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3
4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg
8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
-----END CERTIFICATE-----
Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Services Root Certificate Authority - G2
Not Before: Sep 1 00:00:00 2009 GMT
Not After : Dec 31 23:59:59 2037 GMT
-----BEGIN CERTIFICATE-----
MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs
ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5
MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD
VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy
ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy
dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p
OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2
8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K
Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe
hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk
6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q
AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI
bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB
ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z
qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn
0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN
sSi6
-----END CERTIFICATE-----
Subject: OU=GlobalSign Root CA - R2, O=GlobalSign, CN=GlobalSign
Not Before: Dec 15 08:00:00 2006 GMT
Not After : Dec 15 08:00:00 2021 GMT
-----BEGIN CERTIFICATE-----
MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
-----END CERTIFICATE-----
Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA
Not Before: Nov 10 00:00:00 2006 GMT
Not After : Nov 10 00:00:00 2031 GMT
-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
+OkuE6N36B9K
-----END CERTIFICATE-----
Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA
Not Before: Nov 10 00:00:00 2006 GMT
Not After : Nov 10 00:00:00 2031 GMT
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----
# *.azure-devices.de use this root.
Subject: C = DE, O = D-Trust GmbH, CN = D-TRUST Root Class 3 CA 2 2009
Not Before: Nov 5 08:35:58 2009 GMT
Not After : Nov 5 08:35:58 2029 GMT
-----BEGIN CERTIFICATE-----
MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF
MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD
bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha
ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM
HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03
UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42
tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R
ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM
lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp
/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G
A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G
A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj
dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy
MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl
cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js
L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL
BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni
acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0
o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K
zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8
PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y
Johw1+qRzT65ysCQblrGXnRl11z+o+I=
-----END CERTIFICATE-----
# https://www.amazontrust.com/repository/
Subject: C = US, O = Amazon, CN = Amazon Root CA 1
Not Before: May 26 00:00:00 2015 GMT
Not After : Jan 17 00:00:00 2038 GMT
-----BEGIN CERTIFICATE-----
MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF
ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL
MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj
ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM
9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw
IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6
VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L
93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm
jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA
A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI
U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs
N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv
o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU
5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy
rqXRfboQnoZsG4q5WTP468SQvvG5
-----END CERTIFICATE-----
Subject: C = US, O = Amazon, CN = Amazon Root CA 2
Not Before: May 26 00:00:00 2015 GMT
Not After : May 26 00:00:00 2040 GMT
-----BEGIN CERTIFICATE-----
MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF
ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL
MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK
gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ
W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg
1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K
8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r
2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me
z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR
8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj
mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz
7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6
+XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI
0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB
Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm
UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2
LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY
+gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS
k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl
7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm
btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl
urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+
fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63
n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE
76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H
9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT
4PsJYGw=
-----END CERTIFICATE-----
Not Before: May 26 00:00:00 2015 GMT
Not After : May 26 00:00:00 2040 GMT
Subject: C = US, O = Amazon, CN = Amazon Root CA 3
-----BEGIN CERTIFICATE-----
MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5
MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg
Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl
ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j
QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr
ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr
BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM
YyRIHN8wfdVoOw==
-----END CERTIFICATE-----
Not Before: May 26 00:00:00 2015 GMT
Not After : May 26 00:00:00 2040 GMT
Subject: C = US, O = Amazon, CN = Amazon Root CA 4
-----BEGIN CERTIFICATE-----
MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5
MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg
Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi
9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk
M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB
/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB
MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw
CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW
1KyLa2tJElMzrdfkviT8tQp21KW8EA==
-----END CERTIFICATE-----
Not Before: Nov 10 00:00:00 2006 GMT
Not After : Nov 10 00:00:00 2031 GMT
Subject: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----
Not Before: Nov 13 00:00:00 2012 GMT
Not After : Jan 19 03:14:07 2038 GMT
Subject: OU = GlobalSign ECC Root CA - R4, O = GlobalSign, CN = GlobalSign
-----BEGIN CERTIFICATE-----
MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk
MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH
bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD
QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ
FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw
DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F
uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX
kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs
ewv4n4Q=
-----END CERTIFICATE-----
Not Before: Nov 1 00:00:42 2018 GMT
Not After : Nov 1 00:00:42 2042 GMT
Subject: C = US, O = Google Trust Services LLC, CN = GTS LTSR
-----BEGIN CERTIFICATE-----
MIIBxTCCAWugAwIBAgINAfD3nVndblD3QnNxUDAKBggqhkjOPQQDAjBEMQswCQYD
VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzERMA8G
A1UEAxMIR1RTIExUU1IwHhcNMTgxMTAxMDAwMDQyWhcNNDIxMTAxMDAwMDQyWjBE
MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM
QzERMA8GA1UEAxMIR1RTIExUU1IwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATN
8YyO2u+yCQoZdwAkUNv5c3dokfULfrA6QJgFV2XMuENtQZIG5HUOS6jFn8f0ySlV
eORCxqFyjDJyRn86d+Iko0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUw
AwEB/zAdBgNVHQ4EFgQUPv7/zFLrvzQ+PfNA0OQlsV+4u1IwCgYIKoZIzj0EAwID
SAAwRQIhAPKuf/VtBHqGw3TUwUIq7TfaExp3bH7bjCBmVXJupT9FAiBr0SmCtsuk
miGgpajjf/gFigGM34F9021bCWs1MbL0SA==
-----END CERTIFICATE-----
+1
View File
@@ -0,0 +1 @@
../../test/data/ca.pem
+1 -1
View File
@@ -4,7 +4,7 @@ all: $(PROG)
$(DEBUGGER) ./$(PROG) $(ARGS) $(DEBUGGER) ./$(PROG) $(ARGS)
$(PROG): main.c $(PROG): main.c
$(CC) ../../mongoose.c -I../.. -W -Wall -DMG_ENABLE_LINES=1 -DMG_ENABLE_DIRECTORY_LISTING=1 $(CFLAGS) -o $(PROG) main.c $(CC) ../../mongoose.c -I../.. -W -Wall -DMG_ENABLE_LINES=1 $(CFLAGS) -o $(PROG) main.c
clean: clean:
rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb
+1 -1
View File
@@ -34,7 +34,7 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
// Got websocket frame. Received data is wm->data. Echo it back! // Got websocket frame. Received data is wm->data. Echo it back!
struct mg_ws_message *wm = (struct mg_ws_message *) ev_data; struct mg_ws_message *wm = (struct mg_ws_message *) ev_data;
mg_ws_send(c, wm->data.ptr, wm->data.len, WEBSOCKET_OP_TEXT); mg_ws_send(c, wm->data.ptr, wm->data.len, WEBSOCKET_OP_TEXT);
mg_iobuf_delete(&c->recv, c->recv.len); mg_iobuf_del(&c->recv, 0, c->recv.len);
} }
(void) fn_data; (void) fn_data;
} }
+979 -653
View File
File diff suppressed because it is too large. Load diff
+202 -142
View File
@@ -18,13 +18,81 @@
#ifndef MONGOOSE_H #ifndef MONGOOSE_H
#define MONGOOSE_H #define MONGOOSE_H
#define MG_VERSION "7.3" #define MG_VERSION "7.4"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#ifndef MG_ENABLE_SOCKET
#define MG_ENABLE_SOCKET 1
#endif
#ifndef MG_ENABLE_MBEDTLS
#define MG_ENABLE_MBEDTLS 0
#endif
#ifndef MG_ENABLE_OPENSSL
#define MG_ENABLE_OPENSSL 0
#endif
#ifndef MG_ENABLE_SSI
#define MG_ENABLE_SSI 1
#endif
#ifndef MG_ENABLE_IPV6
#define MG_ENABLE_IPV6 0
#endif
#ifndef MG_ENABLE_LOG
#define MG_ENABLE_LOG 1
#endif
#ifndef MG_ENABLE_MD5
#define MG_ENABLE_MD5 0
#endif
// Set MG_ENABLE_WINSOCK=0 for Win32 builds with external IP stack (like LWIP)
#ifndef MG_ENABLE_WINSOCK
#define MG_ENABLE_WINSOCK 1
#endif
#ifndef MG_ENABLE_DIRLIST
#define MG_ENABLE_DIRLIST 0
#endif
#ifndef MG_ENABLE_CUSTOM_RANDOM
#define MG_ENABLE_CUSTOM_RANDOM 0
#endif
#ifndef MG_ENABLE_PACKED_FS
#define MG_ENABLE_PACKED_FS 0
#endif
// Granularity of the send/recv IO buffer growth
#ifndef MG_IO_SIZE
#define MG_IO_SIZE 2048
#endif
// Maximum size of the recv IO buffer
#ifndef MG_MAX_RECV_BUF_SIZE
#define MG_MAX_RECV_BUF_SIZE (3 * 1024 * 1024)
#endif
#ifndef MG_MAX_HTTP_HEADERS
#define MG_MAX_HTTP_HEADERS 40
#endif
#ifndef MG_PATH_MAX
#define MG_PATH_MAX PATH_MAX
#endif
#ifndef MG_SOCK_LISTEN_BACKLOG_SIZE
#define MG_SOCK_LISTEN_BACKLOG_SIZE 128
#endif
#define MG_ARCH_CUSTOM 0 #define MG_ARCH_CUSTOM 0
#define MG_ARCH_UNIX 1 #define MG_ARCH_UNIX 1
#define MG_ARCH_WIN32 2 #define MG_ARCH_WIN32 2
@@ -32,6 +100,7 @@ extern "C" {
#define MG_ARCH_ESP8266 4 #define MG_ARCH_ESP8266 4
#define MG_ARCH_FREERTOS_TCP 5 #define MG_ARCH_FREERTOS_TCP 5
#define MG_ARCH_FREERTOS_LWIP 6 #define MG_ARCH_FREERTOS_LWIP 6
#define MG_ARCH_AZURERTOS 7
#if !defined(MG_ARCH) #if !defined(MG_ARCH)
#if defined(__unix__) || defined(__APPLE__) #if defined(__unix__) || defined(__APPLE__)
@@ -44,6 +113,8 @@ extern "C" {
#define MG_ARCH MG_ARCH_ESP32 #define MG_ARCH MG_ARCH_ESP32
#elif defined(FREERTOS_IP_H) #elif defined(FREERTOS_IP_H)
#define MG_ARCH MG_ARCH_FREERTOS_TCP #define MG_ARCH MG_ARCH_FREERTOS_TCP
#elif defined(AZURE_RTOS_THREADX)
#define MG_ARCH MG_ARCH_AZURERTOS
#endif #endif
#if !defined(MG_ARCH) #if !defined(MG_ARCH)
@@ -71,6 +142,44 @@ extern "C" {
#if MG_ARCH == MG_ARCH_AZURERTOS
#include <stdarg.h>
#include <stdint.h>
#include <stdbool.h>
#include <time.h>
#include <stdio.h>
#include <tx_api.h>
#include <fx_api.h>
#include <tx_port.h>
#include <nx_port.h>
#include <nx_api.h>
#include <nx_bsd.h>
#ifdef __REDLIB__
#define va_copy(d,s)__builtin_va_copy(d,s)
#endif
#define PATH_MAX FX_MAXIMUM_PATH
#define MG_DIRSEP '\\'
#define socklen_t int
#define closesocket(x) soc_close(x)
#define gmtime_r(a, b) gmtime(a)
#define MG_INT64_FMT "%lld"
static __inline struct tm *localtime_r(time_t *t, struct tm *tm) {
(void) tm;
return localtime(t);
}
#undef FOPEN_MAX
#endif
#if MG_ARCH == MG_ARCH_ESP32 #if MG_ARCH == MG_ARCH_ESP32
#include <ctype.h> #include <ctype.h>
@@ -93,6 +202,8 @@ extern "C" {
#ifndef MG_PATH_MAX #ifndef MG_PATH_MAX
#define MG_PATH_MAX 128 #define MG_PATH_MAX 128
#endif #endif
#undef MG_ENABLE_DIRLIST
#define MG_ENABLE_DIRLIST 1
#endif #endif
@@ -126,12 +237,13 @@ extern "C" {
#if MG_ARCH == MG_ARCH_FREERTOS_LWIP #if MG_ARCH == MG_ARCH_FREERTOS_LWIP
#include <errno.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <string.h>
#if defined(__GNUC__) #if defined(__GNUC__)
#include <sys/stat.h>
#include <sys/time.h> #include <sys/time.h>
#else #else
typedef long suseconds_t; typedef long suseconds_t;
@@ -141,15 +253,23 @@ struct timeval {
}; };
#endif #endif
#if MG_ENABLE_FS
#include <sys/stat.h>
#endif
#include <FreeRTOS.h> #include <FreeRTOS.h>
#include <task.h> #include <task.h>
#include <lwip/sockets.h> #include <lwip/sockets.h>
#if LWIP_SOCKET != 1
// Sockets support disabled in LWIP by default
#error Set LWIP_SOCKET variable to 1 (in lwipopts.h)
#endif
#if LWIP_POSIX_SOCKETS_IO_NAMES != 0
// LWIP_POSIX_SOCKETS_IO_NAMES must be disabled in posix-compatible OS
// enviroment (freertos mimics to one) otherwise names like `read` and `write`
// conflict
#error LWIP_POSIX_SOCKETS_IO_NAMES must be set to 0 (in lwipopts.h) for FreeRTOS
#endif
#define MG_INT64_FMT "%lld" #define MG_INT64_FMT "%lld"
#define MG_DIRSEP '/' #define MG_DIRSEP '/'
@@ -179,11 +299,8 @@ static inline void *mg_calloc(int cnt, size_t size) {
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h>
#if MG_ENABLE_FS
#include <sys/stat.h> #include <sys/stat.h>
#endif #include <time.h>
#include <FreeRTOS.h> #include <FreeRTOS.h>
#include <FreeRTOS_IP.h> #include <FreeRTOS_IP.h>
@@ -219,6 +336,7 @@ static inline void *mg_calloc(int cnt, size_t size) {
FreeRTOS_recvfrom((a), (b), (c), (d), (e), (f)) FreeRTOS_recvfrom((a), (b), (c), (d), (e), (f))
#define closesocket(x) FreeRTOS_closesocket(x) #define closesocket(x) FreeRTOS_closesocket(x)
#define gethostbyname(x) FreeRTOS_gethostbyname(x) #define gethostbyname(x) FreeRTOS_gethostbyname(x)
#define getsockname(a, b, c) (-1)
// Re-route calloc/free to the FreeRTOS's functions, don't use stdlib // Re-route calloc/free to the FreeRTOS's functions, don't use stdlib
static inline void *mg_calloc(int cnt, size_t size) { static inline void *mg_calloc(int cnt, size_t size) {
@@ -259,7 +377,7 @@ struct timeval {
#if MG_ARCH == MG_ARCH_UNIX #if MG_ARCH == MG_ARCH_UNIX
#define _DARWIN_UNLIMITED_SELECT 1 #define _DARWIN_UNLIMITED_SELECT 1 // No limit on file descriptors
#include <arpa/inet.h> #include <arpa/inet.h>
#include <ctype.h> #include <ctype.h>
@@ -287,8 +405,9 @@ struct timeval {
#include <unistd.h> #include <unistd.h>
#define MG_DIRSEP '/' #define MG_DIRSEP '/'
#define MG_ENABLE_POSIX 1
#define MG_INT64_FMT "%" PRId64 #define MG_INT64_FMT "%" PRId64
#undef MG_ENABLE_DIRLIST
#define MG_ENABLE_DIRLIST 1
#endif #endif
@@ -344,8 +463,10 @@ typedef enum { false = 0, true = 1 } bool;
#ifndef __cplusplus #ifndef __cplusplus
#define snprintf _snprintf #define snprintf _snprintf
#define vsnprintf _vsnprintf #define vsnprintf _vsnprintf
#ifndef strdup // For MSVC with _DEBUG, see #1359
#define strdup(x) _strdup(x) #define strdup(x) _strdup(x)
#endif #endif
#endif
typedef unsigned suseconds_t; typedef unsigned suseconds_t;
typedef int socklen_t; typedef int socklen_t;
@@ -359,8 +480,7 @@ typedef int socklen_t;
#ifndef EWOULDBLOCK #ifndef EWOULDBLOCK
#define EWOULDBLOCK WSAEWOULDBLOCK #define EWOULDBLOCK WSAEWOULDBLOCK
#endif #endif
#define realpath(a, b) _fullpath((b), (a), MG_PATH_MAX)
#define fopen(a, b) mg_fopen((a), (b))
#ifndef va_copy #ifndef va_copy
#ifdef __va_copy #ifdef __va_copy
#define va_copy __va_copy #define va_copy __va_copy
@@ -374,12 +494,8 @@ typedef int socklen_t;
#define MG_INT64_FMT "%I64d" #define MG_INT64_FMT "%I64d"
static __inline FILE *mg_fopen(const char *path, const char *mode) { #undef MG_ENABLE_DIRLIST
wchar_t b1[PATH_MAX], b2[10]; #define MG_ENABLE_DIRLIST 1
MultiByteToWideChar(CP_UTF8, 0, path, -1, b1, sizeof(b1) / sizeof(b1[0]));
MultiByteToWideChar(CP_UTF8, 0, mode, -1, b2, sizeof(b2) / sizeof(b2[0]));
return _wfopen(b1, b2);
}
// https://lgtm.com/rules/2154840805/ -gmtime, localtime, ctime and asctime // https://lgtm.com/rules/2154840805/ -gmtime, localtime, ctime and asctime
static __inline struct tm *gmtime_r(time_t *t, struct tm *tm) { static __inline struct tm *gmtime_r(time_t *t, struct tm *tm) {
@@ -395,76 +511,12 @@ static __inline struct tm *localtime_r(time_t *t, struct tm *tm) {
#endif #endif
#ifndef MG_ENABLE_SOCKET
#define MG_ENABLE_SOCKET 1
#endif
#ifndef MG_ENABLE_MBEDTLS
#define MG_ENABLE_MBEDTLS 0
#endif
#ifndef MG_ENABLE_OPENSSL
#define MG_ENABLE_OPENSSL 0
#endif
#ifndef MG_ENABLE_FS
#define MG_ENABLE_FS 1
#endif
#ifndef MG_ENABLE_SSI
#define MG_ENABLE_SSI 0
#endif
#ifndef MG_ENABLE_IPV6
#define MG_ENABLE_IPV6 0
#endif
#ifndef MG_ENABLE_LOG
#define MG_ENABLE_LOG 1
#endif
#ifndef MG_ENABLE_MD5
#define MG_ENABLE_MD5 0
#endif
// Set MG_ENABLE_WINSOCK=0 for Win32 builds with external IP stack (like LWIP)
#ifndef MG_ENABLE_WINSOCK
#define MG_ENABLE_WINSOCK 1
#endif
#ifndef MG_ENABLE_DIRECTORY_LISTING
#define MG_ENABLE_DIRECTORY_LISTING 0
#endif
#ifndef MG_ENABLE_SOCKETPAIR
#define MG_ENABLE_SOCKETPAIR 0
#endif
// Granularity of the send/recv IO buffer growth
#ifndef MG_IO_SIZE
#define MG_IO_SIZE 512
#endif
// Maximum size of the recv IO buffer
#ifndef MG_MAX_RECV_BUF_SIZE
#define MG_MAX_RECV_BUF_SIZE (3 * 1024 * 1024)
#endif
#ifndef MG_MAX_HTTP_HEADERS
#define MG_MAX_HTTP_HEADERS 40
#endif
#ifndef MG_PATH_MAX
#define MG_PATH_MAX PATH_MAX
#endif
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
struct mg_str { struct mg_str {
const char *ptr; const char *ptr; // Pointer to string data
size_t len; size_t len; // String len
}; };
#define MG_NULL_STR \ #define MG_NULL_STR \
@@ -508,14 +560,15 @@ void mg_log_set_callback(void (*fn)(const void *, size_t, void *), void *param);
struct mg_timer { struct mg_timer {
unsigned long period_ms; // Timer period in milliseconds unsigned long period_ms; // Timer period in milliseconds
unsigned flags; // Possible flags values below unsigned flags; // Possible flags values below
#define MG_TIMER_REPEAT 1 // Call function periodically, otherwise run once
#define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set
void (*fn)(void *); // Function to call void (*fn)(void *); // Function to call
void *arg; // Function argument void *arg; // Function argument
unsigned long expire; // Expiration timestamp in milliseconds unsigned long expire; // Expiration timestamp in milliseconds
struct mg_timer *next; // Linkage in g_timers list struct mg_timer *next; // Linkage in g_timers list
}; };
#define MG_TIMER_REPEAT 1 // Call function periodically, otherwise run once
#define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set
extern struct mg_timer *g_timers; // Global list of timers extern struct mg_timer *g_timers; // Global list of timers
void mg_timer_init(struct mg_timer *, unsigned long ms, unsigned, void mg_timer_init(struct mg_timer *, unsigned long ms, unsigned,
@@ -527,26 +580,12 @@ void mg_timer_poll(unsigned long uptime_ms);
// WEAK symbol makes it possible to define a "default" function implementation,
// which could be overridden by the user who can define a function with the
// same name without linking conflict
#if !defined(WEAK)
#if (defined(__GNUC__) || defined(__clang__) || \
defined(__TI_COMPILER_VERSION__)) && \
!defined(_WIN32) && !defined(__CYGWIN__)
#define WEAK __attribute__((weak))
#else
#define WEAK
#endif
#endif
char *mg_file_read(const char *path, size_t *size); char *mg_file_read(const char *path, size_t *size);
int64_t mg_file_size(const char *path);
bool mg_file_write(const char *path, const void *buf, size_t len); bool mg_file_write(const char *path, const void *buf, size_t len);
bool mg_file_printf(const char *path, const char *fmt, ...); bool mg_file_printf(const char *path, const char *fmt, ...);
void mg_random(void *buf, size_t len) WEAK; void mg_random(void *buf, size_t len);
bool mg_globmatch(const char *pattern, size_t plen, const char *s, size_t n); bool mg_globmatch(const char *pattern, size_t plen, const char *s, size_t n);
bool mg_next_comma_entry(struct mg_str *s, struct mg_str *k, struct mg_str *v); bool mg_commalist(struct mg_str *s, struct mg_str *k, struct mg_str *v);
uint16_t mg_ntohs(uint16_t net); uint16_t mg_ntohs(uint16_t net);
uint32_t mg_ntohl(uint32_t net); uint32_t mg_ntohl(uint32_t net);
uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len); uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len);
@@ -557,19 +596,11 @@ unsigned long mg_unhexn(const char *s, size_t len);
int mg_asprintf(char **buf, size_t size, const char *fmt, ...); int mg_asprintf(char **buf, size_t size, const char *fmt, ...);
int mg_vasprintf(char **buf, size_t size, const char *fmt, va_list ap); int mg_vasprintf(char **buf, size_t size, const char *fmt, va_list ap);
int64_t mg_to64(struct mg_str str); int64_t mg_to64(struct mg_str str);
int mg_check_ip_acl(struct mg_str acl, uint32_t remote_ip);
double mg_time(void); double mg_time(void);
unsigned long mg_millis(void); unsigned long mg_millis(void);
void mg_usleep(unsigned long usecs); void mg_usleep(unsigned long usecs);
#if MG_ENABLE_FS
#ifdef _WIN32
typedef struct _stati64 mg_stat_t;
#else
typedef struct stat mg_stat_t;
#endif
int mg_stat(const char *path, mg_stat_t *);
#endif
#define mg_htons(x) mg_ntohs(x) #define mg_htons(x) mg_ntohs(x)
#define mg_htonl(x) mg_ntohl(x) #define mg_htonl(x) mg_ntohl(x)
@@ -608,6 +639,33 @@ int mg_stat(const char *path, mg_stat_t *);
enum { MG_FS_READ = 1, MG_FS_WRITE = 2, MG_FS_DIR = 4 };
// Filesystem API functions
// stat() returns MG_FS_* flags and populates file size and modification time
// list() calls fn() for every directory entry, allowing to list a directory
struct mg_fs {
int (*stat)(const char *path, size_t *size, time_t *mtime);
void (*list)(const char *path, void (*fn)(const char *, void *), void *);
struct mg_fd *(*open)(const char *path, int flags); // Open file
void (*close)(struct mg_fd *fd); // Close file
size_t (*read)(void *fd, void *buf, size_t len); // Read file
size_t (*write)(void *fd, const void *buf, size_t len); // Write file
size_t (*seek)(void *fd, size_t offset); // Set file position
};
// File descriptor
struct mg_fd {
void *fd;
struct mg_fs *fs;
};
extern struct mg_fs mg_fs_posix; // POSIX open/close/read/write/seek
extern struct mg_fs mg_fs_packed; // Packed FS, see examples/complete
unsigned short mg_url_port(const char *url); unsigned short mg_url_port(const char *url);
int mg_url_is_ssl(const char *url); int mg_url_is_ssl(const char *url);
struct mg_str mg_url_host(const char *url); struct mg_str mg_url_host(const char *url);
@@ -619,15 +677,16 @@ const char *mg_url_uri(const char *url);
#include <stddef.h> #include <stddef.h>
struct mg_iobuf { struct mg_iobuf {
unsigned char *buf; unsigned char *buf; // Pointer to stored data
size_t size, len; size_t size; // Total size available
size_t len; // Current number of bytes
}; };
int mg_iobuf_init(struct mg_iobuf *, size_t); int mg_iobuf_init(struct mg_iobuf *, size_t);
int mg_iobuf_resize(struct mg_iobuf *, size_t); int mg_iobuf_resize(struct mg_iobuf *, size_t);
void mg_iobuf_free(struct mg_iobuf *); void mg_iobuf_free(struct mg_iobuf *);
size_t mg_iobuf_append(struct mg_iobuf *, const void *, size_t, size_t); size_t mg_iobuf_add(struct mg_iobuf *, size_t, const void *, size_t, size_t);
size_t mg_iobuf_delete(struct mg_iobuf *, size_t); size_t mg_iobuf_del(struct mg_iobuf *, size_t ofs, size_t len);
int mg_base64_update(unsigned char p, char *to, int len); int mg_base64_update(unsigned char p, char *to, int len);
int mg_base64_final(char *to, int len); int mg_base64_final(char *to, int len);
@@ -763,24 +822,24 @@ bool mg_send(struct mg_connection *, const void *, size_t);
int mg_printf(struct mg_connection *, const char *fmt, ...); int mg_printf(struct mg_connection *, const char *fmt, ...);
int mg_vprintf(struct mg_connection *, const char *fmt, va_list ap); int mg_vprintf(struct mg_connection *, const char *fmt, va_list ap);
char *mg_straddr(struct mg_connection *, char *, size_t); char *mg_straddr(struct mg_connection *, char *, size_t);
bool mg_socketpair(int *s1, int *s2);
bool mg_aton(struct mg_str str, struct mg_addr *addr); bool mg_aton(struct mg_str str, struct mg_addr *addr);
char *mg_ntoa(const struct mg_addr *addr, char *buf, size_t len); char *mg_ntoa(const struct mg_addr *addr, char *buf, size_t len);
struct mg_connection *mg_mkpipe(struct mg_mgr *, mg_event_handler_t, void *);
void mg_mgr_wakeup(struct mg_connection *pipe);
struct mg_http_header { struct mg_http_header {
struct mg_str name; struct mg_str name; // Header name
struct mg_str value; struct mg_str value; // Header value
}; };
struct mg_http_message { struct mg_http_message {
// GET /foo/bar/baz?aa=b&cc=ddd HTTP/1.1
// method |-| |----uri---| |--query--| |proto-|
struct mg_str method, uri, query, proto; // Request/response line struct mg_str method, uri, query, proto; // Request/response line
struct mg_http_header headers[MG_MAX_HTTP_HEADERS]; // Headers struct mg_http_header headers[MG_MAX_HTTP_HEADERS]; // Headers
struct mg_str body; // Body struct mg_str body; // Body
@@ -791,9 +850,11 @@ struct mg_http_message {
// Parameter for mg_http_serve_dir() // Parameter for mg_http_serve_dir()
struct mg_http_serve_opts { struct mg_http_serve_opts {
const char *root_dir; // Web root directory, must be non-NULL const char *root_dir; // Web root directory, must be non-NULL
const char *ssi_pattern; // SSI file name pattern, e.g. #.shtml const char *ssi_pattern; // SSI file name pattern, e.g. #.shtml
const char *extra_headers; // Extra HTTP headers to add in responses const char *extra_headers; // Extra HTTP headers to add in responses
const char *mime_types; // Extra mime types, ext1=type1,ext2=type2,..
struct mg_fs *fs; // Filesystem implementation. Use NULL for POSIX
}; };
// Parameter for mg_http_next_multipart // Parameter for mg_http_next_multipart
@@ -813,13 +874,12 @@ struct mg_connection *mg_http_listen(struct mg_mgr *, const char *url,
struct mg_connection *mg_http_connect(struct mg_mgr *, const char *url, struct mg_connection *mg_http_connect(struct mg_mgr *, const char *url,
mg_event_handler_t fn, void *fn_data); mg_event_handler_t fn, void *fn_data);
void mg_http_serve_dir(struct mg_connection *, struct mg_http_message *hm, void mg_http_serve_dir(struct mg_connection *, struct mg_http_message *hm,
struct mg_http_serve_opts *); struct mg_http_serve_opts *opts);
void mg_http_serve_file(struct mg_connection *, struct mg_http_message *, void mg_http_serve_file(struct mg_connection *, struct mg_http_message *hm,
const char *, const char *mime, const char *headers); const char *path, struct mg_http_serve_opts *opts);
void mg_http_reply(struct mg_connection *, int status_code, const char *headers, void mg_http_reply(struct mg_connection *, int status_code, const char *headers,
const char *body_fmt, ...); const char *body_fmt, ...);
struct mg_str *mg_http_get_header(struct mg_http_message *, const char *name); struct mg_str *mg_http_get_header(struct mg_http_message *, const char *name);
void mg_http_event_handler(struct mg_connection *c, int ev);
int mg_http_get_var(const struct mg_str *, const char *name, char *, size_t); int mg_http_get_var(const struct mg_str *, const char *name, char *, size_t);
int mg_url_decode(const char *s, size_t n, char *to, size_t to_len, int form); int mg_url_decode(const char *s, size_t n, char *to, size_t to_len, int form);
size_t mg_url_encode(const char *s, size_t n, char *buf, size_t len); size_t mg_url_encode(const char *s, size_t n, char *buf, size_t len);
@@ -859,14 +919,11 @@ void mg_tls_handshake(struct mg_connection *);
#define WEBSOCKET_OP_PING 9 #define WEBSOCKET_OP_PING 9
#define WEBSOCKET_OP_PONG 10 #define WEBSOCKET_OP_PONG 10
#define WEBSOCKET_FLAGS_MASK_FIN 128
#define WEBSOCKET_FLAGS_MASK_OP 15
struct mg_ws_message { struct mg_ws_message {
struct mg_str data; struct mg_str data; // Websocket message data
uint8_t flags; // Websocket message flags uint8_t flags; // Websocket message flags
}; };
struct mg_connection *mg_ws_connect(struct mg_mgr *, const char *url, struct mg_connection *mg_ws_connect(struct mg_mgr *, const char *url,
@@ -875,6 +932,7 @@ struct mg_connection *mg_ws_connect(struct mg_mgr *, const char *url,
void mg_ws_upgrade(struct mg_connection *, struct mg_http_message *, void mg_ws_upgrade(struct mg_connection *, struct mg_http_message *,
const char *fmt, ...); const char *fmt, ...);
size_t mg_ws_send(struct mg_connection *, const char *buf, size_t len, int op); size_t mg_ws_send(struct mg_connection *, const char *buf, size_t len, int op);
size_t mg_ws_wrap(struct mg_connection *, size_t len, int op);
@@ -908,13 +966,13 @@ int mg_sntp_parse(const unsigned char *buf, size_t len, struct timeval *tv);
#define MQTT_SET_QOS(flags, qos) (flags) = ((flags) & ~0x6) | ((qos) << 1) #define MQTT_SET_QOS(flags, qos) (flags) = ((flags) & ~0x6) | ((qos) << 1)
struct mg_mqtt_opts { struct mg_mqtt_opts {
struct mg_str client_id; struct mg_str client_id; // Client ID
struct mg_str will_topic; struct mg_str will_topic; // Will topic
struct mg_str will_message; struct mg_str will_message; // Will message
uint8_t qos; // Quality of service uint8_t qos; // Quality of service
bool will_retain; // Retain last will bool will_retain; // Retain last will
bool clean; // Use clean session, 0 or 1 bool clean; // Use clean session, 0 or 1
uint16_t keepalive; // Keep-alive timer in seconds uint16_t keepalive; // Keep-alive timer in seconds
}; };
struct mg_mqtt_message { struct mg_mqtt_message {
@@ -932,6 +990,8 @@ struct mg_connection *mg_mqtt_connect(struct mg_mgr *, const char *url,
mg_event_handler_t fn, void *fn_data); mg_event_handler_t fn, void *fn_data);
struct mg_connection *mg_mqtt_listen(struct mg_mgr *mgr, const char *url, struct mg_connection *mg_mqtt_listen(struct mg_mgr *mgr, const char *url,
mg_event_handler_t fn, void *fn_data); mg_event_handler_t fn, void *fn_data);
void mg_mqtt_login(struct mg_connection *c, const char *url,
struct mg_mqtt_opts *opts);
void mg_mqtt_pub(struct mg_connection *c, struct mg_str *topic, void mg_mqtt_pub(struct mg_connection *c, struct mg_str *topic,
struct mg_str *data, int qos, bool retain); struct mg_str *data, int qos, bool retain);
void mg_mqtt_sub(struct mg_connection *, struct mg_str *topic, int qos); void mg_mqtt_sub(struct mg_connection *, struct mg_str *topic, int qos);
+3
View File
@@ -7,6 +7,7 @@
#define MG_ARCH_ESP8266 4 #define MG_ARCH_ESP8266 4
#define MG_ARCH_FREERTOS_TCP 5 #define MG_ARCH_FREERTOS_TCP 5
#define MG_ARCH_FREERTOS_LWIP 6 #define MG_ARCH_FREERTOS_LWIP 6
#define MG_ARCH_AZURERTOS 7
#if !defined(MG_ARCH) #if !defined(MG_ARCH)
#if defined(__unix__) || defined(__APPLE__) #if defined(__unix__) || defined(__APPLE__)
@@ -19,6 +20,8 @@
#define MG_ARCH MG_ARCH_ESP32 #define MG_ARCH MG_ARCH_ESP32
#elif defined(FREERTOS_IP_H) #elif defined(FREERTOS_IP_H)
#define MG_ARCH MG_ARCH_FREERTOS_TCP #define MG_ARCH MG_ARCH_FREERTOS_TCP
#elif defined(AZURE_RTOS_THREADX)
#define MG_ARCH MG_ARCH_AZURERTOS
#endif #endif
#if !defined(MG_ARCH) #if !defined(MG_ARCH)
+38
View File
@@ -0,0 +1,38 @@
#pragma once
#if MG_ARCH == MG_ARCH_AZURERTOS
#include <stdarg.h>
#include <stdint.h>
#include <stdbool.h>
#include <time.h>
#include <stdio.h>
#include <tx_api.h>
#include <fx_api.h>
#include <tx_port.h>
#include <nx_port.h>
#include <nx_api.h>
#include <nx_bsd.h>
#ifdef __REDLIB__
#define va_copy(d,s)__builtin_va_copy(d,s)
#endif
#define PATH_MAX FX_MAXIMUM_PATH
#define MG_DIRSEP '\\'
#define socklen_t int
#define closesocket(x) soc_close(x)
#define gmtime_r(a, b) gmtime(a)
#define MG_INT64_FMT "%lld"
static __inline struct tm *localtime_r(time_t *t, struct tm *tm) {
(void) tm;
return localtime(t);
}
#undef FOPEN_MAX
#endif
+2
View File
@@ -22,5 +22,7 @@
#ifndef MG_PATH_MAX #ifndef MG_PATH_MAX
#define MG_PATH_MAX 128 #define MG_PATH_MAX 128
#endif #endif
#undef MG_ENABLE_DIRLIST
#define MG_ENABLE_DIRLIST 1
#endif #endif
+14 -5
View File
@@ -2,12 +2,13 @@
#if MG_ARCH == MG_ARCH_FREERTOS_LWIP #if MG_ARCH == MG_ARCH_FREERTOS_LWIP
#include <errno.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <string.h>
#if defined(__GNUC__) #if defined(__GNUC__)
#include <sys/stat.h>
#include <sys/time.h> #include <sys/time.h>
#else #else
typedef long suseconds_t; typedef long suseconds_t;
@@ -17,15 +18,23 @@ struct timeval {
}; };
#endif #endif
#if MG_ENABLE_FS
#include <sys/stat.h>
#endif
#include <FreeRTOS.h> #include <FreeRTOS.h>
#include <task.h> #include <task.h>
#include <lwip/sockets.h> #include <lwip/sockets.h>
#if LWIP_SOCKET != 1
// Sockets support disabled in LWIP by default
#error Set LWIP_SOCKET variable to 1 (in lwipopts.h)
#endif
#if LWIP_POSIX_SOCKETS_IO_NAMES != 0
// LWIP_POSIX_SOCKETS_IO_NAMES must be disabled in posix-compatible OS
// enviroment (freertos mimics to one) otherwise names like `read` and `write`
// conflict
#error LWIP_POSIX_SOCKETS_IO_NAMES must be set to 0 (in lwipopts.h) for FreeRTOS
#endif
#define MG_INT64_FMT "%lld" #define MG_INT64_FMT "%lld"
#define MG_DIRSEP '/' #define MG_DIRSEP '/'
+2 -4
View File
@@ -11,11 +11,8 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h>
#if MG_ENABLE_FS
#include <sys/stat.h> #include <sys/stat.h>
#endif #include <time.h>
#include <FreeRTOS.h> #include <FreeRTOS.h>
#include <FreeRTOS_IP.h> #include <FreeRTOS_IP.h>
@@ -51,6 +48,7 @@
FreeRTOS_recvfrom((a), (b), (c), (d), (e), (f)) FreeRTOS_recvfrom((a), (b), (c), (d), (e), (f))
#define closesocket(x) FreeRTOS_closesocket(x) #define closesocket(x) FreeRTOS_closesocket(x)
#define gethostbyname(x) FreeRTOS_gethostbyname(x) #define gethostbyname(x) FreeRTOS_gethostbyname(x)
#define getsockname(a, b, c) (-1)
// Re-route calloc/free to the FreeRTOS's functions, don't use stdlib // Re-route calloc/free to the FreeRTOS's functions, don't use stdlib
static inline void *mg_calloc(int cnt, size_t size) { static inline void *mg_calloc(int cnt, size_t size) {
+3 -2
View File
@@ -2,7 +2,7 @@
#if MG_ARCH == MG_ARCH_UNIX #if MG_ARCH == MG_ARCH_UNIX
#define _DARWIN_UNLIMITED_SELECT 1 #define _DARWIN_UNLIMITED_SELECT 1 // No limit on file descriptors
#include <arpa/inet.h> #include <arpa/inet.h>
#include <ctype.h> #include <ctype.h>
@@ -30,7 +30,8 @@
#include <unistd.h> #include <unistd.h>
#define MG_DIRSEP '/' #define MG_DIRSEP '/'
#define MG_ENABLE_POSIX 1
#define MG_INT64_FMT "%" PRId64 #define MG_INT64_FMT "%" PRId64
#undef MG_ENABLE_DIRLIST
#define MG_ENABLE_DIRLIST 1
#endif #endif
+5 -8
View File
@@ -51,8 +51,10 @@ typedef enum { false = 0, true = 1 } bool;
#ifndef __cplusplus #ifndef __cplusplus
#define snprintf _snprintf #define snprintf _snprintf
#define vsnprintf _vsnprintf #define vsnprintf _vsnprintf
#ifndef strdup // For MSVC with _DEBUG, see #1359
#define strdup(x) _strdup(x) #define strdup(x) _strdup(x)
#endif #endif
#endif
typedef unsigned suseconds_t; typedef unsigned suseconds_t;
typedef int socklen_t; typedef int socklen_t;
@@ -66,8 +68,7 @@ typedef int socklen_t;
#ifndef EWOULDBLOCK #ifndef EWOULDBLOCK
#define EWOULDBLOCK WSAEWOULDBLOCK #define EWOULDBLOCK WSAEWOULDBLOCK
#endif #endif
#define realpath(a, b) _fullpath((b), (a), MG_PATH_MAX)
#define fopen(a, b) mg_fopen((a), (b))
#ifndef va_copy #ifndef va_copy
#ifdef __va_copy #ifdef __va_copy
#define va_copy __va_copy #define va_copy __va_copy
@@ -81,12 +82,8 @@ typedef int socklen_t;
#define MG_INT64_FMT "%I64d" #define MG_INT64_FMT "%I64d"
static __inline FILE *mg_fopen(const char *path, const char *mode) { #undef MG_ENABLE_DIRLIST
wchar_t b1[PATH_MAX], b2[10]; #define MG_ENABLE_DIRLIST 1
MultiByteToWideChar(CP_UTF8, 0, path, -1, b1, sizeof(b1) / sizeof(b1[0]));
MultiByteToWideChar(CP_UTF8, 0, mode, -1, b2, sizeof(b2) / sizeof(b2[0]));
return _wfopen(b1, b2);
}
// https://lgtm.com/rules/2154840805/ -gmtime, localtime, ctime and asctime // https://lgtm.com/rules/2154840805/ -gmtime, localtime, ctime and asctime
static __inline struct tm *gmtime_r(time_t *t, struct tm *tm) { static __inline struct tm *gmtime_r(time_t *t, struct tm *tm) {
+14 -10
View File
@@ -12,12 +12,8 @@
#define MG_ENABLE_OPENSSL 0 #define MG_ENABLE_OPENSSL 0
#endif #endif
#ifndef MG_ENABLE_FS
#define MG_ENABLE_FS 1
#endif
#ifndef MG_ENABLE_SSI #ifndef MG_ENABLE_SSI
#define MG_ENABLE_SSI 0 #define MG_ENABLE_SSI 1
#endif #endif
#ifndef MG_ENABLE_IPV6 #ifndef MG_ENABLE_IPV6
@@ -37,17 +33,21 @@
#define MG_ENABLE_WINSOCK 1 #define MG_ENABLE_WINSOCK 1
#endif #endif
#ifndef MG_ENABLE_DIRECTORY_LISTING #ifndef MG_ENABLE_DIRLIST
#define MG_ENABLE_DIRECTORY_LISTING 0 #define MG_ENABLE_DIRLIST 0
#endif #endif
#ifndef MG_ENABLE_SOCKETPAIR #ifndef MG_ENABLE_CUSTOM_RANDOM
#define MG_ENABLE_SOCKETPAIR 0 #define MG_ENABLE_CUSTOM_RANDOM 0
#endif
#ifndef MG_ENABLE_PACKED_FS
#define MG_ENABLE_PACKED_FS 0
#endif #endif
// Granularity of the send/recv IO buffer growth // Granularity of the send/recv IO buffer growth
#ifndef MG_IO_SIZE #ifndef MG_IO_SIZE
#define MG_IO_SIZE 512 #define MG_IO_SIZE 2048
#endif #endif
// Maximum size of the recv IO buffer // Maximum size of the recv IO buffer
@@ -62,3 +62,7 @@
#ifndef MG_PATH_MAX #ifndef MG_PATH_MAX
#define MG_PATH_MAX PATH_MAX #define MG_PATH_MAX PATH_MAX
#endif #endif
#ifndef MG_SOCK_LISTEN_BACKLOG_SIZE
#define MG_SOCK_LISTEN_BACKLOG_SIZE 128
#endif
+27
View File
@@ -0,0 +1,27 @@
#pragma once
#include "arch.h"
enum { MG_FS_READ = 1, MG_FS_WRITE = 2, MG_FS_DIR = 4 };
// Filesystem API functions
// stat() returns MG_FS_* flags and populates file size and modification time
// list() calls fn() for every directory entry, allowing to list a directory
struct mg_fs {
int (*stat)(const char *path, size_t *size, time_t *mtime);
void (*list)(const char *path, void (*fn)(const char *, void *), void *);
struct mg_fd *(*open)(const char *path, int flags); // Open file
void (*close)(struct mg_fd *fd); // Close file
size_t (*read)(void *fd, void *buf, size_t len); // Read file
size_t (*write)(void *fd, const void *buf, size_t len); // Write file
size_t (*seek)(void *fd, size_t offset); // Set file position
};
// File descriptor
struct mg_fd {
void *fd;
struct mg_fs *fs;
};
extern struct mg_fs mg_fs_posix; // POSIX open/close/read/write/seek
extern struct mg_fs mg_fs_packed; // Packed FS, see examples/complete
+102
View File
@@ -0,0 +1,102 @@
#include "fs.h"
struct packed_file {
const char *data;
size_t size;
size_t pos;
};
const char *mg_unpack(const char *path, size_t *size, time_t *mtime);
const char *mg_unlist(size_t no);
#if MG_ENABLE_PACKED_FS
#else
const char *mg_unpack(const char *path, size_t *size, time_t *mtime) {
(void) path, (void) size, (void) mtime;
return NULL;
}
const char *mg_unlist(size_t no) {
(void) no;
return NULL;
}
#endif
static int is_dir_prefix(const char *prefix, size_t n, const char *path) {
return n < strlen(path) && memcmp(prefix, path, n) == 0 && path[n] == '/';
//(n == 0 || path[n] == MG_DIRSEP);
}
static int packed_stat(const char *path, size_t *size, time_t *mtime) {
const char *p;
size_t i, n = strlen(path);
if (mg_unpack(path, size, mtime)) return MG_FS_READ; // Regular file
// Scan all files. If `path` is a dir prefix for any of them, it's a dir
for (i = 0; (p = mg_unlist(i)) != NULL; i++) {
if (is_dir_prefix(path, n, p)) return MG_FS_DIR;
}
return 0;
}
static void packed_list(const char *dir, void (*fn)(const char *, void *),
void *userdata) {
char buf[256], tmp[sizeof(buf)];
const char *path, *begin, *end;
size_t i, n = strlen(dir);
tmp[0] = '\0'; // Previously listed entry
for (i = 0; (path = mg_unlist(i)) != NULL; i++) {
if (!is_dir_prefix(dir, n, path)) continue;
begin = &path[n + 1];
end = strchr(begin, '/');
if (end == NULL) end = begin + strlen(begin);
snprintf(buf, sizeof(buf), "%.*s", (int) (end - begin), begin);
buf[sizeof(buf) - 1] = '\0';
// If this entry has been already listed, skip
// NOTE: we're assuming that file list is sorted alphabetically
if (strcmp(buf, tmp) == 0) continue;
fn(buf, userdata); // Not yet listed, call user function
strcpy(tmp, buf); // And save this entry as listed
}
}
static struct mg_fd *packed_open(const char *path, int flags) {
size_t size = 0;
const char *data = mg_unpack(path, &size, NULL);
struct packed_file *fp = NULL;
struct mg_fd *fd = NULL;
if (data == NULL) return NULL;
if (flags & MG_FS_WRITE) return NULL;
fp = (struct packed_file *) calloc(1, sizeof(*fp));
fd = (struct mg_fd *) calloc(1, sizeof(*fd));
fp->size = size;
fp->data = data;
fd->fd = fp;
fd->fs = &mg_fs_packed;
return fd;
}
static void packed_close(struct mg_fd *fd) {
if (fd) free(fd->fd), free(fd);
}
static size_t packed_read(void *fd, void *buf, size_t len) {
struct packed_file *fp = (struct packed_file *) fd;
if (fp->pos + len > fp->size) len = fp->size - fp->pos;
memcpy(buf, &fp->data[fp->pos], len);
fp->pos += len;
return len;
}
static size_t packed_write(void *fd, const void *buf, size_t len) {
(void) fd, (void) buf, (void) len;
return 0;
}
static size_t packed_seek(void *fd, size_t offset) {
struct packed_file *fp = (struct packed_file *) fd;
fp->pos = offset;
if (fp->pos > fp->size) fp->pos = fp->size;
return fp->pos;
}
struct mg_fs mg_fs_packed = {packed_stat, packed_list, packed_open,
packed_close, packed_read, packed_write,
packed_seek};
+229
View File
@@ -0,0 +1,229 @@
#include "fs.h"
#if defined(FOPEN_MAX)
static int p_stat(const char *path, size_t *size, time_t *mtime) {
#ifdef _WIN32
struct _stati64 st;
wchar_t tmp[PATH_MAX];
MultiByteToWideChar(CP_UTF8, 0, path, -1, tmp, sizeof(tmp) / sizeof(tmp[0]));
if (_wstati64(tmp, &st) != 0) return 0;
#else
struct stat st;
if (stat(path, &st) != 0) return 0;
#endif
if (size) *size = (size_t) st.st_size;
if (mtime) *mtime = st.st_mtime;
return MG_FS_READ | MG_FS_WRITE | (S_ISDIR(st.st_mode) ? MG_FS_DIR : 0);
}
#ifdef _WIN32
struct dirent {
char d_name[MAX_PATH];
};
typedef struct win32_dir {
HANDLE handle;
WIN32_FIND_DATAW info;
struct dirent result;
} DIR;
int gettimeofday(struct timeval *tv, void *tz) {
FILETIME ft;
unsigned __int64 tmpres = 0;
if (tv != NULL) {
GetSystemTimeAsFileTime(&ft);
tmpres |= ft.dwHighDateTime;
tmpres <<= 32;
tmpres |= ft.dwLowDateTime;
tmpres /= 10; // convert into microseconds
tmpres -= (int64_t) 11644473600000000;
tv->tv_sec = (long) (tmpres / 1000000UL);
tv->tv_usec = (long) (tmpres % 1000000UL);
}
(void) tz;
return 0;
}
static int to_wchar(const char *path, wchar_t *wbuf, size_t wbuf_len) {
int ret;
char buf[MAX_PATH * 2], buf2[MAX_PATH * 2], *p;
strncpy(buf, path, sizeof(buf));
buf[sizeof(buf) - 1] = '\0';
// Trim trailing slashes. Leave backslash for paths like "X:\"
p = buf + strlen(buf) - 1;
while (p > buf && p[-1] != ':' && (p[0] == '\\' || p[0] == '/')) *p-- = '\0';
memset(wbuf, 0, wbuf_len * sizeof(wchar_t));
ret = MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, (int) wbuf_len);
// Convert back to Unicode. If doubly-converted string does not match the
// original, something is fishy, reject.
WideCharToMultiByte(CP_UTF8, 0, wbuf, (int) wbuf_len, buf2, sizeof(buf2),
NULL, NULL);
if (strcmp(buf, buf2) != 0) {
wbuf[0] = L'\0';
ret = 0;
}
return ret;
}
DIR *opendir(const char *name) {
DIR *d = NULL;
wchar_t wpath[MAX_PATH];
DWORD attrs;
if (name == NULL) {
SetLastError(ERROR_BAD_ARGUMENTS);
} else if ((d = (DIR *) calloc(1, sizeof(*d))) == NULL) {
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
} else {
to_wchar(name, wpath, sizeof(wpath) / sizeof(wpath[0]));
attrs = GetFileAttributesW(wpath);
if (attrs != 0Xffffffff && (attrs & FILE_ATTRIBUTE_DIRECTORY)) {
(void) wcscat(wpath, L"\\*");
d->handle = FindFirstFileW(wpath, &d->info);
d->result.d_name[0] = '\0';
} else {
free(d);
d = NULL;
}
}
return d;
}
int closedir(DIR *d) {
int result = 0;
if (d != NULL) {
if (d->handle != INVALID_HANDLE_VALUE)
result = FindClose(d->handle) ? 0 : -1;
free(d);
} else {
result = -1;
SetLastError(ERROR_BAD_ARGUMENTS);
}
return result;
}
struct dirent *readdir(DIR *d) {
struct dirent *result = NULL;
if (d != NULL) {
memset(&d->result, 0, sizeof(d->result));
if (d->handle != INVALID_HANDLE_VALUE) {
result = &d->result;
WideCharToMultiByte(CP_UTF8, 0, d->info.cFileName, -1, result->d_name,
sizeof(result->d_name), NULL, NULL);
if (!FindNextFileW(d->handle, &d->info)) {
FindClose(d->handle);
d->handle = INVALID_HANDLE_VALUE;
}
} else {
SetLastError(ERROR_FILE_NOT_FOUND);
}
} else {
SetLastError(ERROR_BAD_ARGUMENTS);
}
return result;
}
#endif
static void p_list(const char *dir, void (*fn)(const char *, void *),
void *userdata) {
#if MG_ENABLE_DIRLIST
struct dirent *dp;
DIR *dirp;
if ((dirp = (opendir(dir))) == NULL) return;
while ((dp = readdir(dirp)) != NULL) {
if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) continue;
fn(dp->d_name, userdata);
}
closedir(dirp);
#else
(void) dir, (void) fn, (void) userdata;
#endif
}
static struct mg_fd *p_open(const char *path, int flags) {
const char *mode = flags == (MG_FS_READ | MG_FS_WRITE) ? "r+b"
: flags & MG_FS_READ ? "rb"
: flags & MG_FS_WRITE ? "wb"
: "";
void *fp = NULL;
struct mg_fd *fd = NULL;
#ifdef _WIN32
wchar_t b1[PATH_MAX], b2[10];
MultiByteToWideChar(CP_UTF8, 0, path, -1, b1, sizeof(b1) / sizeof(b1[0]));
MultiByteToWideChar(CP_UTF8, 0, mode, -1, b2, sizeof(b2) / sizeof(b2[0]));
fp = (void *) _wfopen(b1, b2);
#else
fp = (void *) fopen(path, mode);
#endif
if (fp == NULL) return NULL;
fd = (struct mg_fd *) calloc(1, sizeof(*fd));
fd->fd = fp;
fd->fs = &mg_fs_posix;
return fd;
}
static void p_close(struct mg_fd *fd) {
if (fd != NULL) fclose((FILE *) fd->fd), free(fd);
}
static size_t p_read(void *fp, void *buf, size_t len) {
return fread(buf, 1, len, (FILE *) fp);
}
static size_t p_write(void *fp, const void *buf, size_t len) {
return fwrite(buf, 1, len, (FILE *) fp);
}
static size_t p_seek(void *fp, size_t offset) {
#if _FILE_OFFSET_BITS == 64 || _POSIX_C_SOURCE >= 200112L || \
_XOPEN_SOURCE >= 600
fseeko((FILE *) fp, (off_t) offset, SEEK_SET);
#else
fseek((FILE *) fp, (long) offset, SEEK_SET);
#endif
return (size_t) ftell((FILE *) fp);
}
#else
static char *p_realpath(const char *path, char *resolved_path) {
(void) path, (void) resolved_path;
return NULL;
}
static int p_stat(const char *path, size_t *size, time_t *mtime) {
(void) path, (void) size, (void) mtime;
return 0;
}
static void p_list(const char *path, void (*fn)(const char *, void *),
void *userdata) {
(void) path, (void) fn, (void) userdata;
}
static struct mg_fd *p_open(const char *path, int flags) {
(void) path, (void) flags;
return NULL;
}
static void p_close(struct mg_fd *fd) {
(void) fd;
}
static size_t p_read(void *fd, void *buf, size_t len) {
(void) fd, (void) buf, (void) len;
return 0;
}
static size_t p_write(void *fd, const void *buf, size_t len) {
(void) fd, (void) buf, (void) len;
return 0;
}
static size_t p_seek(void *fd, size_t offset) {
(void) fd, (void) offset;
return (size_t) ~0;
}
#endif
struct mg_fs mg_fs_posix = {p_stat, p_list, p_open, p_close,
p_read, p_write, p_seek};
+266 -381
View File
@@ -108,9 +108,9 @@ int mg_http_get_var(const struct mg_str *buf, const char *name, char *dst,
if ((p == buf->ptr || p[-1] == '&') && p[name_len] == '=' && if ((p == buf->ptr || p[-1] == '&') && p[name_len] == '=' &&
!mg_ncasecmp(name, p, name_len)) { !mg_ncasecmp(name, p, name_len)) {
p += name_len + 1; p += name_len + 1;
s = (const char *) memchr(p, '&', (size_t)(e - p)); s = (const char *) memchr(p, '&', (size_t) (e - p));
if (s == NULL) s = e; if (s == NULL) s = e;
len = mg_url_decode(p, (size_t)(s - p), dst, dst_len, 1); len = mg_url_decode(p, (size_t) (s - p), dst, dst_len, 1);
if (len < 0) len = -3; // Failed to decode if (len < 0) len = -3; // Failed to decode
break; break;
} }
@@ -158,7 +158,7 @@ static const char *skip(const char *s, const char *e, const char *d,
struct mg_str *v) { struct mg_str *v) {
v->ptr = s; v->ptr = s;
while (s < e && *s != '\n' && strchr(d, *s) == NULL) s++; while (s < e && *s != '\n' && strchr(d, *s) == NULL) s++;
v->len = (size_t)(s - v->ptr); v->len = (size_t) (s - v->ptr);
while (s < e && strchr(d, *s) != NULL) s++; while (s < e && strchr(d, *s) != NULL) s++;
return s; return s;
} }
@@ -215,8 +215,8 @@ int mg_http_parse(const char *s, size_t len, struct mg_http_message *hm) {
// If URI contains '?' character, setup query string // If URI contains '?' character, setup query string
if ((qs = (const char *) memchr(hm->uri.ptr, '?', hm->uri.len)) != NULL) { if ((qs = (const char *) memchr(hm->uri.ptr, '?', hm->uri.len)) != NULL) {
hm->query.ptr = qs + 1; hm->query.ptr = qs + 1;
hm->query.len = (size_t)(&hm->uri.ptr[hm->uri.len] - (qs + 1)); hm->query.len = (size_t) (&hm->uri.ptr[hm->uri.len] - (qs + 1));
hm->uri.len = (size_t)(qs - hm->uri.ptr); hm->uri.len = (size_t) (qs - hm->uri.ptr);
} }
mg_http_parse_headers(s, end, hm->headers, mg_http_parse_headers(s, end, hm->headers,
@@ -352,7 +352,7 @@ static const char *mg_http_status_code_str(int status_code) {
void mg_http_reply(struct mg_connection *c, int code, const char *headers, void mg_http_reply(struct mg_connection *c, int code, const char *headers,
const char *fmt, ...) { const char *fmt, ...) {
char mem[100], *buf = mem; char mem[256], *buf = mem;
va_list ap; va_list ap;
int len; int len;
va_start(ap, fmt); va_start(ap, fmt);
@@ -364,17 +364,17 @@ void mg_http_reply(struct mg_connection *c, int code, const char *headers,
if (buf != mem) free(buf); if (buf != mem) free(buf);
} }
#if MG_ENABLE_FS
static void http_cb(struct mg_connection *, int, void *, void *); static void http_cb(struct mg_connection *, int, void *, void *);
static void restore_http_cb(struct mg_connection *c) { static void restore_http_cb(struct mg_connection *c) {
if (c->pfn_data != NULL) fclose((FILE *) c->pfn_data); struct mg_fd *fd = (struct mg_fd *) c->pfn_data;
if (fd != NULL) fd->fs->close(fd);
c->pfn_data = NULL; c->pfn_data = NULL;
c->pfn = http_cb; c->pfn = http_cb;
} }
char *mg_http_etag(char *buf, size_t len, mg_stat_t *st) { char *mg_http_etag(char *buf, size_t len, size_t size, time_t mtime) {
snprintf(buf, len, "\"%lx." MG_INT64_FMT "\"", (unsigned long) st->st_mtime, snprintf(buf, len, "\"%lx." MG_INT64_FMT "\"", (unsigned long) mtime,
(int64_t) st->st_size); (int64_t) size);
return buf; return buf;
} }
@@ -407,12 +407,13 @@ int mg_http_upload(struct mg_connection *c, struct mg_http_message *hm,
static void static_cb(struct mg_connection *c, int ev, void *ev_data, static void static_cb(struct mg_connection *c, int ev, void *ev_data,
void *fn_data) { void *fn_data) {
if (ev == MG_EV_WRITE || ev == MG_EV_POLL) { if (ev == MG_EV_WRITE || ev == MG_EV_POLL) {
FILE *fp = (FILE *) fn_data; struct mg_fd *fd = (struct mg_fd *) fn_data;
// Read to send IO buffer directly, avoid extra on-stack buffer // Read to send IO buffer directly, avoid extra on-stack buffer
size_t n, max = 2 * MG_IO_SIZE; size_t n, max = 2 * MG_IO_SIZE;
if (c->send.size < max) mg_iobuf_resize(&c->send, max); if (c->send.size < max) mg_iobuf_resize(&c->send, max);
if (c->send.len >= c->send.size) return; // Rate limit if (c->send.len >= c->send.size) return; // Rate limit
n = fread(c->send.buf + c->send.len, 1, c->send.size - c->send.len, fp); n = fd->fs->read(fd->fd, c->send.buf + c->send.len,
c->send.size - c->send.len);
if (n > 0) c->send.len += n; if (n > 0) c->send.len += n;
if (c->send.len < c->send.size) restore_http_cb(c); if (c->send.len < c->send.size) restore_http_cb(c);
} else if (ev == MG_EV_CLOSE) { } else if (ev == MG_EV_CLOSE) {
@@ -421,73 +422,83 @@ static void static_cb(struct mg_connection *c, int ev, void *ev_data,
(void) ev_data; (void) ev_data;
} }
static const char *guess_content_type(const char *filename) { static struct mg_str guess_content_type(struct mg_str path, const char *extra) {
size_t n = strlen(filename); // clang-format off
#define MIME_ENTRY(_ext, _type) \ struct mimeentry { struct mg_str extension, value; };
{ _ext, sizeof(_ext) - 1, _type } #define MIME_ENTRY(a, b) {{a, sizeof(a) - 1 }, { b, sizeof(b) - 1 }}
const struct { // clang-format on
const char *ext; const struct mimeentry tab[] = {
size_t ext_len; MIME_ENTRY("html", "text/html; charset=utf-8"),
const char *type; MIME_ENTRY("htm", "text/html; charset=utf-8"),
} * t, types[] = { MIME_ENTRY("css", "text/css; charset=utf-8"),
MIME_ENTRY("html", "text/html; charset=utf-8"), MIME_ENTRY("js", "text/javascript; charset=utf-8"),
MIME_ENTRY("htm", "text/html; charset=utf-8"), MIME_ENTRY("gif", "image/gif"),
MIME_ENTRY("css", "text/css; charset=utf-8"), MIME_ENTRY("png", "image/png"),
MIME_ENTRY("js", "text/javascript; charset=utf-8"), MIME_ENTRY("woff", "font/woff"),
MIME_ENTRY("gif", "image/gif"), MIME_ENTRY("ttf", "font/ttf"),
MIME_ENTRY("png", "image/png"), MIME_ENTRY("aac", "audio/aac"),
MIME_ENTRY("woff", "font/woff"), MIME_ENTRY("avi", "video/x-msvideo"),
MIME_ENTRY("ttf", "font/ttf"), MIME_ENTRY("azw", "application/vnd.amazon.ebook"),
MIME_ENTRY("aac", "audio/aac"), MIME_ENTRY("bin", "application/octet-stream"),
MIME_ENTRY("avi", "video/x-msvideo"), MIME_ENTRY("bmp", "image/bmp"),
MIME_ENTRY("azw", "application/vnd.amazon.ebook"), MIME_ENTRY("bz", "application/x-bzip"),
MIME_ENTRY("bin", "application/octet-stream"), MIME_ENTRY("bz2", "application/x-bzip2"),
MIME_ENTRY("bmp", "image/bmp"), MIME_ENTRY("csv", "text/csv"),
MIME_ENTRY("bz", "application/x-bzip"), MIME_ENTRY("doc", "application/msword"),
MIME_ENTRY("bz2", "application/x-bzip2"), MIME_ENTRY("epub", "application/epub+zip"),
MIME_ENTRY("csv", "text/csv"), MIME_ENTRY("exe", "application/octet-stream"),
MIME_ENTRY("doc", "application/msword"), MIME_ENTRY("gz", "application/gzip"),
MIME_ENTRY("epub", "application/epub+zip"), MIME_ENTRY("ico", "image/x-icon"),
MIME_ENTRY("exe", "application/octet-stream"), MIME_ENTRY("json", "application/json"),
MIME_ENTRY("gz", "application/gzip"), MIME_ENTRY("mid", "audio/mid"),
MIME_ENTRY("ico", "image/x-icon"), MIME_ENTRY("mjs", "text/javascript"),
MIME_ENTRY("json", "application/json"), MIME_ENTRY("mov", "video/quicktime"),
MIME_ENTRY("mid", "audio/mid"), MIME_ENTRY("mp3", "audio/mpeg"),
MIME_ENTRY("mjs", "text/javascript"), MIME_ENTRY("mp4", "video/mp4"),
MIME_ENTRY("mov", "video/quicktime"), MIME_ENTRY("mpeg", "video/mpeg"),
MIME_ENTRY("mp3", "audio/mpeg"), MIME_ENTRY("mpg", "video/mpeg"),
MIME_ENTRY("mp4", "video/mp4"), MIME_ENTRY("ogg", "application/ogg"),
MIME_ENTRY("mpeg", "video/mpeg"), MIME_ENTRY("pdf", "application/pdf"),
MIME_ENTRY("mpg", "video/mpeg"), MIME_ENTRY("rar", "application/rar"),
MIME_ENTRY("ogg", "application/ogg"), MIME_ENTRY("rtf", "application/rtf"),
MIME_ENTRY("pdf", "application/pdf"), MIME_ENTRY("shtml", "text/html; charset=utf-8"),
MIME_ENTRY("rar", "application/rar"), MIME_ENTRY("svg", "image/svg+xml"),
MIME_ENTRY("rtf", "application/rtf"), MIME_ENTRY("tar", "application/tar"),
MIME_ENTRY("shtml", "text/html; charset=utf-8"), MIME_ENTRY("tgz", "application/tar-gz"),
MIME_ENTRY("svg", "image/svg+xml"), MIME_ENTRY("txt", "text/plain; charset=utf-8"),
MIME_ENTRY("tar", "application/tar"), MIME_ENTRY("wasm", "application/wasm"),
MIME_ENTRY("tgz", "application/tar-gz"), MIME_ENTRY("wav", "audio/wav"),
MIME_ENTRY("txt", "text/plain; charset=utf-8"), MIME_ENTRY("weba", "audio/webm"),
MIME_ENTRY("wasm", "application/wasm"), MIME_ENTRY("webm", "video/webm"),
MIME_ENTRY("wav", "audio/wav"), MIME_ENTRY("webp", "image/webp"),
MIME_ENTRY("weba", "audio/webm"), MIME_ENTRY("xls", "application/excel"),
MIME_ENTRY("webm", "video/webm"), MIME_ENTRY("xml", "application/xml"),
MIME_ENTRY("webp", "image/webp"), MIME_ENTRY("xsl", "application/xml"),
MIME_ENTRY("xls", "application/excel"), MIME_ENTRY("zip", "application/zip"),
MIME_ENTRY("xml", "application/xml"), MIME_ENTRY("3gp", "video/3gpp"),
MIME_ENTRY("xsl", "application/xml"), MIME_ENTRY("7z", "application/x-7z-compressed"),
MIME_ENTRY("zip", "application/zip"), MIME_ENTRY("7z", "application/x-7z-compressed"),
MIME_ENTRY("3gp", "video/3gpp"), {{0, 0}, {0, 0}},
MIME_ENTRY("7z", "application/x-7z-compressed"), };
{NULL, 0, NULL}, size_t i = 0;
}; struct mg_str k, v, s = mg_str(extra);
for (t = types; t->ext != NULL; t++) { // Shrink path to its extension only
if (n < t->ext_len + 2) continue; while (i < path.len && path.ptr[path.len - i - 1] != '.') i++;
if (mg_ncasecmp(t->ext, &filename[n - t->ext_len], t->ext_len)) continue; path.ptr += path.len - i;
return t->type; path.len = i;
// Process user-provided mime type overrides, if any
while (mg_commalist(&s, &k, &v)) {
if (mg_strcmp(path, k) == 0) return v;
} }
return "text/plain; charset=utf-8";
// Process built-in mime types
for (i = 0; tab[i].extension.ptr != NULL; i++) {
if (mg_strcmp(path, tab[i].extension) == 0) return tab[i].value;
}
return mg_str("text/plain; charset=utf-8");
} }
static int getrange(struct mg_str *s, int64_t *a, int64_t *b) { static int getrange(struct mg_str *s, int64_t *a, int64_t *b) {
@@ -511,24 +522,29 @@ static int getrange(struct mg_str *s, int64_t *a, int64_t *b) {
} }
void mg_http_serve_file(struct mg_connection *c, struct mg_http_message *hm, void mg_http_serve_file(struct mg_connection *c, struct mg_http_message *hm,
const char *path, const char *mime, const char *hdrs) { const char *path, struct mg_http_serve_opts *opts) {
struct mg_str *inm = mg_http_get_header(hm, "If-None-Match");
mg_stat_t st;
char etag[64]; char etag[64];
FILE *fp = fopen(path, "rb"); struct mg_fs *fs = opts->fs == NULL ? &mg_fs_posix : opts->fs;
if (fp == NULL || mg_stat(path, &st) != 0 || struct mg_fd *fd = fs->open(path, MG_FS_READ);
mg_http_etag(etag, sizeof(etag), &st) != etag) { size_t size = 0;
LOG(LL_DEBUG, ("404 [%.*s] [%s] %p", (int) hm->uri.len, hm->uri.ptr, path, time_t mtime = 0;
(void *) fp)); struct mg_str *inm = NULL;
if (fd == NULL || fs->stat(path, &size, &mtime) == 0) {
LOG(LL_DEBUG, ("404 [%s] %p", path, (void *) fd));
mg_http_reply(c, 404, "", "%s", "Not found\n"); mg_http_reply(c, 404, "", "%s", "Not found\n");
if (fp != NULL) fclose(fp); fs->close(fd);
} else if (inm != NULL && mg_vcasecmp(inm, etag) == 0) { // NOTE: mg_http_etag() call should go first!
fclose(fp); } else if (mg_http_etag(etag, sizeof(etag), size, mtime) != NULL &&
(inm = mg_http_get_header(hm, "If-None-Match")) != NULL &&
mg_vcasecmp(inm, etag) == 0) {
fs->close(fd);
mg_printf(c, "HTTP/1.1 304 Not Modified\r\nContent-Length: 0\r\n\r\n"); mg_printf(c, "HTTP/1.1 304 Not Modified\r\nContent-Length: 0\r\n\r\n");
} else { } else {
int n, status = 200; int n, status = 200;
char range[100] = ""; char range[100] = "";
int64_t r1 = 0, r2 = 0, cl = st.st_size; int64_t r1 = 0, r2 = 0, cl = (int64_t) size;
struct mg_str mime = guess_content_type(mg_str(path), opts->mime_types);
// Handle Range header // Handle Range header
struct mg_str *rh = mg_http_get_header(hm, "Range"); struct mg_str *rh = mg_http_get_header(hm, "Range");
@@ -539,206 +555,78 @@ void mg_http_serve_file(struct mg_connection *c, struct mg_http_message *hm,
status = 416; status = 416;
cl = 0; cl = 0;
snprintf(range, sizeof(range), snprintf(range, sizeof(range),
"Content-Range: bytes */" MG_INT64_FMT "\r\n", "Content-Range: bytes */" MG_INT64_FMT "\r\n", (int64_t) size);
(int64_t) st.st_size);
} else { } else {
status = 206; status = 206;
cl = r2 - r1 + 1; cl = r2 - r1 + 1;
snprintf(range, sizeof(range), snprintf(range, sizeof(range),
"Content-Range: bytes " MG_INT64_FMT "-" MG_INT64_FMT "Content-Range: bytes " MG_INT64_FMT "-" MG_INT64_FMT
"/" MG_INT64_FMT "\r\n", "/" MG_INT64_FMT "\r\n",
r1, r1 + cl - 1, (int64_t) st.st_size); r1, r1 + cl - 1, (int64_t) size);
#if _FILE_OFFSET_BITS == 64 || _POSIX_C_SOURCE >= 200112L || \ fs->seek(fd->fd, (size_t) r1);
_XOPEN_SOURCE >= 600
fseeko(fp, (off_t) r1, SEEK_SET);
#else
fseek(fp, (long) r1, SEEK_SET);
#endif
} }
} }
mg_printf(c, mg_printf(c,
"HTTP/1.1 %d %s\r\nContent-Type: %s\r\n" "HTTP/1.1 %d %s\r\nContent-Type: %.*s\r\n"
"Etag: %s\r\nContent-Length: " MG_INT64_FMT "\r\n%s%s\r\n", "Etag: %s\r\nContent-Length: " MG_INT64_FMT "\r\n%s%s\r\n",
status, mg_http_status_code_str(status), mime, etag, cl, range, status, mg_http_status_code_str(status), (int) mime.len, mime.ptr,
hdrs ? hdrs : ""); etag, cl, range, opts->extra_headers ? opts->extra_headers : "");
if (mg_vcasecmp(&hm->method, "HEAD") == 0) { if (mg_vcasecmp(&hm->method, "HEAD") == 0) {
fclose(fp); c->is_draining = 1;
fs->close(fd);
} else { } else {
c->pfn = static_cb; c->pfn = static_cb;
c->pfn_data = fp; c->pfn_data = fd;
} }
} }
} }
#if MG_ARCH == MG_ARCH_ESP32 || MG_ARCH == MG_ARCH_ESP8266 || \ struct printdirentrydata {
MG_ARCH == MG_ARCH_FREERTOS_TCP struct mg_connection *c;
char *realpath(const char *src, char *dst) { struct mg_http_message *hm;
int len = strlen(src); struct mg_http_serve_opts *opts;
if (len > MG_PATH_MAX - 1) len = MG_PATH_MAX - 1; const char *dir;
strncpy(dst, src, len);
dst[len] = '\0';
LOG(LL_DEBUG, ("[%s] -> [%s]", src, dst));
return dst;
}
#endif
// Allow user to override this function
bool mg_is_dir(const char *path) WEAK;
bool mg_is_dir(const char *path) {
#if MG_ARCH == MG_ARCH_FREERTOS_TCP && defined(MG_ENABLE_FF)
struct FF_STAT st;
return (ff_stat(path, &st) == 0) && (st.st_mode & FF_IFDIR);
#else
mg_stat_t st;
return mg_stat(path, &st) == 0 && S_ISDIR(st.st_mode);
#endif
}
#if MG_ENABLE_DIRECTORY_LISTING
#ifdef _WIN32
struct dirent {
char d_name[MAX_PATH];
}; };
typedef struct win32_dir { static void printdirentry(const char *name, void *userdata) {
HANDLE handle; struct printdirentrydata *d = (struct printdirentrydata *) userdata;
WIN32_FIND_DATAW info; struct mg_fs *fs = d->opts->fs == NULL ? &mg_fs_posix : d->opts->fs;
struct dirent result; size_t size = 0;
} DIR; time_t mtime = 0;
char path[MG_PATH_MAX], sz[64], mod[64];
int flags, n = 0;
int gettimeofday(struct timeval *tv, void *tz) { // LOG(LL_DEBUG, ("[%s] [%s]", d->dir, name));
FILETIME ft; if (snprintf(path, sizeof(path), "%s%c%s", d->dir, '/', name) < 0) {
unsigned __int64 tmpres = 0; LOG(LL_ERROR, ("%s truncated", name));
} else if ((flags = fs->stat(path, &size, &mtime)) == 0) {
if (tv != NULL) { LOG(LL_ERROR, ("%lu stat(%s): %d", d->c->id, path, errno));
GetSystemTimeAsFileTime(&ft);
tmpres |= ft.dwHighDateTime;
tmpres <<= 32;
tmpres |= ft.dwLowDateTime;
tmpres /= 10; // convert into microseconds
tmpres -= (int64_t) 11644473600000000;
tv->tv_sec = (long) (tmpres / 1000000UL);
tv->tv_usec = (long) (tmpres % 1000000UL);
}
(void) tz;
return 0;
}
static int to_wchar(const char *path, wchar_t *wbuf, size_t wbuf_len) {
int ret;
char buf[MAX_PATH * 2], buf2[MAX_PATH * 2], *p;
strncpy(buf, path, sizeof(buf));
buf[sizeof(buf) - 1] = '\0';
// Trim trailing slashes. Leave backslash for paths like "X:\"
p = buf + strlen(buf) - 1;
while (p > buf && p[-1] != ':' && (p[0] == '\\' || p[0] == '/')) *p-- = '\0';
memset(wbuf, 0, wbuf_len * sizeof(wchar_t));
ret = MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, (int) wbuf_len);
// Convert back to Unicode. If doubly-converted string does not match the
// original, something is fishy, reject.
WideCharToMultiByte(CP_UTF8, 0, wbuf, (int) wbuf_len, buf2, sizeof(buf2),
NULL, NULL);
if (strcmp(buf, buf2) != 0) {
wbuf[0] = L'\0';
ret = 0;
}
return ret;
}
DIR *opendir(const char *name) {
DIR *d = NULL;
wchar_t wpath[MAX_PATH];
DWORD attrs;
if (name == NULL) {
SetLastError(ERROR_BAD_ARGUMENTS);
} else if ((d = (DIR *) calloc(1, sizeof(*d))) == NULL) {
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
} else { } else {
to_wchar(name, wpath, sizeof(wpath) / sizeof(wpath[0])); const char *slash = flags & MG_FS_DIR ? "/" : "";
attrs = GetFileAttributesW(wpath); struct tm t;
if (attrs != 0Xffffffff && (attrs & FILE_ATTRIBUTE_DIRECTORY)) { if (flags & MG_FS_DIR) {
(void) wcscat(wpath, L"\\*"); snprintf(sz, sizeof(sz), "%s", "[DIR]");
d->handle = FindFirstFileW(wpath, &d->info); } else if (size < 1024) {
d->result.d_name[0] = '\0'; snprintf(sz, sizeof(sz), "%d", (int) size);
} else if (size < 0x100000) {
snprintf(sz, sizeof(sz), "%.1fk", (double) size / 1024.0);
} else if (size < 0x40000000) {
snprintf(sz, sizeof(sz), "%.1fM", (double) size / 1048576);
} else { } else {
free(d); snprintf(sz, sizeof(sz), "%.1fG", (double) size / 1073741824);
d = NULL;
} }
strftime(mod, sizeof(mod), "%d-%b-%Y %H:%M", localtime_r(&mtime, &t));
n = (int) mg_url_encode(name, strlen(name), path, sizeof(path));
mg_printf(d->c,
" <tr><td><a href=\"%.*s%s\">%s%s</a></td>"
"<td>%s</td><td>%s</td></tr>\n",
n, path, slash, name, slash, mod, sz);
} }
return d;
}
int closedir(DIR *d) {
int result = 0;
if (d != NULL) {
if (d->handle != INVALID_HANDLE_VALUE)
result = FindClose(d->handle) ? 0 : -1;
free(d);
} else {
result = -1;
SetLastError(ERROR_BAD_ARGUMENTS);
}
return result;
}
struct dirent *readdir(DIR *d) {
struct dirent *result = NULL;
if (d != NULL) {
memset(&d->result, 0, sizeof(d->result));
if (d->handle != INVALID_HANDLE_VALUE) {
result = &d->result;
WideCharToMultiByte(CP_UTF8, 0, d->info.cFileName, -1, result->d_name,
sizeof(result->d_name), NULL, NULL);
if (!FindNextFileW(d->handle, &d->info)) {
FindClose(d->handle);
d->handle = INVALID_HANDLE_VALUE;
}
} else {
SetLastError(ERROR_FILE_NOT_FOUND);
}
} else {
SetLastError(ERROR_BAD_ARGUMENTS);
}
return result;
}
#endif
static void printdirentry(struct mg_connection *c, const char *name,
mg_stat_t *stp) {
char size[64], mod[64], path[MG_PATH_MAX];
int is_dir = S_ISDIR(stp->st_mode), n = 0;
const char *slash = is_dir ? "/" : "";
struct tm t;
if (is_dir) {
snprintf(size, sizeof(size), "%s", "[DIR]");
} else {
if (stp->st_size < 1024) {
snprintf(size, sizeof(size), "%d", (int) stp->st_size);
} else if (stp->st_size < 0x100000) {
snprintf(size, sizeof(size), "%.1fk", (double) stp->st_size / 1024.0);
} else if (stp->st_size < 0x40000000) {
snprintf(size, sizeof(size), "%.1fM", (double) stp->st_size / 1048576);
} else {
snprintf(size, sizeof(size), "%.1fG", (double) stp->st_size / 1073741824);
}
}
strftime(mod, sizeof(mod), "%d-%b-%Y %H:%M", localtime_r(&stp->st_mtime, &t));
n = (int) mg_url_encode(name, strlen(name), path, sizeof(path));
mg_printf(c,
" <tr><td><a href=\"%.*s%s\">%s%s</a></td>"
"<td>%s</td><td>%s</td></tr>\n",
n, path, slash, name, slash, mod, size);
} }
static void listdir(struct mg_connection *c, struct mg_http_message *hm, static void listdir(struct mg_connection *c, struct mg_http_message *hm,
struct mg_http_serve_opts *opts, char *dir) { struct mg_http_serve_opts *opts, char *dir) {
char path[MG_PATH_MAX], *p = &dir[strlen(dir) - 1], tmp[10];
struct dirent *dp;
DIR *dirp;
static const char *sort_js_code = static const char *sort_js_code =
"<script>function srt(tb, sc, so, d) {" "<script>function srt(tb, sc, so, d) {"
"var tr = Array.prototype.slice.call(tb.rows, 0)," "var tr = Array.prototype.slice.call(tb.rows, 0),"
@@ -762,132 +650,129 @@ static void listdir(struct mg_connection *c, struct mg_http_message *hm,
"srt(tb, sc, so, true);" "srt(tb, sc, so, true);"
"}" "}"
"</script>"; "</script>";
struct mg_fs *fs = opts->fs == NULL ? &mg_fs_posix : opts->fs;
struct printdirentrydata d = {c, hm, opts, dir};
char tmp[10];
size_t off, n;
while (p > dir && *p != '/') *p-- = '\0'; mg_printf(c,
if ((dirp = (opendir(dir))) != NULL) { "HTTP/1.1 200 OK\r\n"
size_t off, n; "Content-Type: text/html; charset=utf-8\r\n"
mg_printf(c, "%s"
"HTTP/1.1 200 OK\r\n" "Content-Length: \r\n\r\n",
"Content-Type: text/html; charset=utf-8\r\n" opts->extra_headers == NULL ? "" : opts->extra_headers);
"%s" off = c->send.len; // Start of body
"Content-Length: \r\n\r\n", mg_printf(c,
opts->extra_headers == NULL ? "" : opts->extra_headers); "<!DOCTYPE html><html><head><title>Index of %.*s</title>%s%s"
off = c->send.len; // Start of body "<style>th,td {text-align: left; padding-right: 1em; "
mg_printf(c, "font-family: monospace; }</style></head>"
"<!DOCTYPE html><html><head><title>Index of %.*s</title>%s%s" "<body><h1>Index of %.*s</h1><table cellpadding=\"0\"><thead>"
"<style>th,td {text-align: left; padding-right: 1em; " "<tr><th><a href=\"#\" rel=\"0\">Name</a></th><th>"
"font-family: monospace; }</style></head>" "<a href=\"#\" rel=\"1\">Modified</a></th>"
"<body><h1>Index of %.*s</h1><table cellpadding=\"0\"><thead>" "<th><a href=\"#\" rel=\"2\">Size</a></th></tr>"
"<tr><th><a href=\"#\" rel=\"0\">Name</a></th><th>" "<tr><td colspan=\"3\"><hr></td></tr>"
"<a href=\"#\" rel=\"1\">Modified</a></th>" "</thead>"
"<th><a href=\"#\" rel=\"2\">Size</a></th></tr>" "<tbody id=\"tb\">\n",
"<tr><td colspan=\"3\"><hr></td></tr>" (int) hm->uri.len, hm->uri.ptr, sort_js_code, sort_js_code2,
"</thead>" (int) hm->uri.len, hm->uri.ptr);
"<tbody id=\"tb\">\n",
(int) hm->uri.len, hm->uri.ptr, sort_js_code, sort_js_code2,
(int) hm->uri.len, hm->uri.ptr);
while ((dp = readdir(dirp)) != NULL) { fs->list(dir, printdirentry, &d);
mg_stat_t st; mg_printf(c,
const char *sep = dp->d_name[0] == MG_DIRSEP ? "/" : ""; "</tbody><tfoot><tr><td colspan=\"3\"><hr></td></tr></tfoot>"
// Do not show current dir and hidden files "</table><address>Mongoose v.%s</address></body></html>\n",
if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) continue; MG_VERSION);
// SPIFFS can report "/foo.txt" in the dp->d_name n = (size_t) snprintf(tmp, sizeof(tmp), "%lu",
if (snprintf(path, sizeof(path), "%s%s%s", dir, sep, dp->d_name) < 0) { (unsigned long) (c->send.len - off));
LOG(LL_ERROR, ("%s truncated", dp->d_name)); if (n > sizeof(tmp)) n = 0;
} else if (mg_stat(path, &st) != 0) { memcpy(c->send.buf + off - 10, tmp, n); // Set content length
LOG(LL_ERROR, ("%lu stat(%s): %d", c->id, path, errno)); }
} else {
printdirentry(c, dp->d_name, &st); static void remove_double_dots(char *s) {
char *p = s;
while (*s != '\0') {
*p++ = *s++;
if (s[-1] == '/' || s[-1] == '\\') {
while (s[0] != '\0') {
if (s[0] == '/' || s[0] == '\\') {
s++;
} else if (s[0] == '.' && s[1] == '.') {
s += 2;
} else {
break;
}
} }
} }
closedir(dirp);
mg_printf(c,
"</tbody><tfoot><tr><td colspan=\"3\"><hr></td></tr></tfoot>"
"</table><address>Mongoose v.%s</address></body></html>\n",
MG_VERSION);
n = (size_t) snprintf(tmp, sizeof(tmp), "%lu",
(unsigned long) (c->send.len - off));
if (n > sizeof(tmp)) n = 0;
memcpy(c->send.buf + off - 10, tmp, n); // Set content length
} else {
mg_http_reply(c, 400, "", "Cannot open dir");
LOG(LL_ERROR, ("%lu opendir(%s) -> %d", c->id, dir, errno));
} }
*p = '\0';
}
// Resolve requested file into `path` and return its fs->stat() result
static int uri_to_path2(struct mg_connection *c, struct mg_http_message *hm,
struct mg_fs *fs, struct mg_str url, struct mg_str dir,
char *path, size_t path_size) {
int flags = 0, tmp;
// Append URI to the root_dir, and sanitize it
size_t n = (size_t) snprintf(path, path_size, "%.*s", (int) dir.len, dir.ptr);
if (n > path_size) n = path_size;
path[path_size - 1] = '\0';
if ((fs->stat(path, NULL, NULL) & MG_FS_DIR) == 0) {
mg_http_reply(c, 400, "", "Invalid web root [%.*s]\n", (int) dir.len,
dir.ptr);
} else {
if (n + 2 < path_size) path[n++] = '/', path[n] = '\0';
mg_url_decode(hm->uri.ptr + url.len, hm->uri.len - url.len, path + n,
path_size - n, 0);
path[path_size - 1] = '\0'; // Double-check
remove_double_dots(path);
n = strlen(path);
LOG(LL_DEBUG, ("--> %s", path));
while (n > 0 && path[n - 1] == '/') path[--n] = 0; // Trim trailing slashes
flags = fs->stat(path, NULL, NULL); // Does it exist?
if (flags == 0) {
mg_http_reply(c, 404, "", "Not found\n"); // Does not exist, doh
} else if (flags & MG_FS_DIR) {
if (((snprintf(path + n, path_size - n, "/index.html") > 0 &&
(tmp = fs->stat(path, NULL, NULL)) != 0) ||
(snprintf(path + n, path_size - n, "/index.shtml") > 0 &&
(tmp = fs->stat(path, NULL, NULL)) != 0))) {
flags = tmp;
} else {
path[n] = '\0'; // Remove appended index file name
}
}
}
return flags;
}
static int uri_to_path(struct mg_connection *c, struct mg_http_message *hm,
struct mg_http_serve_opts *opts, char *path,
size_t path_size) {
struct mg_fs *fs = opts->fs == NULL ? &mg_fs_posix : opts->fs;
struct mg_str k, v, s = mg_str(opts->root_dir), u = {0, 0}, p = {0, 0};
while (mg_commalist(&s, &k, &v)) {
if (v.len == 0) v = k, k = mg_str("/");
if (hm->uri.len < k.len) continue;
if (mg_strcmp(k, mg_str_n(hm->uri.ptr, k.len)) != 0) continue;
u = k, p = v;
}
return uri_to_path2(c, hm, fs, u, p, path, path_size);
} }
#endif
void mg_http_serve_dir(struct mg_connection *c, struct mg_http_message *hm, void mg_http_serve_dir(struct mg_connection *c, struct mg_http_message *hm,
struct mg_http_serve_opts *opts) { struct mg_http_serve_opts *opts) {
char t1[MG_PATH_MAX], t2[sizeof(t1)]; char path[MG_PATH_MAX] = "";
t1[0] = t2[0] = '\0'; const char *sp = opts->ssi_pattern;
int flags = uri_to_path(c, hm, opts, path, sizeof(path));
if (realpath(opts->root_dir, t1) == NULL) { if (flags == 0) return;
LOG(LL_ERROR, ("realpath(%s): %d", opts->root_dir, errno)); LOG(LL_DEBUG, ("%.*s %s %d", (int) hm->uri.len, hm->uri.ptr, path, flags));
mg_http_reply(c, 400, "", "Bad web root [%s]\n", opts->root_dir); if (flags & MG_FS_DIR) {
} else if (!mg_is_dir(t1)) { listdir(c, hm, opts, path);
mg_http_reply(c, 400, "", "Invalid web root [%s]\n", t1); } else if (sp != NULL && mg_globmatch(sp, strlen(sp), path, strlen(path))) {
mg_http_serve_ssi(c, opts->root_dir, path);
} else { } else {
// NOTE(lsm): Xilinx snprintf does not 0-terminate the detination for mg_http_serve_file(c, hm, path, opts);
// the %.*s specifier, if the length is zero. Make sure hm->uri.len > 0
bool is_index = false;
size_t n1 = strlen(t1), n2;
mg_url_decode(hm->uri.ptr, hm->uri.len, t1 + n1, sizeof(t1) - n1, 0);
t1[sizeof(t1) - 1] = '\0';
n2 = strlen(t1);
while (n2 > 0 && t1[n2 - 1] == '/') t1[--n2] = 0;
if (realpath(t1, t2) == NULL) {
LOG(LL_ERROR, ("realpath(%s): %d", t1, errno));
mg_http_reply(c, 404, "", "Not found [%.*s]\n", (int) hm->uri.len,
hm->uri.ptr);
return;
}
if (mg_is_dir(t2)) {
strncat(t2, "/index.html", sizeof(t2) - strlen(t2) - 1);
t2[sizeof(t2) - 1] = '\0';
is_index = true;
}
if (strlen(t2) < n1 || memcmp(t1, t2, n1) != 0) {
// Requested file is located outside root directory, fail
mg_http_reply(c, 404, "", "Invalid URI [%.*s]\n", (int) hm->uri.len,
hm->uri.ptr);
} else {
FILE *fp = fopen(t2, "r");
#if MG_ENABLE_SSI
if (is_index && fp == NULL) {
char *p = t2 + strlen(t2);
while (p > t2 && p[-1] != '/') p--;
strncpy(p, "index.shtml", (size_t)(&t2[sizeof(t2)] - p - 2));
t2[sizeof(t2) - 1] = '\0';
fp = fopen(t2, "r");
}
#endif
if (is_index && fp == NULL) {
#if MG_ENABLE_DIRECTORY_LISTING
listdir(c, hm, opts, t2);
#else
mg_http_reply(c, 403, "", "%s", "Directory listing not supported");
#endif
#if MG_ENABLE_SSI
} else if (opts->ssi_pattern != NULL &&
mg_globmatch(opts->ssi_pattern, strlen(opts->ssi_pattern), t2,
strlen(t2))) {
t1[n1] = '\0';
mg_http_serve_ssi(c, t1, t2);
#endif
} else {
mg_http_serve_file(c, hm, t2, guess_content_type(t2),
opts->extra_headers);
}
if (fp != NULL) fclose(fp);
}
} }
} }
#endif
static bool mg_is_url_safe(int c) { static bool mg_is_url_safe(int c) {
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') ||
@@ -947,7 +832,7 @@ struct mg_str mg_http_get_header_var(struct mg_str s, struct mg_str v) {
while (p < x && (q ? p == b || *p != '"' : *p != ';' && *p != ' ')) p++; while (p < x && (q ? p == b || *p != '"' : *p != ';' && *p != ' ')) p++;
// LOG(LL_INFO, ("[%.*s] [%.*s] [%.*s]", (int) s.len, s.ptr, (int) v.len, // LOG(LL_INFO, ("[%.*s] [%.*s] [%.*s]", (int) s.len, s.ptr, (int) v.len,
// v.ptr, (int) (p - b), b)); // v.ptr, (int) (p - b), b));
return stripquotes(mg_str_n(b, (size_t)(p - b + q))); return stripquotes(mg_str_n(b, (size_t) (p - b + q)));
} }
} }
return mg_str_n(NULL, 0); return mg_str_n(NULL, 0);
@@ -990,7 +875,7 @@ static void walkchunks(struct mg_connection *c, struct mg_http_message *hm,
char *buf2 = (char *) &c->recv.buf[reqlen]; char *buf2 = (char *) &c->recv.buf[reqlen];
size_t memo2 = c->recv.len; size_t memo2 = c->recv.len;
size_t cl2 = get_chunk_length(&buf2[off], memo2 - reqlen - off, &ll); size_t cl2 = get_chunk_length(&buf2[off], memo2 - reqlen - off, &ll);
size_t n = cl < ll + 2 ? 0 : cl2 - ll - 2; size_t n = cl2 < ll + 2 ? 0 : cl2 - ll - 2;
memmove(buf2 + bl, buf2 + off + ll, n); memmove(buf2 + bl, buf2 + off + ll, n);
bl += n; bl += n;
off += cl2; off += cl2;
@@ -1022,9 +907,9 @@ void mg_http_delete_chunk(struct mg_connection *c, struct mg_http_message *hm) {
} }
{ {
const char *end = &ch.ptr[ch.len]; const char *end = &ch.ptr[ch.len];
size_t n = (size_t)(end - (char *) c->recv.buf); size_t n = (size_t) (end - (char *) c->recv.buf);
if (c->recv.len > n) { if (c->recv.len > n) {
memmove((char *) ch.ptr, end, (size_t)(c->recv.len - n)); memmove((char *) ch.ptr, end, (size_t) (c->recv.len - n));
} }
// LOG(LL_INFO, ("DELETING CHUNK: %zu %zu %zu\n%.*s", c->recv.len, n, // LOG(LL_INFO, ("DELETING CHUNK: %zu %zu %zu\n%.*s", c->recv.len, n,
// ch.len, (int) ch.len, ch.ptr)); // ch.len, (int) ch.len, ch.ptr));
@@ -1040,7 +925,7 @@ static void http_cb(struct mg_connection *c, int ev, void *evd, void *fnd) {
bool is_chunked = n > 0 && mg_is_chunked(&hm); bool is_chunked = n > 0 && mg_is_chunked(&hm);
if (ev == MG_EV_CLOSE) { if (ev == MG_EV_CLOSE) {
hm.message.len = c->recv.len; hm.message.len = c->recv.len;
hm.body.len = hm.message.len - (size_t)(hm.body.ptr - hm.message.ptr); hm.body.len = hm.message.len - (size_t) (hm.body.ptr - hm.message.ptr);
} else if (is_chunked && n > 0) { } else if (is_chunked && n > 0) {
walkchunks(c, &hm, (size_t) n); walkchunks(c, &hm, (size_t) n);
} }
@@ -1051,7 +936,7 @@ static void http_cb(struct mg_connection *c, int ev, void *evd, void *fnd) {
break; break;
} else if (n > 0 && (size_t) c->recv.len >= hm.message.len) { } else if (n > 0 && (size_t) c->recv.len >= hm.message.len) {
mg_call(c, MG_EV_HTTP_MSG, &hm); mg_call(c, MG_EV_HTTP_MSG, &hm);
mg_iobuf_delete(&c->recv, hm.message.len); mg_iobuf_del(&c->recv, 0, hm.message.len);
} else { } else {
if (n > 0 && !is_chunked) { if (n > 0 && !is_chunked) {
hm.chunk = hm.chunk =
+11 -12
View File
@@ -1,18 +1,16 @@
#pragma once #pragma once
#include "config.h" #include "config.h"
#include "fs.h"
#include "net.h" #include "net.h"
#include "str.h" #include "str.h"
struct mg_http_header { struct mg_http_header {
struct mg_str name; struct mg_str name; // Header name
struct mg_str value; struct mg_str value; // Header value
}; };
struct mg_http_message { struct mg_http_message {
// GET /foo/bar/baz?aa=b&cc=ddd HTTP/1.1
// method |-| |----uri---| |--query--| |proto-|
struct mg_str method, uri, query, proto; // Request/response line struct mg_str method, uri, query, proto; // Request/response line
struct mg_http_header headers[MG_MAX_HTTP_HEADERS]; // Headers struct mg_http_header headers[MG_MAX_HTTP_HEADERS]; // Headers
struct mg_str body; // Body struct mg_str body; // Body
@@ -23,9 +21,11 @@ struct mg_http_message {
// Parameter for mg_http_serve_dir() // Parameter for mg_http_serve_dir()
struct mg_http_serve_opts { struct mg_http_serve_opts {
const char *root_dir; // Web root directory, must be non-NULL const char *root_dir; // Web root directory, must be non-NULL
const char *ssi_pattern; // SSI file name pattern, e.g. #.shtml const char *ssi_pattern; // SSI file name pattern, e.g. #.shtml
const char *extra_headers; // Extra HTTP headers to add in responses const char *extra_headers; // Extra HTTP headers to add in responses
const char *mime_types; // Extra mime types, ext1=type1,ext2=type2,..
struct mg_fs *fs; // Filesystem implementation. Use NULL for POSIX
}; };
// Parameter for mg_http_next_multipart // Parameter for mg_http_next_multipart
@@ -45,13 +45,12 @@ struct mg_connection *mg_http_listen(struct mg_mgr *, const char *url,
struct mg_connection *mg_http_connect(struct mg_mgr *, const char *url, struct mg_connection *mg_http_connect(struct mg_mgr *, const char *url,
mg_event_handler_t fn, void *fn_data); mg_event_handler_t fn, void *fn_data);
void mg_http_serve_dir(struct mg_connection *, struct mg_http_message *hm, void mg_http_serve_dir(struct mg_connection *, struct mg_http_message *hm,
struct mg_http_serve_opts *); struct mg_http_serve_opts *opts);
void mg_http_serve_file(struct mg_connection *, struct mg_http_message *, void mg_http_serve_file(struct mg_connection *, struct mg_http_message *hm,
const char *, const char *mime, const char *headers); const char *path, struct mg_http_serve_opts *opts);
void mg_http_reply(struct mg_connection *, int status_code, const char *headers, void mg_http_reply(struct mg_connection *, int status_code, const char *headers,
const char *body_fmt, ...); const char *body_fmt, ...);
struct mg_str *mg_http_get_header(struct mg_http_message *, const char *name); struct mg_str *mg_http_get_header(struct mg_http_message *, const char *name);
void mg_http_event_handler(struct mg_connection *c, int ev);
int mg_http_get_var(const struct mg_str *, const char *name, char *, size_t); int mg_http_get_var(const struct mg_str *, const char *name, char *, size_t);
int mg_url_decode(const char *s, size_t n, char *to, size_t to_len, int form); int mg_url_decode(const char *s, size_t n, char *to, size_t to_len, int form);
size_t mg_url_encode(const char *s, size_t n, char *buf, size_t len); size_t mg_url_encode(const char *s, size_t n, char *buf, size_t len);
+9 -6
View File
@@ -42,8 +42,8 @@ int mg_iobuf_init(struct mg_iobuf *io, size_t size) {
return mg_iobuf_resize(io, size); return mg_iobuf_resize(io, size);
} }
size_t mg_iobuf_append(struct mg_iobuf *io, const void *buf, size_t len, size_t mg_iobuf_add(struct mg_iobuf *io, size_t ofs, const void *buf,
size_t chunk_size) { size_t len, size_t chunk_size) {
size_t new_size = io->len + len; size_t new_size = io->len + len;
if (new_size > io->size) { if (new_size > io->size) {
new_size += chunk_size; // Make sure that io->size new_size += chunk_size; // Make sure that io->size
@@ -51,14 +51,17 @@ size_t mg_iobuf_append(struct mg_iobuf *io, const void *buf, size_t len,
mg_iobuf_resize(io, new_size); // Attempt to realloc mg_iobuf_resize(io, new_size); // Attempt to realloc
if (new_size != io->size) len = 0; // Realloc failure, append nothing if (new_size != io->size) len = 0; // Realloc failure, append nothing
} }
if (buf != NULL) memmove(io->buf + io->len, buf, len); if (ofs < io->len) memmove(io->buf + ofs + len, io->buf + ofs, io->len - ofs);
if (buf != NULL) memmove(io->buf + ofs, buf, len);
if (ofs > io->len) io->len += ofs - io->len;
io->len += len; io->len += len;
return len; return len;
} }
size_t mg_iobuf_delete(struct mg_iobuf *io, size_t len) { size_t mg_iobuf_del(struct mg_iobuf *io, size_t ofs, size_t len) {
if (len > io->len) len = 0; if (ofs > io->len) ofs = io->len;
memmove(io->buf, io->buf + len, io->len - len); if (ofs + len > io->len) len = io->len - ofs;
memmove(io->buf + ofs, io->buf + ofs + len, io->len - ofs - len);
zeromem(io->buf + io->len - len, len); zeromem(io->buf + io->len - len, len);
io->len -= len; io->len -= len;
return len; return len;
+5 -4
View File
@@ -3,12 +3,13 @@
#include <stddef.h> #include <stddef.h>
struct mg_iobuf { struct mg_iobuf {
unsigned char *buf; unsigned char *buf; // Pointer to stored data
size_t size, len; size_t size; // Total size available
size_t len; // Current number of bytes
}; };
int mg_iobuf_init(struct mg_iobuf *, size_t); int mg_iobuf_init(struct mg_iobuf *, size_t);
int mg_iobuf_resize(struct mg_iobuf *, size_t); int mg_iobuf_resize(struct mg_iobuf *, size_t);
void mg_iobuf_free(struct mg_iobuf *); void mg_iobuf_free(struct mg_iobuf *);
size_t mg_iobuf_append(struct mg_iobuf *, const void *, size_t, size_t); size_t mg_iobuf_add(struct mg_iobuf *, size_t, const void *, size_t, size_t);
size_t mg_iobuf_delete(struct mg_iobuf *, size_t); size_t mg_iobuf_del(struct mg_iobuf *, size_t ofs, size_t len);
+4 -7
View File
@@ -1,8 +1,6 @@
#include "log.h" #include "log.h"
#include "util.h" #include "util.h"
#if MG_ENABLE_MGOS
#else
#if MG_ENABLE_LOG #if MG_ENABLE_LOG
static void mg_log_stdout(const void *buf, size_t len, void *userdata) { static void mg_log_stdout(const void *buf, size_t len, void *userdata) {
(void) userdata; (void) userdata;
@@ -29,7 +27,7 @@ bool mg_log_prefix(int level, const char *file, int line, const char *fname) {
if (p == NULL) p = strrchr(file, '\\'); if (p == NULL) p = strrchr(file, '\\');
p = p == NULL ? file : p + 1; p = p == NULL ? file : p + 1;
while (mg_next_comma_entry(&s, &k, &v)) { while (mg_commalist(&s, &k, &v)) {
if (v.len == 0) max = atoi(k.ptr); if (v.len == 0) max = atoi(k.ptr);
if (v.len > 0 && strncmp(p, k.ptr, k.len) == 0) max = atoi(v.ptr); if (v.len > 0 && strncmp(p, k.ptr, k.len) == 0) max = atoi(v.ptr);
} }
@@ -38,10 +36,10 @@ bool mg_log_prefix(int level, const char *file, int line, const char *fname) {
char timebuf[21], buf[50] = ""; char timebuf[21], buf[50] = "";
time_t t = time(NULL); time_t t = time(NULL);
struct tm tmp, *tm = gmtime_r(&t, &tmp); struct tm tmp, *tm = gmtime_r(&t, &tmp);
int n, tag; int n;
(void) tmp;
strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", tm); strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", tm);
tag = level == LL_ERROR ? 'E' : level == LL_INFO ? 'I' : ' '; n = snprintf(buf, sizeof(buf), "%s %d %s:%d:%s", timebuf, level, p, line,
n = snprintf(buf, sizeof(buf), "%s %c %s:%d:%s", timebuf, tag, p, line,
fname); fname);
if (n < 0 || n > (int) sizeof(buf) - 2) n = sizeof(buf) - 2; if (n < 0 || n > (int) sizeof(buf) - 2) n = sizeof(buf) - 2;
while (n < (int) sizeof(buf) - 1) buf[n++] = ' '; while (n < (int) sizeof(buf) - 1) buf[n++] = ' ';
@@ -69,4 +67,3 @@ void mg_log_set_callback(void (*fn)(const void *, size_t, void *), void *fnd) {
s_fn_param = fnd; s_fn_param = fnd;
} }
#endif #endif
#endif
+18 -18
View File
@@ -20,24 +20,24 @@ enum { MQTT_OK, MQTT_INCOMPLETE, MQTT_MALFORMED };
void mg_mqtt_send_header(struct mg_connection *c, uint8_t cmd, uint8_t flags, void mg_mqtt_send_header(struct mg_connection *c, uint8_t cmd, uint8_t flags,
uint32_t len) { uint32_t len) {
uint8_t buf[1 + sizeof(len)], *vlen = &buf[1]; uint8_t buf[1 + sizeof(len)], *vlen = &buf[1];
buf[0] = (uint8_t)((cmd << 4) | flags); buf[0] = (uint8_t) ((cmd << 4) | flags);
do { do {
*vlen = len % 0x80; *vlen = len % 0x80;
len /= 0x80; len /= 0x80;
if (len > 0) *vlen |= 0x80; if (len > 0) *vlen |= 0x80;
vlen++; vlen++;
} while (len > 0 && vlen < &buf[sizeof(buf)]); } while (len > 0 && vlen < &buf[sizeof(buf)]);
mg_send(c, buf, (size_t)(vlen - buf)); mg_send(c, buf, (size_t) (vlen - buf));
} }
static void mg_send_u16(struct mg_connection *c, uint16_t value) { static void mg_send_u16(struct mg_connection *c, uint16_t value) {
mg_send(c, &value, sizeof(value)); mg_send(c, &value, sizeof(value));
} }
static void mqtt_login(struct mg_connection *c, const char *url, void mg_mqtt_login(struct mg_connection *c, const char *url,
struct mg_mqtt_opts *opts) { struct mg_mqtt_opts *opts) {
uint32_t total_len = 7 + 1 + 2 + 2; uint32_t total_len = 7 + 1 + 2 + 2;
uint16_t flags = (uint16_t)(((uint16_t) opts->qos & 3) << 3); uint16_t flags = (uint16_t) (((uint16_t) opts->qos & 3) << 3);
struct mg_str user = mg_url_user(url); struct mg_str user = mg_url_user(url);
struct mg_str pass = mg_url_pass(url); struct mg_str pass = mg_url_pass(url);
@@ -83,7 +83,7 @@ static void mqtt_login(struct mg_connection *c, const char *url,
void mg_mqtt_pub(struct mg_connection *c, struct mg_str *topic, void mg_mqtt_pub(struct mg_connection *c, struct mg_str *topic,
struct mg_str *data, int qos, bool retain) { struct mg_str *data, int qos, bool retain) {
uint8_t flags = (uint8_t)(((qos & 3) << 1) | (retain ? 1 : 0)); uint8_t flags = (uint8_t) (((qos & 3) << 1) | (retain ? 1 : 0));
uint32_t total_len = 2 + (uint32_t) topic->len + (uint32_t) data->len; uint32_t total_len = 2 + (uint32_t) topic->len + (uint32_t) data->len;
LOG(LL_DEBUG, ("%lu [%.*s] -> [%.*s]", c->id, (int) topic->len, LOG(LL_DEBUG, ("%lu [%.*s] -> [%.*s]", c->id, (int) topic->len,
(char *) topic->ptr, (int) data->len, (char *) data->ptr)); (char *) topic->ptr, (int) data->len, (char *) data->ptr));
@@ -119,21 +119,21 @@ int mg_mqtt_parse(const uint8_t *buf, size_t len, struct mg_mqtt_message *m) {
memset(m, 0, sizeof(*m)); memset(m, 0, sizeof(*m));
m->dgram.ptr = (char *) buf; m->dgram.ptr = (char *) buf;
if (len < 2) return MQTT_INCOMPLETE; if (len < 2) return MQTT_INCOMPLETE;
m->cmd = (uint8_t)(buf[0] >> 4); m->cmd = (uint8_t) (buf[0] >> 4);
m->qos = (buf[0] >> 1) & 3; m->qos = (buf[0] >> 1) & 3;
n = len_len = 0; n = len_len = 0;
p = (uint8_t *) buf + 1; p = (uint8_t *) buf + 1;
while ((size_t)(p - buf) < len) { while ((size_t) (p - buf) < len) {
lc = *((uint8_t *) p++); lc = *((uint8_t *) p++);
n += (uint32_t)((lc & 0x7f) << 7 * len_len); n += (uint32_t) ((lc & 0x7f) << 7 * len_len);
len_len++; len_len++;
if (!(lc & 0x80)) break; if (!(lc & 0x80)) break;
if (len_len >= 4) return MQTT_MALFORMED; if (len_len >= 4) return MQTT_MALFORMED;
} }
end = p + n; end = p + n;
if (lc & 0x80 || end > buf + len) return MQTT_INCOMPLETE; if (lc & 0x80 || end > buf + len) return MQTT_INCOMPLETE;
m->dgram.len = (size_t)(end - buf); m->dgram.len = (size_t) (end - buf);
switch (m->cmd) { switch (m->cmd) {
case MQTT_CMD_CONNACK: case MQTT_CMD_CONNACK:
@@ -146,28 +146,28 @@ int mg_mqtt_parse(const uint8_t *buf, size_t len, struct mg_mqtt_message *m) {
case MQTT_CMD_PUBCOMP: case MQTT_CMD_PUBCOMP:
case MQTT_CMD_SUBACK: case MQTT_CMD_SUBACK:
if (p + 2 > end) return MQTT_MALFORMED; if (p + 2 > end) return MQTT_MALFORMED;
m->id = (uint16_t)((((uint16_t) p[0]) << 8) | p[1]); m->id = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]);
break; break;
case MQTT_CMD_SUBSCRIBE: { case MQTT_CMD_SUBSCRIBE: {
if (p + 2 > end) return MQTT_MALFORMED; if (p + 2 > end) return MQTT_MALFORMED;
m->id = (uint16_t)((((uint16_t) p[0]) << 8) | p[1]); m->id = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]);
p += 2; p += 2;
break; break;
} }
case MQTT_CMD_PUBLISH: { case MQTT_CMD_PUBLISH: {
if (p + 2 > end) return MQTT_MALFORMED; if (p + 2 > end) return MQTT_MALFORMED;
m->topic.len = (uint16_t)((((uint16_t) p[0]) << 8) | p[1]); m->topic.len = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]);
m->topic.ptr = (char *) p + 2; m->topic.ptr = (char *) p + 2;
p += 2 + m->topic.len; p += 2 + m->topic.len;
if (p > end) return MQTT_MALFORMED; if (p > end) return MQTT_MALFORMED;
if (m->qos > 0) { if (m->qos > 0) {
if (p + 2 > end) return MQTT_MALFORMED; if (p + 2 > end) return MQTT_MALFORMED;
m->id = (uint16_t)((((uint16_t) p[0]) << 8) | p[1]); m->id = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]);
p += 2; p += 2;
} }
if (p > end) return MQTT_MALFORMED; if (p > end) return MQTT_MALFORMED;
m->data.ptr = (char *) p; m->data.ptr = (char *) p;
m->data.len = (size_t)(end - p); m->data.len = (size_t) (end - p);
break; break;
} }
default: default:
@@ -183,7 +183,7 @@ static size_t mg_mqtt_next_topic(struct mg_mqtt_message *msg,
size_t new_pos; size_t new_pos;
if (pos >= msg->dgram.len) return 0; if (pos >= msg->dgram.len) return 0;
topic->len = (size_t)(((unsigned) buf[0]) << 8 | buf[1]); topic->len = (size_t) (((unsigned) buf[0]) << 8 | buf[1]);
topic->ptr = (char *) buf + 2; topic->ptr = (char *) buf + 2;
new_pos = pos + 2 + topic->len + (qos == NULL ? 0 : 1); new_pos = pos + 2 + topic->len + (qos == NULL ? 0 : 1);
if ((size_t) new_pos > msg->dgram.len) return 0; if ((size_t) new_pos > msg->dgram.len) return 0;
@@ -234,7 +234,7 @@ static void mqtt_cb(struct mg_connection *c, int ev, void *ev_data,
} }
} }
mg_call(c, MG_EV_MQTT_CMD, &mm); mg_call(c, MG_EV_MQTT_CMD, &mm);
mg_iobuf_delete(&c->recv, mm.dgram.len); mg_iobuf_del(&c->recv, 0, mm.dgram.len);
} else { } else {
break; break;
} }
@@ -263,7 +263,7 @@ struct mg_connection *mg_mqtt_connect(struct mg_mgr *mgr, const char *url,
if (c != NULL) { if (c != NULL) {
struct mg_mqtt_opts empty; struct mg_mqtt_opts empty;
memset(&empty, 0, sizeof(empty)); memset(&empty, 0, sizeof(empty));
mqtt_login(c, url, opts == NULL ? &empty : opts); mg_mqtt_login(c, url, opts == NULL ? &empty : opts);
c->pfn = mqtt_cb; c->pfn = mqtt_cb;
} }
return c; return c;
+9 -7
View File
@@ -23,13 +23,13 @@
#define MQTT_SET_QOS(flags, qos) (flags) = ((flags) & ~0x6) | ((qos) << 1) #define MQTT_SET_QOS(flags, qos) (flags) = ((flags) & ~0x6) | ((qos) << 1)
struct mg_mqtt_opts { struct mg_mqtt_opts {
struct mg_str client_id; struct mg_str client_id; // Client ID
struct mg_str will_topic; struct mg_str will_topic; // Will topic
struct mg_str will_message; struct mg_str will_message; // Will message
uint8_t qos; // Quality of service uint8_t qos; // Quality of service
bool will_retain; // Retain last will bool will_retain; // Retain last will
bool clean; // Use clean session, 0 or 1 bool clean; // Use clean session, 0 or 1
uint16_t keepalive; // Keep-alive timer in seconds uint16_t keepalive; // Keep-alive timer in seconds
}; };
struct mg_mqtt_message { struct mg_mqtt_message {
@@ -47,6 +47,8 @@ struct mg_connection *mg_mqtt_connect(struct mg_mgr *, const char *url,
mg_event_handler_t fn, void *fn_data); mg_event_handler_t fn, void *fn_data);
struct mg_connection *mg_mqtt_listen(struct mg_mgr *mgr, const char *url, struct mg_connection *mg_mqtt_listen(struct mg_mgr *mgr, const char *url,
mg_event_handler_t fn, void *fn_data); mg_event_handler_t fn, void *fn_data);
void mg_mqtt_login(struct mg_connection *c, const char *url,
struct mg_mqtt_opts *opts);
void mg_mqtt_pub(struct mg_connection *c, struct mg_str *topic, void mg_mqtt_pub(struct mg_connection *c, struct mg_str *topic,
struct mg_str *data, int qos, bool retain); struct mg_str *data, int qos, bool retain);
void mg_mqtt_sub(struct mg_connection *, struct mg_str *topic, int qos); void mg_mqtt_sub(struct mg_connection *, struct mg_str *topic, int qos);
+19 -2
View File
@@ -70,8 +70,25 @@ static bool mg_aton4(struct mg_str str, struct mg_addr *addr) {
return true; return true;
} }
static bool mg_v4mapped(struct mg_str str, struct mg_addr *addr) {
int i;
if (str.len < 14) return false;
if (str.ptr[0] != ':' || str.ptr[1] != ':' || str.ptr[6] != ':') return false;
for (i = 2; i < 6; i++) {
if (str.ptr[i] != 'f' && str.ptr[i] != 'F') return false;
}
if (!mg_aton4(mg_str_n(&str.ptr[7], str.len - 7), addr)) return false;
memset(addr->ip6, 0, sizeof(addr->ip6));
addr->ip6[10] = addr->ip6[11] = 255;
memcpy(&addr->ip6[12], &addr->ip, 4);
addr->is_ip6 = true;
return true;
}
static bool mg_aton6(struct mg_str str, struct mg_addr *addr) { static bool mg_aton6(struct mg_str str, struct mg_addr *addr) {
size_t i, j = 0, n = 0, dc = 42; size_t i, j = 0, n = 0, dc = 42;
if (str.len > 2 && str.ptr[0] == '[') str.ptr++, str.len -= 2;
if (mg_v4mapped(str, addr)) return true;
for (i = 0; i < str.len; i++) { for (i = 0; i < str.len; i++) {
if ((str.ptr[i] >= '0' && str.ptr[i] <= '9') || if ((str.ptr[i] >= '0' && str.ptr[i] <= '9') ||
(str.ptr[i] >= 'a' && str.ptr[i] <= 'f') || (str.ptr[i] >= 'a' && str.ptr[i] <= 'f') ||
@@ -81,8 +98,8 @@ static bool mg_aton6(struct mg_str str, struct mg_addr *addr) {
// LOG(LL_DEBUG, ("%zu %zu [%.*s]", i, j, (int) (i - j + 1), // LOG(LL_DEBUG, ("%zu %zu [%.*s]", i, j, (int) (i - j + 1),
// &str.ptr[j])); // &str.ptr[j]));
val = mg_unhexn(&str.ptr[j], i - j + 1); val = mg_unhexn(&str.ptr[j], i - j + 1);
addr->ip6[n] = (uint8_t)((val >> 8) & 255); addr->ip6[n] = (uint8_t) ((val >> 8) & 255);
addr->ip6[n + 1] = (uint8_t)(val & 255); addr->ip6[n + 1] = (uint8_t) (val & 255);
} else if (str.ptr[i] == ':') { } else if (str.ptr[i] == ':') {
j = i + 1; j = i + 1;
if (i > 0 && str.ptr[i - 1] == ':') { if (i > 0 && str.ptr[i - 1] == ':') {
+3 -1
View File
@@ -71,6 +71,8 @@ bool mg_send(struct mg_connection *, const void *, size_t);
int mg_printf(struct mg_connection *, const char *fmt, ...); int mg_printf(struct mg_connection *, const char *fmt, ...);
int mg_vprintf(struct mg_connection *, const char *fmt, va_list ap); int mg_vprintf(struct mg_connection *, const char *fmt, va_list ap);
char *mg_straddr(struct mg_connection *, char *, size_t); char *mg_straddr(struct mg_connection *, char *, size_t);
bool mg_socketpair(int *s1, int *s2);
bool mg_aton(struct mg_str str, struct mg_addr *addr); bool mg_aton(struct mg_str str, struct mg_addr *addr);
char *mg_ntoa(const struct mg_addr *addr, char *buf, size_t len); char *mg_ntoa(const struct mg_addr *addr, char *buf, size_t len);
struct mg_connection *mg_mkpipe(struct mg_mgr *, mg_event_handler_t, void *);
void mg_mgr_wakeup(struct mg_connection *pipe);
+4 -5
View File
@@ -1,11 +1,11 @@
#include "sntp.h"
#include "arch.h" #include "arch.h"
#include "event.h" #include "event.h"
#include "log.h" #include "log.h"
#include "sntp.h"
#include "util.h" #include "util.h"
#define SNTP_INTERVAL_SEC (3600) #define SNTP_INTERVAL_SEC (3600)
#define SNTP_TIME_OFFSET 2208988800 #define SNTP_TIME_OFFSET 2208988800UL
static unsigned long s_sntmp_next; static unsigned long s_sntmp_next;
@@ -21,7 +21,7 @@ int mg_sntp_parse(const unsigned char *buf, size_t len, struct timeval *tv) {
LOG(LL_ERROR, ("%s", "server sent a kiss of death")); LOG(LL_ERROR, ("%s", "server sent a kiss of death"));
} else { } else {
uint32_t *data = (uint32_t *) &buf[40]; uint32_t *data = (uint32_t *) &buf[40];
tv->tv_sec = mg_ntohl(data[0]) - SNTP_TIME_OFFSET; tv->tv_sec = (time_t) (mg_ntohl(data[0]) - SNTP_TIME_OFFSET);
tv->tv_usec = (suseconds_t) mg_ntohl(data[1]); tv->tv_usec = (suseconds_t) mg_ntohl(data[1]);
s_sntmp_next = (unsigned long) (tv->tv_sec + SNTP_INTERVAL_SEC); s_sntmp_next = (unsigned long) (tv->tv_sec + SNTP_INTERVAL_SEC);
res = 0; res = 0;
@@ -38,10 +38,9 @@ static void sntp_cb(struct mg_connection *c, int ev, void *evd, void *fnd) {
(unsigned) tv.tv_usec, s_sntmp_next)); (unsigned) tv.tv_usec, s_sntmp_next));
} }
c->recv.len = 0; // Clear receive buffer c->recv.len = 0; // Clear receive buffer
} else if (ev == MG_EV_RESOLVE) { } else if (ev == MG_EV_CONNECT) {
mg_sntp_send(c, (unsigned long) time(NULL)); mg_sntp_send(c, (unsigned long) time(NULL));
} else if (ev == MG_EV_CLOSE) { } else if (ev == MG_EV_CLOSE) {
// mg_fn_del(c, sntp_cb);
} }
(void) fnd; (void) fnd;
(void) evd; (void) evd;
+140 -141
View File
@@ -28,27 +28,17 @@ typedef Socket_t SOCKET;
typedef int SOCKET; typedef int SOCKET;
#endif #endif
union _su { #define FD(c_) ((SOCKET) (size_t) (c_)->fd)
SOCKET s; #define S2PTR(s_) ((void *) (size_t) (s_))
void *ptr;
};
#define FD(c_) ptr2sock((c_)->fd)
static SOCKET ptr2sock(void *ptr) {
union _su u = {0};
u.ptr = ptr;
return u.s;
}
static void *sock2ptr(SOCKET s) {
union _su u = {s};
return u.ptr;
}
#ifndef MSG_NONBLOCKING #ifndef MSG_NONBLOCKING
#define MSG_NONBLOCKING 0 #define MSG_NONBLOCKING 0
#endif #endif
#ifndef AF_INET6
#define AF_INET6 10
#endif
union usa { union usa {
struct sockaddr sa; struct sockaddr sa;
struct sockaddr_in sin; struct sockaddr_in sin;
@@ -57,20 +47,33 @@ union usa {
#endif #endif
}; };
static union usa tousa(struct mg_addr *a) { static socklen_t tousa(struct mg_addr *a, union usa *usa) {
union usa usa; socklen_t len = sizeof(usa->sin);
memset(&usa, 0, sizeof(usa)); memset(usa, 0, sizeof(*usa));
usa.sin.sin_family = AF_INET; usa->sin.sin_family = AF_INET;
usa.sin.sin_port = a->port; usa->sin.sin_port = a->port;
*(uint32_t *) &usa.sin.sin_addr = a->ip; *(uint32_t *) &usa->sin.sin_addr = a->ip;
#if MG_ENABLE_IPV6 #if MG_ENABLE_IPV6
if (a->is_ip6) { if (a->is_ip6) {
usa.sin.sin_family = AF_INET6; usa->sin.sin_family = AF_INET6;
usa.sin6.sin6_port = a->port; usa->sin6.sin6_port = a->port;
memcpy(&usa.sin6.sin6_addr, a->ip6, sizeof(a->ip6)); memcpy(&usa->sin6.sin6_addr, a->ip6, sizeof(a->ip6));
len = sizeof(usa->sin6);
}
#endif
return len;
}
static void tomgaddr(union usa *usa, struct mg_addr *a, bool is_ip6) {
a->is_ip6 = is_ip6;
a->port = usa->sin.sin_port;
memcpy(&a->ip, &usa->sin.sin_addr, sizeof(a->ip));
#if MG_ENABLE_IPV6
if (is_ip6) {
memcpy(a->ip6, &usa->sin6.sin6_addr, sizeof(a->ip6));
a->port = usa->sin6.sin6_port;
} }
#endif #endif
return usa;
} }
static bool mg_sock_would_block(void) { static bool mg_sock_would_block(void) {
@@ -90,7 +93,7 @@ static struct mg_connection *alloc_conn(struct mg_mgr *mgr, bool is_client,
struct mg_connection *c = (struct mg_connection *) calloc(1, sizeof(*c)); struct mg_connection *c = (struct mg_connection *) calloc(1, sizeof(*c));
if (c != NULL) { if (c != NULL) {
c->is_client = is_client; c->is_client = is_client;
c->fd = sock2ptr(fd); c->fd = S2PTR(fd);
c->mgr = mgr; c->mgr = mgr;
c->id = ++mgr->nextid; c->id = ++mgr->nextid;
} }
@@ -98,23 +101,13 @@ static struct mg_connection *alloc_conn(struct mg_mgr *mgr, bool is_client,
} }
static long mg_sock_send(struct mg_connection *c, const void *buf, size_t len) { static long mg_sock_send(struct mg_connection *c, const void *buf, size_t len) {
long n = 0; long n = send(FD(c), (char *) buf, len, MSG_NONBLOCKING);
if (c->is_udp) {
union usa usa = tousa(&c->peer);
socklen_t slen = sizeof(usa.sin);
#if MG_ENABLE_IPV6
if (c->peer.is_ip6) slen = sizeof(usa.sin6);
#endif
n = sendto(FD(c), (char *) buf, len, 0, &usa.sa, slen);
} else {
n = send(FD(c), (char *) buf, len, MSG_NONBLOCKING);
}
return n == 0 ? -1 : n < 0 && mg_sock_would_block() ? 0 : n; return n == 0 ? -1 : n < 0 && mg_sock_would_block() ? 0 : n;
} }
bool mg_send(struct mg_connection *c, const void *buf, size_t len) { bool mg_send(struct mg_connection *c, const void *buf, size_t len) {
return c->is_udp ? mg_sock_send(c, buf, len) > 0 return c->is_udp ? mg_sock_send(c, buf, len) > 0
: mg_iobuf_append(&c->send, buf, len, MG_IO_SIZE); : mg_iobuf_add(&c->send, c->send.len, buf, len, MG_IO_SIZE);
} }
static void mg_set_non_blocking_mode(SOCKET fd) { static void mg_set_non_blocking_mode(SOCKET fd) {
@@ -125,6 +118,10 @@ static void mg_set_non_blocking_mode(SOCKET fd) {
const BaseType_t off = 0; const BaseType_t off = 0;
setsockopt(fd, 0, FREERTOS_SO_RCVTIMEO, &off, sizeof(off)); setsockopt(fd, 0, FREERTOS_SO_RCVTIMEO, &off, sizeof(off));
setsockopt(fd, 0, FREERTOS_SO_SNDTIMEO, &off, sizeof(off)); setsockopt(fd, 0, FREERTOS_SO_SNDTIMEO, &off, sizeof(off));
#elif MG_ARCH == MG_ARCH_FREERTOS_LWIP
lwip_fcntl(fd, F_SETFL, O_NONBLOCK);
#elif MG_ARCH == MG_ARCH_AZURERTOS
fcntl(fd, F_SETFL, O_NONBLOCK);
#else #else
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK, FD_CLOEXEC); fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK, FD_CLOEXEC);
#endif #endif
@@ -132,29 +129,33 @@ static void mg_set_non_blocking_mode(SOCKET fd) {
SOCKET mg_open_listener(const char *url, struct mg_addr *addr) { SOCKET mg_open_listener(const char *url, struct mg_addr *addr) {
SOCKET fd = INVALID_SOCKET; SOCKET fd = INVALID_SOCKET;
int s_err = 0; // Memoized socket error, in case closesocket() overrides it
memset(addr, 0, sizeof(*addr)); memset(addr, 0, sizeof(*addr));
addr->port = mg_htons(mg_url_port(url)); addr->port = mg_htons(mg_url_port(url));
if (!mg_aton(mg_url_host(url), addr)) { if (!mg_aton(mg_url_host(url), addr)) {
LOG(LL_ERROR, ("invalid listening URL: %s", url)); LOG(LL_ERROR, ("invalid listening URL: %s", url));
} else { } else {
union usa usa = tousa(addr); union usa usa;
int on = 1, af = AF_INET; socklen_t slen = tousa(addr, &usa);
int on = 1, af = addr->is_ip6 ? AF_INET6 : AF_INET;
int type = strncmp(url, "udp:", 4) == 0 ? SOCK_DGRAM : SOCK_STREAM; int type = strncmp(url, "udp:", 4) == 0 ? SOCK_DGRAM : SOCK_STREAM;
int proto = type == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP; int proto = type == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP;
socklen_t slen = sizeof(usa.sin); (void) on;
#if MG_ENABLE_IPV6
if (addr->is_ip6) af = AF_INET6, slen = sizeof(usa.sin6);
#endif
if ((fd = socket(af, type, proto)) != INVALID_SOCKET && if ((fd = socket(af, type, proto)) != INVALID_SOCKET &&
#if !defined(_WIN32) || !defined(SO_EXCLUSIVEADDRUSE) #if (!defined(_WIN32) || !defined(SO_EXCLUSIVEADDRUSE)) && \
// SO_RESUSEADDR is not enabled on Windows because the semantics of (!defined(LWIP_SOCKET) || (defined(LWIP_SOCKET) && SO_REUSE == 1))
// SO_REUSEADDR on UNIX and Windows is different. On Windows, // 1. SO_RESUSEADDR is not enabled on Windows because the semantics of
// SO_REUSEADDR allows to bind a socket to a port without error even if // SO_REUSEADDR on UNIX and Windows is different. On Windows,
// the port is already open by another program. This is not the behavior // SO_REUSEADDR allows to bind a socket to a port without error even
// SO_REUSEADDR was designed for, and leads to hard-to-track failure // if the port is already open by another program. This is not the
// scenarios. Therefore, SO_REUSEADDR was disabled on Windows unless // behavior SO_REUSEADDR was designed for, and leads to hard-to-track
// SO_EXCLUSIVEADDRUSE is supported and set on a socket. // failure scenarios. Therefore, SO_REUSEADDR was disabled on Windows
// unless SO_EXCLUSIVEADDRUSE is supported and set on a socket.
// 2. In case of LWIP, SO_REUSEADDR should be explicitly enabled, by
// defining
// SO_REUSE (in lwipopts.h), otherwise the code below will compile
// but won't work! (setsockopt will return EINVAL)
!setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on)) && !setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on)) &&
#endif #endif
#if defined(_WIN32) && defined(SO_EXCLUSIVEADDRUSE) && !defined(WINCE) #if defined(_WIN32) && defined(SO_EXCLUSIVEADDRUSE) && !defined(WINCE)
@@ -166,7 +167,7 @@ SOCKET mg_open_listener(const char *url, struct mg_addr *addr) {
#endif #endif
bind(fd, &usa.sa, slen) == 0 && bind(fd, &usa.sa, slen) == 0 &&
// NOTE(lsm): FreeRTOS uses backlog value as a connection limit // NOTE(lsm): FreeRTOS uses backlog value as a connection limit
(type == SOCK_DGRAM || listen(fd, 128) == 0)) { (type == SOCK_DGRAM || listen(fd, MG_SOCK_LISTEN_BACKLOG_SIZE) == 0)) {
// In case port was set to 0, get the real port number // In case port was set to 0, get the real port number
if (getsockname(fd, &usa.sa, &slen) == 0) { if (getsockname(fd, &usa.sa, &slen) == 0) {
addr->port = usa.sin.sin_port; addr->port = usa.sin.sin_port;
@@ -176,12 +177,14 @@ SOCKET mg_open_listener(const char *url, struct mg_addr *addr) {
} }
mg_set_non_blocking_mode(fd); mg_set_non_blocking_mode(fd);
} else if (fd != INVALID_SOCKET) { } else if (fd != INVALID_SOCKET) {
s_err = MG_SOCK_ERRNO;
closesocket(fd); closesocket(fd);
fd = INVALID_SOCKET; fd = INVALID_SOCKET;
} }
} }
if (fd == INVALID_SOCKET) { if (fd == INVALID_SOCKET) {
LOG(LL_ERROR, ("Failed to listen on %s, errno %d", url, MG_SOCK_ERRNO)); if (s_err == 0) s_err = MG_SOCK_ERRNO;
LOG(LL_ERROR, ("Failed to listen on %s, errno %d", url, s_err));
} }
return fd; return fd;
@@ -191,22 +194,9 @@ static long mg_sock_recv(struct mg_connection *c, void *buf, size_t len) {
long n = 0; long n = 0;
if (c->is_udp) { if (c->is_udp) {
union usa usa; union usa usa;
socklen_t slen = sizeof(usa.sin); socklen_t slen = tousa(&c->peer, &usa);
#if MG_ENABLE_IPV6
if (c->peer.is_ip6) slen = sizeof(usa.sin6);
#endif
n = recvfrom(FD(c), (char *) buf, len, 0, &usa.sa, &slen); n = recvfrom(FD(c), (char *) buf, len, 0, &usa.sa, &slen);
if (n > 0) { if (n > 0) tomgaddr(&usa, &c->peer, slen != sizeof(usa.sin));
if (c->peer.is_ip6) {
#if MG_ENABLE_IPV6
memcpy(c->peer.ip6, &usa.sin6.sin6_addr, sizeof(c->peer.ip6));
c->peer.port = usa.sin6.sin6_port;
#endif
} else {
c->peer.ip = *(uint32_t *) &usa.sin.sin_addr;
c->peer.port = usa.sin.sin_port;
}
}
} else { } else {
n = recv(FD(c), (char *) buf, len, MSG_NONBLOCKING); n = recv(FD(c), (char *) buf, len, MSG_NONBLOCKING);
} }
@@ -271,7 +261,7 @@ static void write_conn(struct mg_connection *c) {
LOG(LL_INFO, ("\n-- %lu %s %s %ld\n%s", c->id, c->label, "<-", n, s)); LOG(LL_INFO, ("\n-- %lu %s %s %ld\n%s", c->id, c->label, "<-", n, s));
free(s); free(s);
} }
mg_iobuf_delete(&c->send, (size_t) n); mg_iobuf_del(&c->send, 0, (size_t) n);
if (c->send.len == 0) mg_iobuf_resize(&c->send, 0); if (c->send.len == 0) mg_iobuf_resize(&c->send, 0);
mg_call(c, MG_EV_WRITE, &n); mg_call(c, MG_EV_WRITE, &n);
// if (c->send.len == 0) mg_iobuf_resize(&c->send, 0); // if (c->send.len == 0) mg_iobuf_resize(&c->send, 0);
@@ -279,29 +269,30 @@ static void write_conn(struct mg_connection *c) {
} }
static void close_conn(struct mg_connection *c) { static void close_conn(struct mg_connection *c) {
// Unlink this connection from the list mg_resolve_cancel(c); // Close any pending DNS query
mg_resolve_cancel(c);
LIST_DELETE(struct mg_connection, &c->mgr->conns, c); LIST_DELETE(struct mg_connection, &c->mgr->conns, c);
if (c == c->mgr->dns4.c) c->mgr->dns4.c = NULL; if (c == c->mgr->dns4.c) c->mgr->dns4.c = NULL;
if (c == c->mgr->dns6.c) c->mgr->dns6.c = NULL; if (c == c->mgr->dns6.c) c->mgr->dns6.c = NULL;
// Order of operations is important. `MG_EV_CLOSE` event must be fired
// before we deallocate received data, see #1331
mg_call(c, MG_EV_CLOSE, NULL); mg_call(c, MG_EV_CLOSE, NULL);
// while (c->callbacks != NULL) mg_fn_del(c, c->callbacks->fn);
LOG(LL_DEBUG, ("%lu closed", c->id)); LOG(LL_DEBUG, ("%lu closed", c->id));
if (FD(c) != INVALID_SOCKET) { if (FD(c) != INVALID_SOCKET) {
closesocket(FD(c)); closesocket(FD(c));
#if MG_ARCH == MG_ARCH_FREERTOS_TCP #if MG_ARCH == MG_ARCH_FREERTOS_TCP
FreeRTOS_FD_CLR(c->fd, c->mgr->ss, eSELECT_ALL); FreeRTOS_FD_CLR(c->fd, c->mgr->ss, eSELECT_ALL);
#endif #endif
c->fd = S2PTR(INVALID_SOCKET);
} }
mg_tls_free(c); mg_tls_free(c);
free(c->recv.buf); mg_iobuf_free(&c->recv);
free(c->send.buf); mg_iobuf_free(&c->send);
memset(c, 0, sizeof(*c)); memset(c, 0, sizeof(*c));
free(c); free(c);
} }
static void setsockopts(struct mg_connection *c) { static void setsockopts(struct mg_connection *c) {
#if MG_ARCH == MG_ARCH_FREERTOS_TCP #if MG_ARCH == MG_ARCH_FREERTOS_TCP || MG_ARCH == MG_ARCH_AZURERTOS
(void) c; (void) c;
#else #else
int on = 1; int on = 1;
@@ -330,28 +321,21 @@ static void setsockopts(struct mg_connection *c) {
void mg_connect_resolved(struct mg_connection *c) { void mg_connect_resolved(struct mg_connection *c) {
char buf[40]; char buf[40];
int type = c->is_udp ? SOCK_DGRAM : SOCK_STREAM; int type = c->is_udp ? SOCK_DGRAM : SOCK_STREAM;
int rc, af = AF_INET; int rc, af = c->peer.is_ip6 ? AF_INET6 : AF_INET;
#if MG_ENABLE_IPV6
if (c->peer.is_ip6) af = AF_INET6;
#endif
mg_straddr(c, buf, sizeof(buf)); mg_straddr(c, buf, sizeof(buf));
c->fd = sock2ptr(socket(af, type, 0)); c->fd = S2PTR(socket(af, type, 0));
if (FD(c) == INVALID_SOCKET) { if (FD(c) == INVALID_SOCKET) {
mg_error(c, "socket(): %d", MG_SOCK_ERRNO); mg_error(c, "socket(): %d", MG_SOCK_ERRNO);
return; } else {
} union usa usa;
socklen_t slen = tousa(&c->peer, &usa);
mg_set_non_blocking_mode(FD(c)); if (c->is_udp == 0) mg_set_non_blocking_mode(FD(c));
mg_call(c, MG_EV_RESOLVE, NULL); if (c->is_udp == 0) setsockopts(c);
if (type == SOCK_STREAM) { mg_call(c, MG_EV_RESOLVE, NULL);
union usa usa = tousa(&c->peer); if ((rc = connect(FD(c), &usa.sa, slen)) == 0) {
socklen_t slen = sizeof(usa.sin); mg_call(c, MG_EV_CONNECT, NULL);
#if MG_ENABLE_IPV6 } else if (mg_sock_would_block()) {
if (c->peer.is_ip6) slen = sizeof(usa.sin6); c->is_connecting = 1;
#endif
if ((rc = connect(FD(c), &usa.sa, slen)) == 0 || mg_sock_would_block()) {
setsockopts(c);
if (rc != 0) c->is_connecting = 1;
} else { } else {
mg_error(c, "connect: %d", MG_SOCK_ERRNO); mg_error(c, "connect: %d", MG_SOCK_ERRNO);
} }
@@ -382,6 +366,12 @@ static void accept_conn(struct mg_mgr *mgr, struct mg_connection *lsn) {
socklen_t sa_len = sizeof(usa); socklen_t sa_len = sizeof(usa);
SOCKET fd = accept(FD(lsn), &usa.sa, &sa_len); SOCKET fd = accept(FD(lsn), &usa.sa, &sa_len);
if (fd == INVALID_SOCKET) { if (fd == INVALID_SOCKET) {
#if MG_ARCH == MG_ARCH_AZURERTOS
// AzureRTOS, in non-block socket mode can mark listening socket readable
// even it is not. See comment for 'select' func implementation in nx_bsd.c
// That's not an error, just should try later
if (MG_SOCK_ERRNO != EAGAIN)
#endif
LOG(LL_ERROR, ("%lu accept failed, errno %d", lsn->id, MG_SOCK_ERRNO)); LOG(LL_ERROR, ("%lu accept failed, errno %d", lsn->id, MG_SOCK_ERRNO));
#if (!defined(_WIN32) && (MG_ARCH != MG_ARCH_FREERTOS_TCP)) #if (!defined(_WIN32) && (MG_ARCH != MG_ARCH_FREERTOS_TCP))
} else if ((long) fd >= FD_SETSIZE) { } else if ((long) fd >= FD_SETSIZE) {
@@ -393,15 +383,7 @@ static void accept_conn(struct mg_mgr *mgr, struct mg_connection *lsn) {
closesocket(fd); closesocket(fd);
} else { } else {
char buf[40]; char buf[40];
c->peer.port = usa.sin.sin_port; tomgaddr(&usa, &c->peer, sa_len != sizeof(usa.sin));
memcpy(&c->peer.ip, &usa.sin.sin_addr, sizeof(c->peer.ip));
#if MG_ENABLE_IPV6
if (sa_len == sizeof(usa.sin6)) {
memcpy(c->peer.ip6, &usa.sin6.sin6_addr, sizeof(c->peer.ip6));
c->peer.port = usa.sin6.sin6_port;
c->peer.is_ip6 = 1;
}
#endif
mg_straddr(c, buf, sizeof(buf)); mg_straddr(c, buf, sizeof(buf));
LOG(LL_DEBUG, ("%lu accepted %s", c->id, buf)); LOG(LL_DEBUG, ("%lu accepted %s", c->id, buf));
mg_set_non_blocking_mode(FD(c)); mg_set_non_blocking_mode(FD(c));
@@ -417,47 +399,66 @@ static void accept_conn(struct mg_mgr *mgr, struct mg_connection *lsn) {
} }
} }
#if MG_ENABLE_SOCKETPAIR static bool mg_socketpair(SOCKET sp[2], union usa usa[2]) {
bool mg_socketpair(int *s1, int *s2) { socklen_t n = sizeof(usa[0].sin);
#ifdef MG_ENABLE_NATIVE_SOCKETPAIR bool result = false;
// For some reason, native socketpair() call fails on Macos
// Enable this codepath only when MG_ENABLE_NATIVE_SOCKETPAIR is defined
int sp[2], ret = 0;
if (socketpair(AF_INET, SOCK_DGRAM, IPPROTO_UDP, sp) == 0) {
*s1 = sp[0], *s2 = sp[1], ret = 1;
}
LOG(LL_INFO, ("errno %d", errno));
return ret;
#else
union usa sa, sa2;
SOCKET sp[2] = {INVALID_SOCKET, INVALID_SOCKET};
socklen_t len = sizeof(sa.sin);
int ret = 0;
(void) memset(&sa, 0, sizeof(sa)); (void) memset(&usa[0], 0, sizeof(usa[0]));
sa.sin.sin_family = AF_INET; usa[0].sin.sin_family = AF_INET;
sa.sin.sin_addr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */ *(uint32_t *) &usa->sin.sin_addr = mg_htonl(0x7f000001); // 127.0.0.1
sa2 = sa; usa[1] = usa[0];
if ((sp[0] = socket(AF_INET, SOCK_DGRAM, 0)) != INVALID_SOCKET && if ((sp[0] = socket(AF_INET, SOCK_DGRAM, 0)) != INVALID_SOCKET &&
(sp[1] = socket(AF_INET, SOCK_DGRAM, 0)) != INVALID_SOCKET && (sp[1] = socket(AF_INET, SOCK_DGRAM, 0)) != INVALID_SOCKET &&
bind(sp[0], &sa.sa, len) == 0 && bind(sp[1], &sa2.sa, len) == 0 && bind(sp[0], &usa[0].sa, n) == 0 && bind(sp[1], &usa[1].sa, n) == 0 &&
getsockname(sp[0], &sa.sa, &len) == 0 && getsockname(sp[0], &usa[0].sa, &n) == 0 &&
getsockname(sp[1], &sa2.sa, &len) == 0 && getsockname(sp[1], &usa[1].sa, &n) == 0 &&
connect(sp[0], &sa2.sa, len) == 0 && connect(sp[1], &sa.sa, len) == 0) { connect(sp[0], &usa[1].sa, n) == 0 &&
mg_set_non_blocking_mode(sp[1]); connect(sp[1], &usa[0].sa, n) == 0) {
*s1 = sp[0]; mg_set_non_blocking_mode(sp[1]); // Set close-on-exec
*s2 = sp[1]; result = true;
ret = 1;
} else { } else {
if (sp[0] != INVALID_SOCKET) closesocket(sp[0]); if (sp[0] != INVALID_SOCKET) closesocket(sp[0]);
if (sp[1] != INVALID_SOCKET) closesocket(sp[1]); if (sp[1] != INVALID_SOCKET) closesocket(sp[1]);
sp[0] = sp[1] = INVALID_SOCKET;
} }
return ret; return result;
#endif }
void mg_mgr_wakeup(struct mg_connection *c) {
LOG(LL_INFO, ("skt: %p", c->pfn_data));
send((SOCKET) (size_t) c->pfn_data, "\x01", 1, MSG_NONBLOCKING);
}
static void pf1(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
if (ev == MG_EV_READ) mg_iobuf_free(&c->recv);
(void) ev_data, (void) fn_data;
}
struct mg_connection *mg_mkpipe(struct mg_mgr *mgr, mg_event_handler_t fn,
void *fn_data) {
union usa usa[2];
SOCKET sp[2] = {INVALID_SOCKET, INVALID_SOCKET};
struct mg_connection *c = NULL;
if (!mg_socketpair(sp, usa)) {
LOG(LL_ERROR, ("Cannot create socket pair"));
} else if ((c = alloc_conn(mgr, false, sp[1])) == NULL) {
closesocket(sp[0]);
closesocket(sp[1]);
LOG(LL_ERROR, ("OOM"));
} else {
LOG(LL_INFO, ("pipe %lu", (unsigned long) sp[0]));
tomgaddr(&usa[0], &c->peer, false);
c->is_udp = 1;
c->pfn = pf1;
c->pfn_data = (void *) (size_t) sp[0];
c->fn = fn;
c->fn_data = fn_data;
LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
}
return c;
} }
#endif
struct mg_connection *mg_listen(struct mg_mgr *mgr, const char *url, struct mg_connection *mg_listen(struct mg_mgr *mgr, const char *url,
mg_event_handler_t fn, void *fn_data) { mg_event_handler_t fn, void *fn_data) {
@@ -466,12 +467,13 @@ struct mg_connection *mg_listen(struct mg_mgr *mgr, const char *url,
struct mg_addr addr; struct mg_addr addr;
SOCKET fd = mg_open_listener(url, &addr); SOCKET fd = mg_open_listener(url, &addr);
if (fd == INVALID_SOCKET) { if (fd == INVALID_SOCKET) {
LOG(LL_ERROR, ("Failed: %s, errno %d", url, MG_SOCK_ERRNO));
} else if ((c = alloc_conn(mgr, 0, fd)) == NULL) { } else if ((c = alloc_conn(mgr, 0, fd)) == NULL) {
LOG(LL_ERROR, ("OOM %s", url)); LOG(LL_ERROR, ("OOM %s", url));
closesocket(fd); closesocket(fd);
} else { } else {
memcpy(&c->peer, &addr, sizeof(struct mg_addr)); memcpy(&c->peer, &addr, sizeof(struct mg_addr));
c->fd = sock2ptr(fd); c->fd = S2PTR(fd);
c->is_listening = 1; c->is_listening = 1;
c->is_udp = is_udp; c->is_udp = is_udp;
LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c); LIST_ADD_HEAD(struct mg_connection, &mgr->conns, c);
@@ -511,9 +513,6 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) {
FD_ZERO(&wset); FD_ZERO(&wset);
for (c = mgr->conns; c != NULL; c = c->next) { for (c = mgr->conns; c != NULL; c = c->next) {
// c->is_writable = 0;
// TLS might have stuff buffered, so dig everything
// c->is_readable = c->is_tls && c->is_readable ? 1 : 0;
if (c->is_closing || c->is_resolving || FD(c) == INVALID_SOCKET) continue; if (c->is_closing || c->is_resolving || FD(c) == INVALID_SOCKET) continue;
FD_SET(FD(c), &rset); FD_SET(FD(c), &rset);
if (FD(c) > maxfd) maxfd = FD(c); if (FD(c) > maxfd) maxfd = FD(c);
@@ -521,7 +520,7 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) {
FD_SET(FD(c), &wset); FD_SET(FD(c), &wset);
} }
if ((rc = select(maxfd + 1, &rset, &wset, NULL, &tv)) < 0) { if ((rc = select((int) maxfd + 1, &rset, &wset, NULL, &tv)) < 0) {
LOG(LL_DEBUG, ("select: %d %d", rc, MG_SOCK_ERRNO)); LOG(LL_DEBUG, ("select: %d %d", rc, MG_SOCK_ERRNO));
FD_ZERO(&rset); FD_ZERO(&rset);
FD_ZERO(&wset); FD_ZERO(&wset);
+13 -7
View File
@@ -24,7 +24,7 @@ static char *mg_ssi(const char *path, const char *root, int depth) {
snprintf(tmp, sizeof(tmp), "%.*s%s", (int) (p - path), path, arg); snprintf(tmp, sizeof(tmp), "%.*s%s", (int) (p - path), path, arg);
if (depth < MG_MAX_SSI_DEPTH && if (depth < MG_MAX_SSI_DEPTH &&
(data = mg_ssi(tmp, root, depth + 1)) != NULL) { (data = mg_ssi(tmp, root, depth + 1)) != NULL) {
mg_iobuf_append(&b, data, strlen(data), align); mg_iobuf_add(&b, b.len, data, strlen(data), align);
free(data); free(data);
} else { } else {
LOG(LL_ERROR, ("%s: file=%s error or too deep", path, arg)); LOG(LL_ERROR, ("%s: file=%s error or too deep", path, arg));
@@ -34,7 +34,7 @@ static char *mg_ssi(const char *path, const char *root, int depth) {
snprintf(tmp, sizeof(tmp), "%s%s", root, arg); snprintf(tmp, sizeof(tmp), "%s%s", root, arg);
if (depth < MG_MAX_SSI_DEPTH && if (depth < MG_MAX_SSI_DEPTH &&
(data = mg_ssi(tmp, root, depth + 1)) != NULL) { (data = mg_ssi(tmp, root, depth + 1)) != NULL) {
mg_iobuf_append(&b, data, strlen(data), align); mg_iobuf_add(&b, b.len, data, strlen(data), align);
free(data); free(data);
} else { } else {
LOG(LL_ERROR, ("%s: virtual=%s error or too deep", path, arg)); LOG(LL_ERROR, ("%s: virtual=%s error or too deep", path, arg));
@@ -42,13 +42,13 @@ static char *mg_ssi(const char *path, const char *root, int depth) {
} else { } else {
// Unknown SSI tag // Unknown SSI tag
LOG(LL_INFO, ("Unknown SSI tag: %.*s", (int) len, buf)); LOG(LL_INFO, ("Unknown SSI tag: %.*s", (int) len, buf));
mg_iobuf_append(&b, buf, len, align); mg_iobuf_add(&b, b.len, buf, len, align);
} }
intag = 0; intag = 0;
len = 0; len = 0;
} else if (ch == '<') { } else if (ch == '<') {
intag = 1; intag = 1;
if (len > 0) mg_iobuf_append(&b, buf, len, align); if (len > 0) mg_iobuf_add(&b, b.len, buf, len, align);
len = 0; len = 0;
buf[len++] = (char) (ch & 0xff); buf[len++] = (char) (ch & 0xff);
} else if (intag) { } else if (intag) {
@@ -62,13 +62,13 @@ static char *mg_ssi(const char *path, const char *root, int depth) {
} else { } else {
buf[len++] = (char) (ch & 0xff); buf[len++] = (char) (ch & 0xff);
if (len >= sizeof(buf)) { if (len >= sizeof(buf)) {
mg_iobuf_append(&b, buf, len, align); mg_iobuf_add(&b, b.len, buf, len, align);
len = 0; len = 0;
} }
} }
} }
if (len > 0) mg_iobuf_append(&b, buf, len, align); if (len > 0) mg_iobuf_add(&b, b.len, buf, len, align);
if (b.len > 0) mg_iobuf_append(&b, "", 1, align); // nul-terminate if (b.len > 0) mg_iobuf_add(&b, b.len, "", 1, align); // nul-terminate
fclose(fp); fclose(fp);
} }
(void) depth; (void) depth;
@@ -83,4 +83,10 @@ void mg_http_serve_ssi(struct mg_connection *c, const char *root,
mg_http_reply(c, 200, headers, "%s", data == NULL ? "" : data); mg_http_reply(c, 200, headers, "%s", data == NULL ? "" : data);
free(data); free(data);
} }
#else
void mg_http_serve_ssi(struct mg_connection *c, const char *root,
const char *fullpath) {
mg_http_reply(c, 501, NULL, "SSI not enabled");
(void) root, (void) fullpath;
}
#endif #endif
+2 -2
View File
@@ -4,8 +4,8 @@
#include <string.h> #include <string.h>
struct mg_str { struct mg_str {
const char *ptr; const char *ptr; // Pointer to string data
size_t len; size_t len; // String len
}; };
#define MG_NULL_STR \ #define MG_NULL_STR \
+3 -2
View File
@@ -3,14 +3,15 @@
struct mg_timer { struct mg_timer {
unsigned long period_ms; // Timer period in milliseconds unsigned long period_ms; // Timer period in milliseconds
unsigned flags; // Possible flags values below unsigned flags; // Possible flags values below
#define MG_TIMER_REPEAT 1 // Call function periodically, otherwise run once
#define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set
void (*fn)(void *); // Function to call void (*fn)(void *); // Function to call
void *arg; // Function argument void *arg; // Function argument
unsigned long expire; // Expiration timestamp in milliseconds unsigned long expire; // Expiration timestamp in milliseconds
struct mg_timer *next; // Linkage in g_timers list struct mg_timer *next; // Linkage in g_timers list
}; };
#define MG_TIMER_REPEAT 1 // Call function periodically, otherwise run once
#define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set
extern struct mg_timer *g_timers; // Global list of timers extern struct mg_timer *g_timers; // Global list of timers
void mg_timer_init(struct mg_timer *, unsigned long ms, unsigned, void mg_timer_init(struct mg_timer *, unsigned long ms, unsigned,
+10 -8
View File
@@ -90,8 +90,8 @@ void mg_tls_init(struct mg_connection *c, struct mg_tls_opts *opts) {
mg_error(c, "TLS OOM"); mg_error(c, "TLS OOM");
goto fail; goto fail;
} }
LOG(LL_DEBUG, ("%lu Setting TLS, CA: %s, cert: %s, key: %s", c->id, ca, LOG(LL_DEBUG,
cert, certkey)); ("%lu Setting TLS, CA: %s, cert: %s, key: %s", c->id, ca, cert, certkey));
mbedtls_ssl_init(&tls->ssl); mbedtls_ssl_init(&tls->ssl);
mbedtls_ssl_config_init(&tls->conf); mbedtls_ssl_config_init(&tls->conf);
mbedtls_x509_crt_init(&tls->ca); mbedtls_x509_crt_init(&tls->ca);
@@ -133,7 +133,8 @@ void mg_tls_init(struct mg_connection *c, struct mg_tls_opts *opts) {
#endif #endif
if (opts->srvname.len > 0) { if (opts->srvname.len > 0) {
char mem[128], *buf = mem; char mem[128], *buf = mem;
mg_asprintf(&buf, sizeof(mem), "%.*s", (int) opts->srvname.len, opts->srvname.ptr); mg_asprintf(&buf, sizeof(mem), "%.*s", (int) opts->srvname.len,
opts->srvname.ptr);
mbedtls_ssl_set_hostname(&tls->ssl, buf); mbedtls_ssl_set_hostname(&tls->ssl, buf);
if (buf != mem) free(buf); if (buf != mem) free(buf);
} }
@@ -226,6 +227,8 @@ static int mg_tls_err(struct mg_tls *tls, int res) {
// - *ALL* SSL accepted connection report read error on the next poll cycle. // - *ALL* SSL accepted connection report read error on the next poll cycle.
// Thus a single errored connection can close all the rest, unrelated ones. // Thus a single errored connection can close all the rest, unrelated ones.
// Clearing the error keeps the shared SSL_CTX in an OK state. // Clearing the error keeps the shared SSL_CTX in an OK state.
if (err != 0) ERR_print_errors_fp(stderr);
ERR_clear_error(); ERR_clear_error();
if (err == SSL_ERROR_WANT_READ) return 0; if (err == SSL_ERROR_WANT_READ) return 0;
if (err == SSL_ERROR_WANT_WRITE) return 0; if (err == SSL_ERROR_WANT_WRITE) return 0;
@@ -304,7 +307,8 @@ void mg_tls_init(struct mg_connection *c, struct mg_tls_opts *opts) {
if (opts->ciphers != NULL) SSL_set_cipher_list(tls->ssl, opts->ciphers); if (opts->ciphers != NULL) SSL_set_cipher_list(tls->ssl, opts->ciphers);
if (opts->srvname.len > 0) { if (opts->srvname.len > 0) {
char mem[128], *buf = mem; char mem[128], *buf = mem;
mg_asprintf(&buf, sizeof(mem), "%.*s", (int) opts->srvname.len, opts->srvname.ptr); mg_asprintf(&buf, sizeof(mem), "%.*s", (int) opts->srvname.len,
opts->srvname.ptr);
SSL_set_tlsext_host_name(tls->ssl, buf); SSL_set_tlsext_host_name(tls->ssl, buf);
if (buf != mem) free(buf); if (buf != mem) free(buf);
} }
@@ -325,15 +329,13 @@ fail:
void mg_tls_handshake(struct mg_connection *c) { void mg_tls_handshake(struct mg_connection *c) {
struct mg_tls *tls = (struct mg_tls *) c->tls; struct mg_tls *tls = (struct mg_tls *) c->tls;
int rc; int rc;
SSL_set_fd(tls->ssl, (int) (long) c->fd); SSL_set_fd(tls->ssl, (int) (size_t) c->fd);
rc = c->is_client ? SSL_connect(tls->ssl) : SSL_accept(tls->ssl); rc = c->is_client ? SSL_connect(tls->ssl) : SSL_accept(tls->ssl);
if (rc == 1) { if (rc == 1) {
LOG(LL_DEBUG, ("%lu success", c->id)); LOG(LL_DEBUG, ("%lu success", c->id));
c->is_tls_hs = 0; c->is_tls_hs = 0;
} else { } else {
int code; int code = mg_tls_err(tls, rc);
ERR_print_errors_fp(stderr);
code = mg_tls_err(tls, rc);
if (code != 0) mg_error(c, "tls hs: rc %d, err %d", rc, code); if (code != 0) mg_error(c, "tls hs: rc %d, err %d", rc, code);
} }
} }
+2 -6
View File
@@ -1,5 +1,5 @@
#include <stdlib.h>
#include "url.h" #include "url.h"
#include <stdlib.h>
struct url { struct url {
size_t key, user, pass, host, port, uri, end; size_t key, user, pass, host, port, uri, end;
@@ -21,7 +21,7 @@ static struct url urlparse(const char *url) {
u.port = 0; u.port = 0;
} else if (url[i] == ']') { } else if (url[i] == ']') {
u.port = 0; // IPv6 URLs, like http://[::1]/bar u.port = 0; // IPv6 URLs, like http://[::1]/bar
} else if (url[i] == ':' && u.port == 0) { } else if (url[i] == ':' && u.port == 0 && u.uri == 0) {
u.port = i + 1; u.port = i + 1;
} else if (url[i] == '@' && u.user == 0 && u.pass == 0) { } else if (url[i] == '@' && u.user == 0 && u.pass == 0) {
u.user = u.host; u.user = u.host;
@@ -45,10 +45,6 @@ struct mg_str mg_url_host(const char *url) {
: u.uri ? u.uri - u.host : u.uri ? u.uri - u.host
: u.end - u.host; : u.end - u.host;
struct mg_str s = mg_str_n(url + u.host, n); struct mg_str s = mg_str_n(url + u.host, n);
if (s.len > 2 && s.ptr[0] == '[' && s.ptr[s.len - 1] == ']') {
s.len -= 2;
s.ptr++;
}
return s; return s;
} }
+48 -29
View File
@@ -2,32 +2,14 @@
#include "util.h" #include "util.h"
#if MG_ENABLE_FS
int mg_stat(const char *path, mg_stat_t *st) {
#ifdef _WIN32
wchar_t tmp[MG_PATH_MAX];
MultiByteToWideChar(CP_UTF8, 0, path, -1, tmp, sizeof(tmp) / sizeof(tmp[0]));
return _wstati64(tmp, st);
#else
return stat(path, st);
#endif
}
int64_t mg_file_size(const char *path) {
#if MG_ARCH == MG_ARCH_FREERTOS_TCP && defined(MG_ENABLE_FF)
struct FF_STAT st;
return ff_stat(path, &st) == 0 ? st.st_size : 0;
#else
mg_stat_t st;
return mg_stat(path, &st) == 0 ? st.st_size : 0;
#endif
}
char *mg_file_read(const char *path, size_t *sizep) { char *mg_file_read(const char *path, size_t *sizep) {
FILE *fp; FILE *fp;
char *data = NULL; char *data = NULL;
size_t size = (size_t) mg_file_size(path); size_t size = 0;
if ((fp = fopen(path, "rb")) != NULL) { if ((fp = fopen(path, "rb")) != NULL) {
fseek(fp, 0, SEEK_END);
size = (size_t) ftell(fp);
rewind(fp);
data = (char *) calloc(1, size + 1); data = (char *) calloc(1, size + 1);
if (data != NULL) { if (data != NULL) {
if (fread(data, 1, size, fp) != size) { if (fread(data, 1, size, fp) != size) {
@@ -74,26 +56,28 @@ bool mg_file_printf(const char *path, const char *fmt, ...) {
if (buf != tmp) free(buf); if (buf != tmp) free(buf);
return result; return result;
} }
#endif // MG_ENABLE_FS
#if MG_ENABLE_CUSTOM_RANDOM
#else
void mg_random(void *buf, size_t len) { void mg_random(void *buf, size_t len) {
bool done = false; bool done = false;
unsigned char *p = (unsigned char *) buf; unsigned char *p = (unsigned char *) buf;
#if MG_ARCH == MG_ARCH_ESP32 #if MG_ARCH == MG_ARCH_ESP32
while (len--) *p++ = (unsigned char) (esp_random() & 255); while (len--) *p++ = (unsigned char) (esp_random() & 255);
#elif MG_ARCH == MG_ARCH_WIN32 #elif MG_ARCH == MG_ARCH_WIN32
#elif MG_ARCH_UNIX && MG_ENABLE_FS #elif MG_ARCH_UNIX
FILE *fp = fopen("/dev/urandom", "rb"); FILE *fp = fopen("/dev/urandom", "rb");
if (fp != NULL) { if (fp != NULL) {
if (fread(buf, 1, len, fp) == len) done = true; if (fread(buf, 1, len, fp) == len) done = true;
fclose(fp); fclose(fp);
} }
#endif #endif
// Fallback to a pseudo random gen // Fallback to a pseudo random gen
if (!done) { if (!done) {
while (len--) *p++ = (unsigned char) (rand() & 255); while (len--) *p++ = (unsigned char) (rand() & 255);
} }
} }
#endif
bool mg_globmatch(const char *s1, size_t n1, const char *s2, size_t n2) { bool mg_globmatch(const char *s1, size_t n1, const char *s2, size_t n2) {
size_t i = 0, j = 0, ni = 0, nj = 0; size_t i = 0, j = 0, ni = 0, nj = 0;
@@ -102,9 +86,10 @@ bool mg_globmatch(const char *s1, size_t n1, const char *s2, size_t n2) {
i++, j++; i++, j++;
} else if (i < n1 && (s1[i] == '*' || s1[i] == '#')) { } else if (i < n1 && (s1[i] == '*' || s1[i] == '#')) {
ni = i, nj = j + 1, i++; ni = i, nj = j + 1, i++;
} else if (nj > 0 && nj <= n2 && (s1[i - 1] == '#' || s2[j] != '/')) { } else if (nj > 0 && nj <= n2 && (s1[ni] == '#' || s2[j] != '/')) {
i = ni, j = nj; i = ni, j = nj;
} else { } else {
// printf(">>: [%s] [%s] %d %d %d %d\n", s1, s2, i, j, ni, nj);
return false; return false;
} }
} }
@@ -124,7 +109,7 @@ static size_t mg_nce(const char *s, size_t n, size_t ofs, size_t *koff,
return ofs > n ? n : ofs; return ofs > n ? n : ofs;
} }
bool mg_next_comma_entry(struct mg_str *s, struct mg_str *k, struct mg_str *v) { bool mg_commalist(struct mg_str *s, struct mg_str *k, struct mg_str *v) {
size_t koff = 0, klen = 0, voff = 0, vlen = 0; size_t koff = 0, klen = 0, voff = 0, vlen = 0;
size_t off = mg_nce(s->ptr, s->len, 0, &koff, &klen, &voff, &vlen); size_t off = mg_nce(s->ptr, s->len, 0, &koff, &klen, &voff, &vlen);
if (k != NULL) *k = mg_str_n(s->ptr + koff, klen); if (k != NULL) *k = mg_str_n(s->ptr + koff, klen);
@@ -143,7 +128,7 @@ uint32_t mg_ntohl(uint32_t net) {
uint16_t mg_ntohs(uint16_t net) { uint16_t mg_ntohs(uint16_t net) {
uint8_t data[2] = {0, 0}; uint8_t data[2] = {0, 0};
memcpy(&data, &net, sizeof(data)); memcpy(&data, &net, sizeof(data));
return (uint16_t)((uint16_t) data[1] | (((uint16_t) data[0]) << 8)); return (uint16_t) ((uint16_t) data[1] | (((uint16_t) data[0]) << 8));
} }
char *mg_hexdump(const void *buf, size_t len) { char *mg_hexdump(const void *buf, size_t len) {
@@ -281,6 +266,36 @@ uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len) {
return ~crc; return ~crc;
} }
static int isbyte(int n) {
return n >= 0 && n <= 255;
}
static int parse_net(const char *spec, uint32_t *net, uint32_t *mask) {
int n, a, b, c, d, slash = 32, len = 0;
if ((sscanf(spec, "%d.%d.%d.%d/%d%n", &a, &b, &c, &d, &slash, &n) == 5 ||
sscanf(spec, "%d.%d.%d.%d%n", &a, &b, &c, &d, &n) == 4) &&
isbyte(a) && isbyte(b) && isbyte(c) && isbyte(d) && slash >= 0 &&
slash < 33) {
len = n;
*net = ((uint32_t) a << 24) | ((uint32_t) b << 16) | ((uint32_t) c << 8) |
(uint32_t) d;
*mask = slash ? (uint32_t) (0xffffffffU << (32 - slash)) : (uint32_t) 0;
}
return len;
}
int mg_check_ip_acl(struct mg_str acl, uint32_t remote_ip) {
struct mg_str k, v;
int allowed = acl.len == 0 ? '+' : '-'; // If any ACL is set, deny by default
while (mg_commalist(&acl, &k, &v)) {
uint32_t net, mask;
if (k.ptr[0] != '+' && k.ptr[0] != '-') return -1;
if (parse_net(&k.ptr[1], &net, &mask) == 0) return -2;
if ((remote_ip & mask) == net) allowed = k.ptr[0];
}
return allowed == '+';
}
double mg_time(void) { double mg_time(void) {
#if MG_ARCH == MG_ARCH_WIN32 #if MG_ARCH == MG_ARCH_WIN32
SYSTEMTIME sysnow; SYSTEMTIME sysnow;
@@ -299,7 +314,7 @@ double mg_time(void) {
((int64_t) ftime.dwHighDateTime << 32)) / ((int64_t) ftime.dwHighDateTime << 32)) /
10000000.0) - 10000000.0) -
11644473600; 11644473600;
#elif MG_ARCH == MG_ARCH_FREERTOS_TCP #elif MG_ARCH == MG_ARCH_FREERTOS_TCP || MG_ARCH == MG_ARCH_AZURERTOS
return mg_millis() / 1000.0; return mg_millis() / 1000.0;
#else #else
struct timeval tv; struct timeval tv;
@@ -315,6 +330,8 @@ void mg_usleep(unsigned long usecs) {
ets_delay_us(usecs); ets_delay_us(usecs);
#elif MG_ARCH == MG_ARCH_FREERTOS_TCP || MG_ARCH == MG_ARCH_FREERTOS_LWIP #elif MG_ARCH == MG_ARCH_FREERTOS_TCP || MG_ARCH == MG_ARCH_FREERTOS_LWIP
vTaskDelay(pdMS_TO_TICKS(usecs / 1000)); vTaskDelay(pdMS_TO_TICKS(usecs / 1000));
#elif MG_ARCH == MG_ARCH_AZURERTOS
tx_thread_sleep((usecs / 1000) * TX_TIMER_TICKS_PER_SECOND);
#else #else
usleep((useconds_t) usecs); usleep((useconds_t) usecs);
#endif #endif
@@ -329,6 +346,8 @@ unsigned long mg_millis(void) {
return xTaskGetTickCount() * portTICK_PERIOD_MS; return xTaskGetTickCount() * portTICK_PERIOD_MS;
#elif MG_ARCH == MG_ARCH_FREERTOS_TCP || MG_ARCH == MG_ARCH_FREERTOS_LWIP #elif MG_ARCH == MG_ARCH_FREERTOS_TCP || MG_ARCH == MG_ARCH_FREERTOS_LWIP
return xTaskGetTickCount() * portTICK_PERIOD_MS; return xTaskGetTickCount() * portTICK_PERIOD_MS;
#elif MG_ARCH == MG_ARCH_AZURERTOS
return tx_time_get() * (1000 /* MS per SEC */ / TX_TIMER_TICKS_PER_SECOND);
#else #else
struct timespec ts; struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts); clock_gettime(CLOCK_REALTIME, &ts);
+3 -25
View File
@@ -3,26 +3,12 @@
#include "arch.h" #include "arch.h"
#include "str.h" #include "str.h"
// WEAK symbol makes it possible to define a "default" function implementation,
// which could be overridden by the user who can define a function with the
// same name without linking conflict
#if !defined(WEAK)
#if (defined(__GNUC__) || defined(__clang__) || \
defined(__TI_COMPILER_VERSION__)) && \
!defined(_WIN32) && !defined(__CYGWIN__)
#define WEAK __attribute__((weak))
#else
#define WEAK
#endif
#endif
char *mg_file_read(const char *path, size_t *size); char *mg_file_read(const char *path, size_t *size);
int64_t mg_file_size(const char *path);
bool mg_file_write(const char *path, const void *buf, size_t len); bool mg_file_write(const char *path, const void *buf, size_t len);
bool mg_file_printf(const char *path, const char *fmt, ...); bool mg_file_printf(const char *path, const char *fmt, ...);
void mg_random(void *buf, size_t len) WEAK; void mg_random(void *buf, size_t len);
bool mg_globmatch(const char *pattern, size_t plen, const char *s, size_t n); bool mg_globmatch(const char *pattern, size_t plen, const char *s, size_t n);
bool mg_next_comma_entry(struct mg_str *s, struct mg_str *k, struct mg_str *v); bool mg_commalist(struct mg_str *s, struct mg_str *k, struct mg_str *v);
uint16_t mg_ntohs(uint16_t net); uint16_t mg_ntohs(uint16_t net);
uint32_t mg_ntohl(uint32_t net); uint32_t mg_ntohl(uint32_t net);
uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len); uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len);
@@ -33,19 +19,11 @@ unsigned long mg_unhexn(const char *s, size_t len);
int mg_asprintf(char **buf, size_t size, const char *fmt, ...); int mg_asprintf(char **buf, size_t size, const char *fmt, ...);
int mg_vasprintf(char **buf, size_t size, const char *fmt, va_list ap); int mg_vasprintf(char **buf, size_t size, const char *fmt, va_list ap);
int64_t mg_to64(struct mg_str str); int64_t mg_to64(struct mg_str str);
int mg_check_ip_acl(struct mg_str acl, uint32_t remote_ip);
double mg_time(void); double mg_time(void);
unsigned long mg_millis(void); unsigned long mg_millis(void);
void mg_usleep(unsigned long usecs); void mg_usleep(unsigned long usecs);
#if MG_ENABLE_FS
#ifdef _WIN32
typedef struct _stati64 mg_stat_t;
#else
typedef struct stat mg_stat_t;
#endif
int mg_stat(const char *path, mg_stat_t *);
#endif
#define mg_htons(x) mg_ntohs(x) #define mg_htons(x) mg_ntohs(x)
#define mg_htonl(x) mg_ntohl(x) #define mg_htonl(x) mg_ntohl(x)
+1 -9
View File
@@ -1,9 +1 @@
#define MG_VERSION "7.4"
#ifndef MONGOOSE_H
#define MONGOOSE_H
#define MG_VERSION "7.3"
#ifdef __cplusplus
extern "C" {
#endif
+108 -44
View File
@@ -14,15 +14,16 @@ struct ws_msg {
size_t data_len; size_t data_len;
}; };
static void ws_handshake(struct mg_connection *c, const char *key, static void ws_handshake(struct mg_connection *c, const struct mg_str *wskey,
size_t key_len, const char *fmt, va_list ap) { const struct mg_str *wsproto, const char *fmt,
va_list ap) {
const char *magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; const char *magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
unsigned char sha[20], b64_sha[30]; unsigned char sha[20], b64_sha[30];
char mem[128], *buf = mem; char mem[128], *buf = mem;
mg_sha1_ctx sha_ctx; mg_sha1_ctx sha_ctx;
mg_sha1_init(&sha_ctx); mg_sha1_init(&sha_ctx);
mg_sha1_update(&sha_ctx, (unsigned char *) key, key_len); mg_sha1_update(&sha_ctx, (unsigned char *) wskey->ptr, wskey->len);
mg_sha1_update(&sha_ctx, (unsigned char *) magic, 36); mg_sha1_update(&sha_ctx, (unsigned char *) magic, 36);
mg_sha1_final(sha, &sha_ctx); mg_sha1_final(sha, &sha_ctx);
mg_base64_encode(sha, sizeof(sha), (char *) b64_sha); mg_base64_encode(sha, sizeof(sha), (char *) b64_sha);
@@ -33,18 +34,23 @@ static void ws_handshake(struct mg_connection *c, const char *key,
"Upgrade: websocket\r\n" "Upgrade: websocket\r\n"
"Connection: Upgrade\r\n" "Connection: Upgrade\r\n"
"Sec-WebSocket-Accept: %s\r\n" "Sec-WebSocket-Accept: %s\r\n"
"%s\r\n", "%s",
b64_sha, buf); b64_sha, buf);
if (buf != mem) free(buf); if (buf != mem) free(buf);
if (wsproto != NULL) {
mg_printf(c, "Sec-WebSocket-Protocol: %.*s\r\n", (int) wsproto->len,
wsproto->ptr);
}
mg_send(c, "\r\n", 2);
} }
static size_t ws_process(uint8_t *buf, size_t len, struct ws_msg *msg) { static size_t ws_process(uint8_t *buf, size_t len, struct ws_msg *msg) {
size_t i, n = 0, mask_len = 0; size_t i, n = 0, mask_len = 0;
memset(msg, 0, sizeof(*msg)); memset(msg, 0, sizeof(*msg));
if (len >= 2) { if (len >= 2) {
n = buf[1] & 0x7f; n = buf[1] & 0x7f; // Frame length
mask_len = buf[1] & WEBSOCKET_FLAGS_MASK_FIN ? 4 : 0; mask_len = buf[1] & 128 ? 4 : 0; // last bit is a mask bit
msg->flags = *(unsigned char *) buf; msg->flags = buf[0];
if (n < 126 && len >= mask_len) { if (n < 126 && len >= mask_len) {
msg->data_len = n; msg->data_len = n;
msg->header_len = 2 + mask_len; msg->header_len = 2 + mask_len;
@@ -54,10 +60,13 @@ static size_t ws_process(uint8_t *buf, size_t len, struct ws_msg *msg) {
} else if (len >= 10 + mask_len) { } else if (len >= 10 + mask_len) {
msg->header_len = 10 + mask_len; msg->header_len = 10 + mask_len;
msg->data_len = msg->data_len =
(size_t)(((uint64_t) mg_ntohl(*(uint32_t *) &buf[2])) << 32) + (size_t) (((uint64_t) mg_ntohl(*(uint32_t *) &buf[2])) << 32) +
mg_ntohl(*(uint32_t *) &buf[6]); mg_ntohl(*(uint32_t *) &buf[6]);
} }
} }
// Sanity check, and integer overflow protection for the boundary check below
// data_len should not be larger than 1 Gb
if (msg->data_len > 1024 * 1024 * 1024) return 0;
if (msg->header_len + msg->data_len > len) return 0; if (msg->header_len + msg->data_len > len) return 0;
if (mask_len > 0) { if (mask_len > 0) {
uint8_t *p = buf + msg->header_len, *m = p - mask_len; uint8_t *p = buf + msg->header_len, *m = p - mask_len;
@@ -66,48 +75,59 @@ static size_t ws_process(uint8_t *buf, size_t len, struct ws_msg *msg) {
return msg->header_len + msg->data_len; return msg->header_len + msg->data_len;
} }
size_t mg_ws_send(struct mg_connection *c, const char *buf, size_t len, static size_t mkhdr(size_t len, int op, bool is_client, uint8_t *buf) {
int op) { size_t n = 0;
unsigned char header[10], mask[4]; buf[0] = (uint8_t) (op | 128);
size_t i, header_len = 0;
header[0] = (uint8_t)(op | WEBSOCKET_FLAGS_MASK_FIN);
if (len < 126) { if (len < 126) {
header[1] = (unsigned char) len; buf[1] = (unsigned char) len;
header_len = 2; n = 2;
} else if (len < 65536) { } else if (len < 65536) {
uint16_t tmp = mg_htons((uint16_t) len); uint16_t tmp = mg_htons((uint16_t) len);
header[1] = 126; buf[1] = 126;
memcpy(&header[2], &tmp, sizeof(tmp)); memcpy(&buf[2], &tmp, sizeof(tmp));
header_len = 4; n = 4;
} else { } else {
uint32_t tmp; uint32_t tmp;
header[1] = 127; buf[1] = 127;
tmp = mg_htonl((uint32_t)((uint64_t) len >> 32)); tmp = mg_htonl((uint32_t) ((uint64_t) len >> 32));
memcpy(&header[2], &tmp, sizeof(tmp)); memcpy(&buf[2], &tmp, sizeof(tmp));
tmp = mg_htonl((uint32_t)(len & 0xffffffff)); tmp = mg_htonl((uint32_t) (len & 0xffffffff));
memcpy(&header[6], &tmp, sizeof(tmp)); memcpy(&buf[6], &tmp, sizeof(tmp));
header_len = 10; n = 10;
} }
if (c->is_client) header[1] |= 1 << 7; // Set masking flag if (is_client) {
mg_send(c, header, header_len); buf[1] |= 1 << 7; // Set masking flag
if (c->is_client) { mg_random(&buf[n], 4);
mg_random(mask, sizeof(mask)); n += 4;
mg_send(c, mask, sizeof(mask));
header_len += sizeof(mask);
} }
LOG(LL_VERBOSE_DEBUG, ("WS out: %d [%.*s]", (int) len, (int) len, buf)); return n;
mg_send(c, buf, len); }
static void mg_ws_mask(struct mg_connection *c, size_t len) {
if (c->is_client && c->send.buf != NULL) { if (c->is_client && c->send.buf != NULL) {
uint8_t *p = c->send.buf + c->send.len - len; size_t i;
uint8_t *p = c->send.buf + c->send.len - len, *mask = p - 4;
for (i = 0; i < len; i++) p[i] ^= mask[i & 3]; for (i = 0; i < len; i++) p[i] ^= mask[i & 3];
} }
}
size_t mg_ws_send(struct mg_connection *c, const char *buf, size_t len,
int op) {
uint8_t header[14];
size_t header_len = mkhdr(len, op, c->is_client, header);
mg_send(c, header, header_len);
LOG(LL_VERBOSE_DEBUG, ("WS out: %d [%.*s]", (int) len, (int) len, buf));
mg_send(c, buf, len);
mg_ws_mask(c, len);
return header_len + len; return header_len + len;
} }
static void mg_ws_cb(struct mg_connection *c, int ev, void *ev_data, static void mg_ws_cb(struct mg_connection *c, int ev, void *ev_data,
void *fn_data) { void *fn_data) {
struct ws_msg msg; struct ws_msg msg;
size_t ofs = (size_t) c->pfn_data;
// assert(ofs < c->recv.len);
if (ev == MG_EV_READ) { if (ev == MG_EV_READ) {
if (!c->is_websocket && c->is_client) { if (!c->is_websocket && c->is_client) {
int n = mg_http_get_request_len(c->recv.buf, c->recv.len); int n = mg_http_get_request_len(c->recv.buf, c->recv.len);
@@ -124,16 +144,20 @@ static void mg_ws_cb(struct mg_connection *c, int ev, void *ev_data,
c->is_websocket = 1; c->is_websocket = 1;
mg_call(c, MG_EV_WS_OPEN, &hm); mg_call(c, MG_EV_WS_OPEN, &hm);
} }
mg_iobuf_delete(&c->recv, (size_t) n); mg_iobuf_del(&c->recv, 0, (size_t) n);
} else { } else {
return; // A request is not yet received return; // A request is not yet received
} }
} }
while (ws_process(c->recv.buf, c->recv.len, &msg) > 0) { while (ws_process(c->recv.buf + ofs, c->recv.len - ofs, &msg) > 0) {
char *s = (char *) c->recv.buf + msg.header_len; char *s = (char *) c->recv.buf + ofs + msg.header_len;
struct mg_ws_message m = {{s, msg.data_len}, msg.flags}; struct mg_ws_message m = {{s, msg.data_len}, msg.flags};
switch (msg.flags & WEBSOCKET_FLAGS_MASK_OP) { size_t len = msg.header_len + msg.data_len;
uint8_t final = msg.flags & 128, op = msg.flags & 15;
// LOG(LL_VERBOSE_DEBUG, ("fin %d op %d len %d [%.*s]", final, op,
// (int) m.data.len, (int) m.data.len, m.data.ptr));
switch (op) {
case WEBSOCKET_OP_CONTINUE: case WEBSOCKET_OP_CONTINUE:
mg_call(c, MG_EV_WS_CTL, &m); mg_call(c, MG_EV_WS_CTL, &m);
break; break;
@@ -147,7 +171,7 @@ static void mg_ws_cb(struct mg_connection *c, int ev, void *ev_data,
break; break;
case WEBSOCKET_OP_TEXT: case WEBSOCKET_OP_TEXT:
case WEBSOCKET_OP_BINARY: case WEBSOCKET_OP_BINARY:
mg_call(c, MG_EV_WS_MSG, &m); if (final) mg_call(c, MG_EV_WS_MSG, &m);
break; break;
case WEBSOCKET_OP_CLOSE: case WEBSOCKET_OP_CLOSE:
LOG(LL_ERROR, ("%lu Got WS CLOSE", c->id)); LOG(LL_ERROR, ("%lu Got WS CLOSE", c->id));
@@ -156,10 +180,30 @@ static void mg_ws_cb(struct mg_connection *c, int ev, void *ev_data,
break; break;
default: default:
// Per RFC6455, close conn when an unknown op is recvd // Per RFC6455, close conn when an unknown op is recvd
mg_error(c, "unknown WS op %d", msg.flags & WEBSOCKET_FLAGS_MASK_OP); mg_error(c, "unknown WS op %d", op);
break; break;
} }
mg_iobuf_delete(&c->recv, msg.header_len + msg.data_len);
// Handle fragmented frames: strip header, keep in c->recv
if (final == 0 || op == 0) {
if (op) ofs++, len--, msg.header_len--; // First frame
mg_iobuf_del(&c->recv, ofs, msg.header_len); // Strip header
len -= msg.header_len;
ofs += len;
c->pfn_data = (void *) ofs;
// LOG(LL_INFO, ("FRAG %d [%.*s]", (int) ofs, (int) ofs, c->recv.buf));
}
// Remove non-fragmented frame
if (final && op) mg_iobuf_del(&c->recv, ofs, len);
// Last chunk of the fragmented frame
if (final && !op) {
m.flags = c->recv.buf[0];
m.data = mg_str_n((char *) &c->recv.buf[1], (size_t) (ofs - 1));
mg_call(c, MG_EV_WS_MSG, &m);
mg_iobuf_del(&c->recv, 0, ofs);
ofs = 0;
c->pfn_data = NULL;
}
} }
} }
(void) fn_data; (void) fn_data;
@@ -199,7 +243,7 @@ struct mg_connection *mg_ws_connect(struct mg_mgr *mgr, const char *url,
if (buf1 != mem1) free(buf1); if (buf1 != mem1) free(buf1);
if (buf2 != mem2) free(buf2); if (buf2 != mem2) free(buf2);
c->pfn = mg_ws_cb; c->pfn = mg_ws_cb;
c->fn_data = fn_data; c->pfn_data = NULL;
} }
return c; return c;
} }
@@ -208,11 +252,31 @@ void mg_ws_upgrade(struct mg_connection *c, struct mg_http_message *hm,
const char *fmt, ...) { const char *fmt, ...) {
struct mg_str *wskey = mg_http_get_header(hm, "Sec-WebSocket-Key"); struct mg_str *wskey = mg_http_get_header(hm, "Sec-WebSocket-Key");
c->pfn = mg_ws_cb; c->pfn = mg_ws_cb;
if (wskey != NULL) { c->pfn_data = NULL;
if (wskey == NULL) {
mg_http_reply(c, 426, "", "WS upgrade expected\n");
c->is_draining = 1;
} else {
struct mg_str *wsproto = mg_http_get_header(hm, "Sec-WebSocket-Protocol");
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
ws_handshake(c, wskey->ptr, wskey->len, fmt, ap); ws_handshake(c, wskey, wsproto, fmt, ap);
va_end(ap); va_end(ap);
c->is_websocket = 1;
mg_call(c, MG_EV_WS_OPEN, hm);
} }
c->is_websocket = 1; }
size_t mg_ws_wrap(struct mg_connection *c, size_t len, int op) {
uint8_t header[14], *p;
size_t header_len = mkhdr(len, op, c->is_client, header);
// NOTE: order of operations is important!
mg_iobuf_add(&c->send, c->send.len, NULL, header_len, MG_IO_SIZE);
p = &c->send.buf[c->send.len - len]; // p points to data
memmove(p, p - header_len, len); // Shift data
memcpy(p - header_len, header, header_len); // Prepend header
mg_ws_mask(c, len); // Mask data
return c->send.len;
} }
+3 -5
View File
@@ -7,14 +7,11 @@
#define WEBSOCKET_OP_PING 9 #define WEBSOCKET_OP_PING 9
#define WEBSOCKET_OP_PONG 10 #define WEBSOCKET_OP_PONG 10
#define WEBSOCKET_FLAGS_MASK_FIN 128
#define WEBSOCKET_FLAGS_MASK_OP 15
#include "http.h" #include "http.h"
struct mg_ws_message { struct mg_ws_message {
struct mg_str data; struct mg_str data; // Websocket message data
uint8_t flags; // Websocket message flags uint8_t flags; // Websocket message flags
}; };
struct mg_connection *mg_ws_connect(struct mg_mgr *, const char *url, struct mg_connection *mg_ws_connect(struct mg_mgr *, const char *url,
@@ -23,3 +20,4 @@ struct mg_connection *mg_ws_connect(struct mg_mgr *, const char *url,
void mg_ws_upgrade(struct mg_connection *, struct mg_http_message *, void mg_ws_upgrade(struct mg_connection *, struct mg_http_message *,
const char *fmt, ...); const char *fmt, ...);
size_t mg_ws_send(struct mg_connection *, const char *buf, size_t len, int op); size_t mg_ws_send(struct mg_connection *, const char *buf, size_t len, int op);
size_t mg_ws_wrap(struct mg_connection *, size_t len, int op);
+57 -21
View File
@@ -1,25 +1,36 @@
Subject: O=Digital Signature Trust Co., CN=DST Root CA X3 Issuer: C = US, O = Internet Security Research Group, CN = ISRG Root X1
Not Before: Sep 30 21:12:19 2000 GMT Not Before: Jun 4 11:04:38 2015 GMT
Not After : Sep 30 14:01:15 2021 GMT Not After : Jun 4 11:04:38 2035 GMT
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/ MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b 0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69 KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5 qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE----- -----END CERTIFICATE-----
Subject: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root Subject: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root
@@ -245,6 +256,31 @@ iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn
sSi6 sSi6
-----END CERTIFICATE----- -----END CERTIFICATE-----
Subject: C = BE, O = GlobalSign nv-sa, OU = Root CA, CN = GlobalSign Root CA
Not Before: Sep 1 12:00:00 1998 GMT
Not After : Jan 28 12:00:00 2028 GMT
-----BEGIN CERTIFICATE-----
MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG
A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw
MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT
aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ
jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp
xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp
1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG
snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ
U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8
9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B
AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz
yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE
38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP
AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad
DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME
HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
-----END CERTIFICATE-----
Subject: OU=GlobalSign Root CA - R2, O=GlobalSign, CN=GlobalSign Subject: OU=GlobalSign Root CA - R2, O=GlobalSign, CN=GlobalSign
Not Before: Dec 15 08:00:00 2006 GMT Not Before: Dec 15 08:00:00 2006 GMT
Not After : Dec 15 08:00:00 2021 GMT Not After : Dec 15 08:00:00 2021 GMT
Loaded 100 of 98 files, more files were not shown because too many files have changed in this diff. Show more