Created
June 17, 2015 13:05
-
-
Save dvas0004/82250551f34c77e0b35a to your computer and use it in GitHub Desktop.
Example of Golang embedding, see http://blog.davidvassallo.me/?p=1650
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"io" | |
"net/http" | |
"log" | |
"crypto/tls" | |
"net" | |
"sixpmplc.com/golang/license_server/tls_common" | |
) | |
type embeddedServer struct { | |
/* | |
custom struct that embeds golang's standard http.Server type | |
another way of looking at this is that embeddedServer "inherits" from http.Server, | |
though this is not strictly accurate. Have a look at note below for additional information | |
*/ | |
http.Server | |
webserverCertificate string | |
webserverKey string | |
} | |
func (srv *embeddedServer) ListenAndServeTLS(addr string) error { | |
/* | |
This is where we "hide" or "override" the default "ListenAndServeTLS" method so we modify it to accept | |
hardcoded certificates and keys rather than the default filenames | |
The default implementation of ListenAndServeTLS was obtained from: | |
https://github.com/zenazn/goji/blob/master/graceful/server.go#L33 | |
and tls.X509KeyPair (http://golang.org/pkg/crypto/tls/#X509KeyPair) is used, | |
rather than the default tls.LoadX509KeyPair | |
*/ | |
config := &tls.Config{ | |
MinVersion: tls.VersionTLS10, | |
} | |
if srv.TLSConfig != nil { | |
*config = *srv.TLSConfig | |
} | |
if config.NextProtos == nil { | |
config.NextProtos = []string{"http/1.1"} | |
} | |
var err error | |
config.Certificates = make([]tls.Certificate, 1) | |
config.Certificates[0], err = tls.X509KeyPair([]byte(srv.webserverCertificate), []byte(srv.webserverKey)) | |
if err != nil { | |
return err | |
} | |
conn, err := net.Listen("tcp", addr) | |
if err != nil { | |
return err | |
} | |
tlsListener := tls.NewListener(conn, config) | |
return srv.Serve(tlsListener) | |
} | |
func hello(w http.ResponseWriter, r *http.Request) { | |
io.WriteString(w, "Hello world!") | |
} | |
func main() { | |
// instantiating an embeddedServer type, and assigning hardcoded TLS certificate and key | |
embeddedTLSserver := &embeddedServer{ | |
webserverCertificate: tls_common.WebserverCertificate, | |
webserverKey: tls_common.WebserverPrivateKey, | |
} | |
// reference: https://golang.org/doc/articles/wiki/ | |
http.HandleFunc("/", hello) | |
http.HandleFunc("/decrypt", decryptMessage) | |
http.HandleFunc("/verify", verifyMessage) | |
/* | |
reference: http://golang.org/pkg/net/http/#ListenAndServeTLS | |
Normally we would call an TLS server using the ListenAndServeTLS as described above, resulting in a call similar to: | |
http.ListenAndServeTLS(":10443", "server.crt", "server.key", nil) | |
However, we have a problem with that because it references external files, which we dont want. Since this executable | |
is going to be installed in a "hostile" environment, we want to make sure that all sensitive information like | |
certificates and private keys are hardcoded into the executable. | |
Unfortunately, we can't simply set the TLSConfig attribute of http.Server (why golang gods, why?!) | |
So we need to write our own implementation of ListenAndServeTLS. | |
This is where "embeddedServer" type comes in. Note that we define "type embeddedServer struct" towards the beginning | |
of this program. We then proceed to use a feature of golang called "embedding". Please refer to the following link | |
for more information: | |
http://www.hydrogen18.com/blog/golang-embedding.html | |
*/ | |
log.Fatal(embeddedTLSserver.ListenAndServeTLS(":10443")) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment