Add HTTPS server examples
This commit is contained in:
@@ -6,3 +6,7 @@
|
||||
002_proxy.exe
|
||||
003_virtual_hosts
|
||||
003_virtual_hosts.exe
|
||||
004_https_server
|
||||
004_https_server.exe
|
||||
005_virtual_hosts_over_https
|
||||
005_virtual_hosts_over_https.exe
|
||||
|
||||
@@ -17,7 +17,7 @@ endif
|
||||
|
||||
.PHONY: all clean example
|
||||
|
||||
all: chttp.c chttp.h 000_simple_client$(EXT) 001_simple_server$(EXT) 002_proxy$(EXT) 003_virtual_hosts$(EXT)
|
||||
all: chttp.c chttp.h 000_simple_client$(EXT) 001_simple_server$(EXT) 002_proxy$(EXT) 003_virtual_hosts$(EXT) 004_https_server$(EXT) 005_virtual_hosts_over_https$(EXT)
|
||||
|
||||
chttp.c chttp.h: $(wildcard src/*.c src/*.h) misc/amalg.py Makefile
|
||||
python misc/amalg.py
|
||||
@@ -26,4 +26,4 @@ chttp.c chttp.h: $(wildcard src/*.c src/*.h) misc/amalg.py Makefile
|
||||
gcc $< chttp.c -o $@ $(CFLAGS) $(LFLAGS)
|
||||
|
||||
clean:
|
||||
rm chttp.c chttp.h 000_simple_client 000_simple_client.exe 001_simple_server 001_simple_server.exe 002_proxy 002_proxy.exe 003_virtual_hosts 003_virtual_hosts.exe
|
||||
rm chttp.c chttp.h 000_simple_client 000_simple_client.exe 001_simple_server 001_simple_server.exe 002_proxy 002_proxy.exe 003_virtual_hosts 003_virtual_hosts.exe 004_https_server 004_https_server.exe 005_virtual_hosts_over_https 005_virtual_hosts_over_https.exe
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#include "../chttp.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
HTTP_String local_addr = HTTP_STR("127.0.0.1");
|
||||
uint16_t local_port = 8443;
|
||||
|
||||
HTTP_String cert_file = HTTP_STR("websiteA_cert.pem");
|
||||
HTTP_String key_file = HTTP_STR("websiteA_key.pem");
|
||||
|
||||
HTTP_Server server;
|
||||
int ret = http_server_init(&server);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Couldn't initialize server (%s)\n", http_strerror(ret));
|
||||
return -1;
|
||||
}
|
||||
|
||||
http_server_set_reuse_addr(&server, true);
|
||||
http_server_set_trace_bytes(&server, true);
|
||||
|
||||
ret = http_server_listen_tls(&server, local_addr, local_port, cert_file, key_file);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Couldn't start listening (%s)\n", http_strerror(ret));
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
|
||||
HTTP_Request *req;
|
||||
HTTP_ResponseBuilder builder;
|
||||
http_server_wait_request(&server, &req, &builder);
|
||||
|
||||
http_response_builder_status(builder, 200);
|
||||
http_response_builder_body(builder, HTTP_STR("Hello from websiteA.com!"));
|
||||
http_response_builder_send(builder);
|
||||
}
|
||||
|
||||
http_server_free(&server);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#include "../chttp.h"
|
||||
|
||||
// This is an example of how to serve different websites
|
||||
// over a single HTTPS server instance.
|
||||
|
||||
int setup_test_certificates(void);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// To test this program you need to add the following
|
||||
// lines to your hosts file:
|
||||
//
|
||||
// 127.0.0.1 websiteA.com
|
||||
// 127.0.0.1 websiteB.com
|
||||
// 127.0.0.1 websiteC.com
|
||||
//
|
||||
// That you can find at /etc/hosts on Linux and
|
||||
// C:\Windows\System32\drivers\etc\hosts on Windows
|
||||
|
||||
// First, create three certificates for the domains:
|
||||
//
|
||||
// websiteA.com
|
||||
// websiteB.com
|
||||
// websiteC.com
|
||||
//
|
||||
// This will create a number of certificate files
|
||||
// and private key files
|
||||
//
|
||||
// websiteA_cert.pem websiteA_key.pem
|
||||
// websiteB_cert.pem websiteB_key.pem
|
||||
// websiteC_cert.pem websiteC_key.pem
|
||||
//
|
||||
// Of course this is just for testing. It is expected
|
||||
// you have your own.
|
||||
int ret = setup_test_certificates();
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
HTTP_Server server;
|
||||
ret = http_server_init(&server);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Couldn't initialize server (%s)\n", http_strerror(ret));
|
||||
return -1;
|
||||
}
|
||||
|
||||
http_server_set_reuse_addr(&server, true);
|
||||
http_server_set_trace_bytes(&server, true);
|
||||
|
||||
|
||||
// First, set up an HTTPS server instance with one
|
||||
// of the certificate. This will act as default certificate
|
||||
// when ecrypted connections don't target a specific domain.
|
||||
|
||||
HTTP_String local_addr = HTTP_STR("127.0.0.1");
|
||||
uint16_t local_port = 8443;
|
||||
|
||||
HTTP_String cert_file = HTTP_STR("websiteA_cert.pem");
|
||||
HTTP_String key_file = HTTP_STR("websiteA_key.pem");
|
||||
|
||||
ret = http_server_listen_tls(&server, local_addr, local_port, cert_file, key_file);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Couldn't start listening (%s)\n", http_strerror(ret));
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Then we can add an arbitrary number of additional
|
||||
// certificates using the add_website function
|
||||
|
||||
ret = http_server_add_certificate(&server,
|
||||
HTTP_STR("websiteB.com"),
|
||||
HTTP_STR("websiteB_cert.pem"),
|
||||
HTTP_STR("websiteB_key.pem"));
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
ret = http_server_add_certificate(&server,
|
||||
HTTP_STR("websiteC.com"),
|
||||
HTTP_STR("websiteC_cert.pem"),
|
||||
HTTP_STR("websiteC_key.pem"));
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
// Now the server is ready to accept incoming HTTP
|
||||
// or HTTPS connections.
|
||||
//
|
||||
// Note that the add_website function is only used
|
||||
// to serve the correct certificate to the client.
|
||||
// The HTTP request itself may very well hold a
|
||||
// different domain name in the host header:
|
||||
//
|
||||
// [client] [server]
|
||||
// | |
|
||||
// | TLS hanshake to domain1.com |
|
||||
// | -------------------------------> |
|
||||
// | |
|
||||
// | cert for domain1.com |
|
||||
// | <------------------------------- |
|
||||
// | |
|
||||
// | HTTP request to domain2.com |
|
||||
// | over the encrypted connection |
|
||||
// | established with domain1.com |
|
||||
// | -------------------------------> |
|
||||
// | |
|
||||
// | response as domain2.com |
|
||||
// | <------------------------------- |
|
||||
// | |
|
||||
|
||||
for (;;) {
|
||||
|
||||
HTTP_Request *req;
|
||||
HTTP_ResponseBuilder builder;
|
||||
http_server_wait_request(&server, &req, &builder);
|
||||
|
||||
if (http_match_host(req, HTTP_STR("websiteB.com"), 8080) ||
|
||||
http_match_host(req, HTTP_STR("websiteB.com"), 8443)) {
|
||||
|
||||
http_response_builder_status(builder, 200);
|
||||
http_response_builder_body(builder, HTTP_STR("Hello from websiteB.com!"));
|
||||
http_response_builder_send(builder);
|
||||
|
||||
} else if (http_match_host(req, HTTP_STR("websiteC.com"), 8080) ||
|
||||
http_match_host(req, HTTP_STR("websiteC.com"), 8443)) {
|
||||
|
||||
http_response_builder_status(builder, 200);
|
||||
http_response_builder_body(builder, HTTP_STR("Hello from websiteC.com!"));
|
||||
http_response_builder_send(builder);
|
||||
|
||||
} else {
|
||||
|
||||
// Serve websiteA.com by default to be consistent
|
||||
// with the certificate setup
|
||||
|
||||
http_response_builder_status(builder, 200);
|
||||
http_response_builder_body(builder, HTTP_STR("Hello from websiteA.com!"));
|
||||
http_response_builder_send(builder);
|
||||
}
|
||||
}
|
||||
|
||||
http_server_free(&server);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int setup_test_certificates(void)
|
||||
{
|
||||
int ret = http_create_test_certificate(
|
||||
HTTP_STR("IT"),
|
||||
HTTP_STR("Organization A"),
|
||||
HTTP_STR("websiteA.com"),
|
||||
HTTP_STR("websiteA_cert.pem"),
|
||||
HTTP_STR("websiteA_key.pem")
|
||||
);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
ret = http_create_test_certificate(
|
||||
HTTP_STR("IT"),
|
||||
HTTP_STR("Organization B"),
|
||||
HTTP_STR("websiteB.com"),
|
||||
HTTP_STR("websiteB_cert.pem"),
|
||||
HTTP_STR("websiteB_key.pem")
|
||||
);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
ret = http_create_test_certificate(
|
||||
HTTP_STR("IT"),
|
||||
HTTP_STR("Organization C"),
|
||||
HTTP_STR("websiteC.com"),
|
||||
HTTP_STR("websiteC_cert.pem"),
|
||||
HTTP_STR("websiteC_key.pem")
|
||||
);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user