Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Michal Witkowski committed Oct 31, 2016
0 parents commit 3f7fc8b
Show file tree
Hide file tree
Showing 5 changed files with 325 additions and 0 deletions.
163 changes: 163 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
# Created by .ignore support plugin (hsz.mobi)
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839

# User-specific stuff:
.idea
.idea/workspace.xml
.idea/tasks.xml
.idea/dictionaries
.idea/vcs.xml
.idea/jsLibraryMappings.xml

# Sensitive or high-churn files:
.idea/dataSources.ids
.idea/dataSources.xml
.idea/dataSources.local.xml
.idea/sqlDataSources.xml
.idea/dynamic.xml
.idea/uiDesigner.xml

# Gradle:
.idea/gradle.xml
.idea/libraries

# Mongo Explorer plugin:
.idea/mongoSettings.xml

## File-based project format:
*.iws

## Plugin-specific files:

# IntelliJ
/out/

# mpeltonen/sbt-idea plugin
.idea_modules/

# JIRA plugin
atlassian-ide-plugin.xml

# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
### Go template
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so

# Folders
_obj
_test

# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out

*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*

_testmain.go

*.exe
*.test
*.prof
### Python template
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# IPython Notebook
.ipynb_checkpoints

# pyenv
.python-version

# celery beat schedule file
celerybeat-schedule

# dotenv
.env

# virtualenv
venv/
ENV/

# Spyder project settings
.spyderproject

# Rope project settings
.ropeproject

5 changes: 5 additions & 0 deletions example/certs/gen_cert.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash
# Regenerate the self-signed certificate for local host.

openssl req -x509 -sha256 -nodes -newkey rsa:2048 -days 365 -keyout localhost.key -out localhost.crt

21 changes: 21 additions & 0 deletions example/certs/localhost.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDhTCCAm2gAwIBAgIJALjSEF7Y2tBMMA0GCSqGSIb3DQEBCwUAMFkxCzAJBgNV
BAYTAlVLMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0xNjA4MTYwNzQz
MTFaFw0xNzA4MTYwNzQzMTFaMFkxCzAJBgNVBAYTAlVLMRMwEQYDVQQIDApTb21l
LVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEjAQBgNV
BAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANnu
F3N5F3dqmshGs1jMDWI/FNWMNn5T9l9L+X/bw0FylPr6z46I6baFvuOR0CFnOVRj
VnL4XGnHuf5BF00r3yaZTik7E/XAP3I2SHjwIRMO6v+dZqkFB1dqGSumBP2Vxh9F
HdqVj5Q7No7HAdbef7QMlngW/K8+dZ4I5vR95ZedIhmrVzEGsndB83xqJeq8Jpnf
Xwq2Pzmwa5zy0P2cdMFebYqzyOpu5nt3+IE1GFSbQ+xDSAAtejirIARGxIwFMVBg
wpy43fbU5zQ/HeMjs5l3WrQ9KPVlR+mw8gtrv0JnpxgwBaPTA9W8jr6Z6Qdb0/BR
L/3j9LjtLdB2U6cR2FUCAwEAAaNQME4wHQYDVR0OBBYEFFJ4XhqFff7nv/gLMObh
DaIQ8MMUMB8GA1UdIwQYMBaAFFJ4XhqFff7nv/gLMObhDaIQ8MMUMAwGA1UdEwQF
MAMBAf8wDQYJKoZIhvcNAQELBQADggEBAB0YmklAhFPY4X5/uVem53Gcr+SB02Gs
VHDHKkMFlc74lFoRd/ZFnzI9y4oSBvK5ryjDiA+A7msyc5X2Ii+96wdfRUbyzeUi
oYC66GlYitRHJhJIp/alvU8qHEkWXQD5s2rk5RuLNDZKKHEHcZRsQcK11p1otAQa
r1L1V+O3OMZJmAdlWuehW0IN161vMlR0oCEpmL9VLrRNPcOL5lGV/GlNCMzLP2XM
T9EWt4i6mtGELZ94hea6GxaYfK00K+3t0eVUsMs2IbpoJinLHcJ4fPQdAjzvaAud
FCrJIOkJPk0rNeBIXnRRtBL87MV+/rhG1I/eLqLgz5QVjpNG9QDjx8A=
-----END CERTIFICATE-----
28 changes: 28 additions & 0 deletions example/certs/localhost.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDZ7hdzeRd3aprI
RrNYzA1iPxTVjDZ+U/ZfS/l/28NBcpT6+s+OiOm2hb7jkdAhZzlUY1Zy+Fxpx7n+
QRdNK98mmU4pOxP1wD9yNkh48CETDur/nWapBQdXahkrpgT9lcYfRR3alY+UOzaO
xwHW3n+0DJZ4FvyvPnWeCOb0feWXnSIZq1cxBrJ3QfN8aiXqvCaZ318Ktj85sGuc
8tD9nHTBXm2Ks8jqbuZ7d/iBNRhUm0PsQ0gALXo4qyAERsSMBTFQYMKcuN321Oc0
Px3jI7OZd1q0PSj1ZUfpsPILa79CZ6cYMAWj0wPVvI6+mekHW9PwUS/94/S47S3Q
dlOnEdhVAgMBAAECggEAYurqJBS7rQ1rUiqdL1n3XTfKyh9JgM+1jY3boshqeSN8
Met0GHtWse1FNuAxe2fyIrawP6ExuSXZ62k6HWIjeM6vJpHVPn/TjJDNFm/QY2kr
C3kzZtaMfYYABMrniv7XncvugA/QyvSRj/8Oe6wkhOINzlaIvTZ5hpD9283lT4pB
vT6qthNrr+6tBX4qCqKD/xhBQbCXTdXmQHVMksesSTOELuSKtnK2QJiAp7L502Hw
tWm0obt4T9AbK8QDkLWMUAUsYzSRgRhKB3FGSa4TT0uI2TE9UpNPiOeb47YcZodd
eHjbmToL1NK2OXGRhxeYY7bDa24lkKT8rKSXkiTngQKBgQDxg0GajHqtKR2S1UMt
UStHwQ+0mEYrNPtT4ipwEIbGbc5Z38E7xUcHimV5NcAgDno4oUvo/lolDYb3E64u
Nie+YsK84np0RsqHxKKF+JumRB1HT7MYwdV1CsKJP3g0SnQYV0VYW/C56LOf4Z1I
l4HGKrPGYRUyGjIo223pcOigtQKBgQDnALFJa6KLX6kdkYPvpsVr3eC+2iPsr4qj
lMhr30UkWVSZG4Pfx3fZIUsUNa20PbtSTBKo+tHGTtf0aRPCwvGnyhaAaPy3w2w8
9ohULe4IPn7zal+UgGyiGWpyt29SGF8zSpdalfxSNuup+Lm3TBE9Rh31N0djqgrl
jHxpf+I9IQKBgQCsYDqazFli7k2lV4Gy/pQdirZi96xdeltH68zOX31Sc10s2H9a
4dtojmcOtEaEmtCxSq6bha9hct45y1ousYh8YpELr7om87/qV3aImIC/ky4yj7gM
m4x3FU70FtD8wYdLOD7OahDPID/UhXt1LG37us7FcNVoBTp33uX8EBJ5YQKBgAH8
64mqN3fjltz+R5hkYwaOnkSGNBDxYcwOl7r17O5nJmc66WOfn9RqiO7fl2MZtOb8
aJyzq+J9AzbDQLxIWTQMdS0dui8Kq3/Kz1mKG6ZOg2Es5S2t/UFX3qamFXsrYoZa
efr5l3ZNqrGHxnFhYjSYyeE2XJLq/7UCBIAT7aqBAoGARyysROXvpI0VWd1m/x3X
8zTlZqy4jMxWm1XArDJWEYcLd8uWUsQ4mad+qopwBP8w2Irn9qFpokLp7qT82bKg
Hwha/6qRG6aTD/JHl2Q636EPXHmSPPTUhEjVKAwDIeo1W32pbn10L+1fIPl5Ig7v
31zo/OuHi+06gzcM8Pb+Oh0=
-----END PRIVATE KEY-----
108 changes: 108 additions & 0 deletions example/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package main

import (
"flag"
"log"
"net"
"net/http"

"crypto/tls"
"fmt"
)

var (
port = flag.Int("port", 9090, "whether to use tls or not")
useTls = flag.Bool("tls", true, "Whether to use TLS and HTTP2.")
tlsCertFilePath = flag.String("tls_cert_file", "certs/localhost.crt", "Path to the CRT/PEM file.")
tlsKeyFilePath = flag.String("tls_key_file", "certs/localhost.key", "Path to the private key file.")
)

func main() {
flag.Parse()

handler := func(resp http.ResponseWriter, req *http.Request) {
resp.WriteHeader(http.StatusOK)
resp.Header().Add("Content-Type", "application/json")
resp.Write([]byte(`{"msg": "hello"}`))
log.Printf("Got request: %v", req)
}

httpServer := http.Server{
Handler: http.HandlerFunc(handler),
}
var httpListener net.Listener
listener, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))
if err != nil {
log.Fatalf("Failed to listen: %v", err)
}
if !*useTls {
httpListener = listener
} else {
tlsConfig, err := tlsConfigForCert(*tlsCertFilePath, *tlsKeyFilePath)
if err != nil {
log.Fatalf("Failed configuring TLS: %v", err)
}
//httpServer.TLSConfig = tlsConfig
tlsListener := tls.NewListener(listener, tlsConfig)
httpListener = tlsListener

}
//httpListener.Addr()
log.Printf("Listening on: %s", listener.Addr().String())
if err := httpServer.Serve(httpListener); err != nil {
log.Fatalf("Failed listning: %v", err)
}
}

// tlsConfigForCert is needed as it duplicates ListenAndServeTLS, but for a listener.
func tlsConfigForCert(certFile string, keyFile string) (*tls.Config, error) {
var err error
config := new(tls.Config)
config, err = tlsEnableHttp2(config)
if err != nil {
return nil, err
}
// Make sure http1.1 is *after* h2.
config.NextProtos = append(config.NextProtos, "http/1.1")

config.Certificates = make([]tls.Certificate, 1)
config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
return nil, err
}
return tlsEnableHttp2(config)
}

//tlsEnableHttp2 performs what http2ConfigureServer does privately.
func tlsEnableHttp2(config *tls.Config) (*tls.Config, error) {
if config.CipherSuites != nil {
// If they already provided a CipherSuite list, return
// an error if it has a bad order or is missing
// ECDHE_RSA_WITH_AES_128_GCM_SHA256.
const requiredCipher = tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
haveRequired := false
for _, cs := range config.CipherSuites {
if cs == requiredCipher {
haveRequired = true
}
}
if !haveRequired {
return nil, fmt.Errorf("http2: TLSConfig.CipherSuites is missing HTTP/2-required TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256")
}
}

config.PreferServerCipherSuites = true

haveNPN := false
for _, p := range config.NextProtos {
if p == "h2" {
haveNPN = true
break
}
}
if !haveNPN {
config.NextProtos = append(config.NextProtos, "h2")
}
config.NextProtos = append(config.NextProtos, "h2-14")
return config, nil
}

0 comments on commit 3f7fc8b

Please sign in to comment.