Skip to content

feat: add funtionallity to run TLS server #53

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

Merged
merged 1 commit into from
Oct 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 27 additions & 7 deletions kid.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,20 +77,29 @@ func New() *Kid {
// Run runs HTTP server.
//
// Specifying an address is optional. Default address is :2376.
func (k *Kid) Run(address ...string) error {
addr := resolveAddress(address, runtime.GOOS)
func (k *Kid) Run(addrs ...string) error {
address := k.setUpServer(addrs)

k.printDebug(os.Stdout, "Kid version %s\n", Version)
k.printDebug(os.Stdout, "Starting server at %s\n", addr)
k.printDebug(os.Stdout, "Starting server at %s\n", address)
k.printDebug(os.Stdout, "Quit the server with CONTROL-C\n")

k.mutex.Lock()
k.server = &http.Server{Addr: addr, Handler: k}
k.mutex.Unlock()

return k.server.ListenAndServe()
}

// Run runs HTTPS server.
//
// Specifying an address is optional. Default address is :2376.
func (k *Kid) RunTLS(certFile, keyFile string, addrs ...string) error {
address := k.setUpServer(addrs)

k.printDebug(os.Stdout, "Kid version %s\n", Version)
k.printDebug(os.Stdout, "Starting TLS server at %s\n", address)
k.printDebug(os.Stdout, "Quit the server with CONTROL-C\n")

return k.server.ListenAndServeTLS(certFile, keyFile)
}

// Shutdown gracefully shuts down the server without interrupting any active connections.
func (k *Kid) Shutdown(ctx context.Context) error {
k.mutex.Lock()
Expand Down Expand Up @@ -267,6 +276,17 @@ func (k *Kid) ApplyOptions(opts ...Option) {
}
}

// setupServer sets up the server.
func (k *Kid) setUpServer(addrs []string) string {
address := resolveAddress(addrs, runtime.GOOS)

k.mutex.Lock()
defer k.mutex.Unlock()

k.server = &http.Server{Addr: address, Handler: k}
return address
}

// printDebug prints logs only in debug mode.
func (k *Kid) printDebug(w io.Writer, format string, values ...any) {
if k.Debug() {
Expand Down
43 changes: 43 additions & 0 deletions kid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package kid
import (
"bytes"
"context"
"crypto/tls"
"fmt"
"io"
"net/http"
Expand Down Expand Up @@ -447,6 +448,39 @@ func TestKid_Run(t *testing.T) {
assert.Equal(t, "{\"message\":\"healthy\"}\n", string(body))
}

func TestKid_RunTLS(t *testing.T) {
k := New()

k.Get("/", func(c *Context) {
c.JSON(http.StatusOK, Map{"message": "healthy"})
})

go func() {
err := k.RunTLS("./testdata/certs/localhost.crt", "./testdata/certs/localhost.key", ":8686")
assert.NoError(t, err)
}()

// Wait for the server to start
time.Sleep(5 * time.Millisecond)

client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
}

resp, err := client.Get("https://localhost:8686")
assert.NoError(t, err)

defer resp.Body.Close()

body, err := io.ReadAll(resp.Body)
assert.NoError(t, err)
assert.Equal(t, http.StatusOK, resp.StatusCode)
assert.Equal(t, "application/json", resp.Header.Get("Content-Type"))
assert.Equal(t, "{\"message\":\"healthy\"}\n", string(body))
}

func TestKid_Shutdown(t *testing.T) {
k := New()

Expand All @@ -461,6 +495,15 @@ func TestKid_Shutdown(t *testing.T) {
assert.NoError(t, k.Shutdown(context.Background()))
}

func TestKid_setUpServer(t *testing.T) {
k := New()

address := k.setUpServer([]string{":2377"})

assert.NotNil(t, k.server)
assert.Equal(t, ":2377", address)
}

func TestKid_Static(t *testing.T) {
k := New()

Expand Down
7 changes: 7 additions & 0 deletions testdata/certs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Generate new certs using this command:
```
openssl req -x509 -out localhost.crt -keyout localhost.key -days 9999 \
-newkey rsa:2048 -nodes -sha256 \
-subj '/CN=localhost' -extensions EXT -config <( \
printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")
```
19 changes: 19 additions & 0 deletions testdata/certs/localhost.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDETCCAfmgAwIBAgIUOoxYk6MjSdK8TWQR0Fzm2ziQWCQwDQYJKoZIhvcNAQEL
BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MCAXDTIzMTAxMzIzNTkxMVoYDzIwNTEw
MjI3MjM1OTExWjAUMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQDX7pwPNBWBa2B4vX0YkEP22MpGUiYOi0y30FnCEYZI
kZRBPcYdU7q9ojKV5qyWPYivgqehFcDdH4b2o8sGYYk+ZAmX4i3FGvwzIymCO9DX
wOKiP5bLvBTRvY3I7NswgGbd/X7hVEZgYQLEJE8menV7cTmINtK+Kr5LA7W8wURv
Z3UIlBZdOHeR8QxdBrQ/PT13BLPtqxO6AuylP6gsq7rvqMvwgk0iouPyquqhmAy3
xh7KPpVzw268cNHFaE5launFKHnZ6TiskzddS/CsQYMthr/K1zmLMm810GSUkNRb
8MVtf+w5sqsE/2g5kgpNsX9w4RoG+JfHvkAbL14DeGslAgMBAAGjWTBXMBQGA1Ud
EQQNMAuCCWxvY2FsaG9zdDALBgNVHQ8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUH
AwEwHQYDVR0OBBYEFE7pmc57y/WqzIkTdw95gVjwht1mMA0GCSqGSIb3DQEBCwUA
A4IBAQC3kd5M9mj5wUDpcI3gPe585LaOXbhBBHx5j4v3TJPUwq8eshWYGnBEbcma
jRk/QH5BJMrdC1x5wb2UAJuFgpFBH6EZJXBiivhHAD0vxKc85T7Ee4Vamgxoi6UY
opiUdkhSbrm3gNZEGX1Zpt73YxjoAiqFlFcNfCrAyPFaSQTX6PPsRcSr/vgUdeW6
LuxGtR20ry+XY2fixButx+n+F52vhyKiqLEjEYCXmYLuYeaFZeCFkfIR1HdOVpU6
2q1ovLNhCNNJ4oV+uGjc0fN3wDIbAiX+kTKOPOYzyXavug38y/Yy1cXZzZUJa9Jq
kZQ7WstTDwzkQ7OcnLz16NhUEEHb
-----END CERTIFICATE-----
28 changes: 28 additions & 0 deletions testdata/certs/localhost.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDX7pwPNBWBa2B4
vX0YkEP22MpGUiYOi0y30FnCEYZIkZRBPcYdU7q9ojKV5qyWPYivgqehFcDdH4b2
o8sGYYk+ZAmX4i3FGvwzIymCO9DXwOKiP5bLvBTRvY3I7NswgGbd/X7hVEZgYQLE
JE8menV7cTmINtK+Kr5LA7W8wURvZ3UIlBZdOHeR8QxdBrQ/PT13BLPtqxO6Auyl
P6gsq7rvqMvwgk0iouPyquqhmAy3xh7KPpVzw268cNHFaE5launFKHnZ6Tiskzdd
S/CsQYMthr/K1zmLMm810GSUkNRb8MVtf+w5sqsE/2g5kgpNsX9w4RoG+JfHvkAb
L14DeGslAgMBAAECggEADIvwxXFhToPOtzVLb4HycQVnu25Kh83QR13z2TLreov6
8U+Fk26qCxrBlbQxkwlAR/JviwyYiECstugNg/Fm6Bkn9YtO3YUT4mTIpKiVGfQ7
NvI68Nuc2hMJigM5OTg8welY1f7vl+oLHxp8/t9etC2ACkolNKeHJxSwGqegMljV
POPQzpGST4kVFu1CQNlummmPusSVGMzba0r1F76UsH+5eSdPegNKu53bQXHY8bRW
NarAFe3XX8H3dUC5hwVIJAucf7xUJ1wjIKx7m1IlAVAayuq6d2hIfHEVsdrH2+Eb
GpSq077BsHbnEyb/74bzQQQeie3NQzWFRCf9I370AQKBgQDztUhWhiILnvtyPbrw
BGyxm+RI9dRksj1sqdYUzJ13JfTZfHEAmbkH1plbk1SXYcqsBIFA109kDPZb9sN8
af4k1szzsGu1S0q/WaGAqSfElLk1oDeSp4O2w5q7Wt1XbyqKmf8YFSHtnqP53o1P
uipDCEz0iy0f048B+eI4eVbXXQKBgQDi0q/wFVByVBNopIQoY/qIXuFZd4x5bL/W
j2uzdmWhbfpErhlS5k6mZskHksLCit7zLO9/lzbpgJkrGnamb6xJrqShXZpLMwLs
ZZMGE2LdjsdZBa5ZTOjPytfwBPaZhOlBkee5wx1INWBNaSGQMBt8aSidAn6diG81
8zvZeS8OaQKBgFdjTckY1+Rq4acZU4r1SzR0vesbm0lwUG5CiC11IZGz3pSN9sdM
V/jjjqIztkWCH3aHNwHVMvahX0Wiun5GU4dKLrvDKxwbH3Z14V+NSGFJIxCDnunL
f4NtqHI+JthPWGXSypIMIdpe5FWY4/sOulDHDTEzJr8e0UzYGbI+cFFRAoGAGefQ
Ok5k4rnhgZkQkwBgM8UKXcp+m7uk6V92AIgsMVS7Oa7cq5AsOWsR2LCVV9y+e+2M
6PifR+ntFHQwSvAEMGIm4VssbRxFYDR1p0L9jqpo8Czq7b4P9POI2BvpAj2g2mFM
ovW62W1nM1Anii1EZmAoSE5poZpcgT/nfP4PNskCgYEApaab6ild/555vPjacniI
Eor8QdvRHXXyKgpfK9U0npI+JxFgCW7A5JVnnDKrSRvTRWL2Nb1+e5yyZuKY0gSJ
Bdlg16F6gxHVP9AUoYExf7xZJYQcbn3RG+z7bDcjeD5A+dJvLG4bs6YsDRooojvp
kKDphAOwspt5QCQeAKTB1lc=
-----END PRIVATE KEY-----