Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate experimental HTTP/2 support #37

Merged
merged 10 commits into from
Jul 12, 2024
7 changes: 7 additions & 0 deletions examples/http2/dub.sdl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
name "http2-example"

dependency "vibe-http" path="../../../vibe-http"

/*versions "VibeForceALPN"*/
targetType "executable"
/*buildOptions "profileGC"*/
20 changes: 20 additions & 0 deletions examples/http2/server.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDUjCCAjoCCQDPHygOhe1ZVjANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQGEwJE
RTEbMBkGA1UECBMSU2NobGVzd2lnLUhvbHN0ZWluMRAwDgYDVQQHFAdMw7xiZWNr
MRkwFwYDVQQKExBvdXRlcnByb2R1Y3Qub3JnMRIwEAYDVQQDEwlsb2NhbGhvc3Qw
HhcNMTIwMjE0MjAxNDM0WhcNMTMwMjEzMjAxNDM0WjBrMQswCQYDVQQGEwJERTEb
MBkGA1UECBMSU2NobGVzd2lnLUhvbHN0ZWluMRAwDgYDVQQHFAdMw7xiZWNrMRkw
FwYDVQQKExBvdXRlcnByb2R1Y3Qub3JnMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC4fLPWRShlq+o6vM5nhUCtR+IN
mlAlQCzM3asWpQ76T/MOX1Ci1brypRgOXCmYI8c5lFGOIMpH1ZAh987t4UdkwVCn
76pXv5yY4U1jJ5i9v7R7IUeKZ7utwlq1jPo3WWhiZwm1o6AxVRHGiUQ5XrcX0Rgt
0bh9/5BWHLks3OJ44myjpgGv2J7n1LcyecRAd+suN4qsBiTITQBYq27WYsDCqrVB
BoyCPhb51xTlaMlcAH2ekrm886FlC95VrwV7o4jb4sRGYdfKqT6HwXK1yTB3n742
2WavDgRj2vNQaL+XoPiBOrQZ8fj9PeWCyefSEtqz8/dpnJO+pxidKAow8As5AgMB
AAEwDQYJKoZIhvcNAQEFBQADggEBAA8N27Wb9aq9JkAEGZ0Z/CLHbLeV3UQ5qb9V
6KG8vvSoew3oxMlcHa49kq89AKx/gewt4fqCAHk64qpx8aEdbYorTbo9VIbwoLek
9Lyp+AynmqDA6zk5+uOtPkwfN84f30khH04ouSmOvbV+uqD9bVZtR8ULTzbuE2h1
jbT64JQd+GW/uLQ770EKDVFml52BMJWrRFFgaRQhkm9k8krKqsCvYfMoULk3EQqS
b5a/5q9pirXB7AHmiYAnqDu2xQL8N5e548RTZSWNl7mZD1NvVYc4l8tSKfCC3zG3
4wKngPl6t68pdnli67lX3YDTdHgOZWL+CsJT9TIRAOojfp5kWGY=
-----END CERTIFICATE-----
27 changes: 27 additions & 0 deletions examples/http2/server.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAuHyz1kUoZavqOrzOZ4VArUfiDZpQJUAszN2rFqUO+k/zDl9Q
otW68qUYDlwpmCPHOZRRjiDKR9WQIffO7eFHZMFQp++qV7+cmOFNYyeYvb+0eyFH
ime7rcJatYz6N1loYmcJtaOgMVURxolEOV63F9EYLdG4ff+QVhy5LNzieOJso6YB
r9ie59S3MnnEQHfrLjeKrAYkyE0AWKtu1mLAwqq1QQaMgj4W+dcU5WjJXAB9npK5
vPOhZQveVa8Fe6OI2+LERmHXyqk+h8Fytckwd5++Ntlmrw4EY9rzUGi/l6D4gTq0
GfH4/T3lgsnn0hLas/P3aZyTvqcYnSgKMPALOQIDAQABAoIBABdkiJEk18h8kgi8
pBdwSBEwyjMbXAo9JvEbMnR+nXWT6afq4hijrT7TPEel3AhUkRB2BBlXgw60v7/u
4ig7pofaE1YYB6t0unCQMPXfsXht9H6ga6fbG2se982JgLi/94JyukJz6v4WYVih
UytLHUBB3SUCMLiZTT3+CmTr5TOamtcUi9ZNKtbxT2l+8iDbi7WaCUznrODZ8YMn
/5RhE3XopBuCmeT8P7EhJSHe1THEcCcXtlChb7bMU7DMpvWYp9XBM4CQ2PpdHN5x
bvKP8P6IH0TpjdBrdE16yO9P14saJoy1GSOx8y6zUxTMdgyFUnXK4bC+nUi3VRrq
cikR3GECgYEA9MUsGAhVF8CRUsgvbn/q1QM1oFG1Dj1+LYEnXXNbdOugZVj2L8eT
olAFFjprciemADmqhnxNgM0Ev+RVZzSDZFrAhQ+NYKw6JQe/EfIvnGyt5GXnoIJQ
4hsibRH2UDHoGzxWTwcxbOdM3mqnY3WCMA3JWoLDEqApGRDh/hFFYtUCgYEAwPOB
Ryfx5wTg/HM2kaVETgPkML81PvGdJxgKDW6XabEVdqf3Ds1UfELHRCK0LH0RS+8L
5GDBuBeAuhpXtzkmwK30rTMfVqxi7IlddcYpBqCg9bHdyg6iAI2htwm+j9aLSCPw
uNeCSqIYKIvLrcvrFWOlLRYonSxlyj7XLFypkNUCgYAnjkGs9JPDzePuS9mWcueh
Wu5spSesUHW2ptuUt5K9F2MJXdITMJ6EKYhY6kH45b1m5erP5wCjYv50gFLo5cyi
CCR6nGPNjqeq2lCfdtMI5WtIsMs43jZyA86Rb8itdxM6a4rLJK9xGQQMIZJBeXj7
iQ7UKLObq/RYT6kl5OagrQKBgGLsdRtGH3+RwMetSgzh7mMRG6ziWyoqNagVaxH3
4SkO4TI0azXrj6Ull4QXRsiIVpXXuQEdmjQH2LeRSedmJbgjd45U53xIZW9f/cqk
DeSX9e4BgvRVDDm8Y2y0Uj7sf/w8cO5Tjzk0Ya5n/cTdB2mv7L9w3OG4IXfPQAI+
f7EBAoGBAKgvIg/bvF705Lg2bebjR2MVeVySDZP/SjY5my+4cF8VSJOK+8WA1MeJ
dv4sukGjAMrMApegKmaiIngb2izINfanEd0xn4h1nCwVcRaNr9fSkZDBhi+JErol
0janntvmByXPD0BXguza7NVJGmtzCyZk+rOHtC1J+qG7kdXHpPYT
-----END RSA PRIVATE KEY-----
100 changes: 100 additions & 0 deletions examples/http2/source/app.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/* ==== Vibe.d HTTP/2 Webserver Example ==== */
/* Supports both HTTP and HTTPS transport */
/* Transparent (WIP: exposing settings) */
/* ========================================= */

import vibe.http.server;
import vibe.stream.tls;
import vibe.http.internal.http2.server : http2Callback; // ALPN negotiation
import vibe.core.core : runApplication;

/* ==== declare two handlers (could use the same one) ==== */
void handleReq(HTTPServerRequest req, HTTPServerResponse res)
@safe {
if (res.httpVersion == HTTPVersion.HTTP_2)
res.writeBody("Hello, you connected to "~req.path~"! This response is sent through HTTP/2\n");
else
res.writeBody("Hello, World! You connected through HTTP/1, try using HTTP/2!\n");
}

void tlsHandleReq(HTTPServerRequest req, HTTPServerResponse res)
@safe {
if (req.httpVersion == HTTPVersion.HTTP_2)
res.writeBody("Hello, you connected to "~req.path~"! This response is sent through HTTP/2 with TLS\n");
else
res.writeBody("Hello, World! You connected through HTTP/1 with TLS, try using HTTP/2!\n");
}

// sends a very big data frame
void bigHandleReq(size_t DIM)(HTTPServerRequest req, HTTPServerResponse res)
@trusted {
import vibe.container.internal.appender : FixedAppender;
import std.range : iota;

FixedAppender!(immutable(char)[], DIM) appender;

if (req.path == "/") {
foreach(i; iota(1,DIM-4)) appender.put('1');
appender.put(['O','k','!', '\n']);
res.writeBody(appender.data);
}
}

void main()
{
//import vibe.core.log;
//setLogLevel(LogLevel.trace);
HTTPListener[] listeners;

/* ==== cleartext HTTP/2 support (h2c) ==== */
auto settings = new HTTPServerSettings;
settings.port = 8090;
settings.bindAddresses = ["127.0.0.1"];
settings.options |= HTTPServerOption.enableHTTP2;
listeners ~= listenHTTP(settings, &handleReq);

/* ==== cleartext HTTP/2 support (h2c) with a heavy DATA frame ==== */
auto bigSettings = new HTTPServerSettings;
bigSettings.port = 8092;
bigSettings.bindAddresses = ["127.0.0.1"];
bigSettings.options |= HTTPServerOption.enableHTTP2;
listeners ~= listenHTTP(bigSettings, &bigHandleReq!100000);

/* ========== HTTPS (h2) support ========== */
auto tlsSettings = new HTTPServerSettings;
tlsSettings.port = 8091;
tlsSettings.bindAddresses = ["127.0.0.1"];
tlsSettings.options |= HTTPServerOption.enableHTTP2;

/// setup TLS context by using cert and key in example rootdir
tlsSettings.tlsContext = createTLSContext(TLSContextKind.server);
tlsSettings.tlsContext.useCertificateChainFile("server.crt");
tlsSettings.tlsContext.usePrivateKeyFile("server.key");

// set alpn callback to support HTTP/2 protocol negotiation
tlsSettings.tlsContext.alpnCallback(http2Callback);
listeners ~= listenHTTP(tlsSettings, &tlsHandleReq);

/* ========== HTTPS (h2) support with a heavy DATA frame ========== */
auto bigTLSSettings = new HTTPServerSettings;
bigTLSSettings.port = 8093;
bigTLSSettings.bindAddresses = ["127.0.0.1"];
bigTLSSettings.options |= HTTPServerOption.enableHTTP2;

/// setup TLS context by using cert and key in example rootdir
bigTLSSettings.tlsContext = createTLSContext(TLSContextKind.server);
bigTLSSettings.tlsContext.useCertificateChainFile("server.crt");
bigTLSSettings.tlsContext.usePrivateKeyFile("server.key");

// set alpn callback to support HTTP/2 protocol negotiation
bigTLSSettings.tlsContext.alpnCallback(http2Callback);
listeners ~= listenHTTP(bigTLSSettings, &bigHandleReq!100000);

scope(exit)
foreach (l; listeners)
l.stopListening();

/* ========== Run both `listenHTTP` handlers ========== */
// UNCOMMENT to run
runApplication();
}
4 changes: 3 additions & 1 deletion source/vibe/http/common.d
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ import std.uni: asLowerCase, sicmp;

enum HTTPVersion {
HTTP_1_0,
HTTP_1_1
HTTP_1_1,
HTTP_2
}


Expand Down Expand Up @@ -362,6 +363,7 @@ nothrow pure @nogc @safe {
final switch(ver){
case HTTPVersion.HTTP_1_0: return "HTTP/1.0";
case HTTPVersion.HTTP_1_1: return "HTTP/1.1";
case HTTPVersion.HTTP_2: return "HTTP/2";
}
}

Expand Down
Loading
Loading