Move the http server from the hgweb package to the http package
--- a/hgweb/logger.go Mon Mar 07 01:52:42 2022 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
- log "github.com/sirupsen/logrus"
-type loggerResponseWriter struct {
-var _ http.ResponseWriter = (*loggerResponseWriter)(nil)
-func (w *loggerResponseWriter) Header() http.Header {
-func (w *loggerResponseWriter) Write(data []byte) (int, error) {
- w.WriteHeader(http.StatusOK)
- n, err := w.w.Write(data)
-func (w *loggerResponseWriter) WriteHeader(statusCode int) {
- w.statusCode = statusCode
- w.w.WriteHeader(w.statusCode)
-func (w *loggerResponseWriter) StatusCode() int {
-func (w *loggerResponseWriter) Written() int64 {
-func getAddr(r *http.Request) string {
- // check for the X-Forwarded-For header and use if it we have it
- if fwd := r.Header.Get("X-Forwarded-For"); fwd != "" {
- // Request.RemoteAddr is ipv4:port or [ipv6]:port so we have to trim off
- // we use LastIndex so we can parse IPv6 addresses
- if idx := strings.LastIndex(addr, ":"); idx != -1 {
- // if the ipv6 was wrapped in [] we need to unwrap it
- if idx := strings.Index(addr, "]"); idx != -1 {
-func Logger(h http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- rw := &loggerResponseWriter{
- // implement the NCSA Combined Log Format
- // http://publib.boulder.ibm.com/tividd/td/ITWSA/ITWSA_info45/en_US/HTML/guide/c-logs.html#combined
- if user, _, ok := r.BasicAuth(); ok && username != "" {
- userAgent := r.UserAgent()
- "%s - %s [%s] \"%s %s %s\" %d %d %q %q\n",
- time.Now().Format("02/Jan/2006:15:04:05 -0700"),
--- a/hgweb/server.go Mon Mar 07 01:52:42 2022 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
- log "github.com/sirupsen/logrus"
- "keep.imfreedom.org/grim/hgkeeper/hg"
- hgkHttp "keep.imfreedom.org/grim/hgkeeper/http"
- externalHostname string
-func NewServer(listenAddr string, externalHostname, externalPort string) (*Server, error) {
- listenAddr: listenAddr,
- externalHostname: externalHostname,
- externalPort: externalPort,
-func (s *Server) Listen() error {
- templatesDir, err := hg.TemplatesDir()
- staticPath := filepath.Join(templatesDir, "static")
- log.Infof("serving static files from %s", staticPath)
- fileServer := http.FileServer(http.Dir(staticPath))
- mux := http.NewServeMux()
- if s.externalHostname != "" {
- mux.Handle("/ssh/authorized_keys", hgkHttp.AuthorizedKeysHandler(s.externalHostname, s.externalPort))
- log.Infof("added /ssh/authorized_keys endpoint with external hostname %s and export port %s", s.externalHostname, s.externalPort)
- log.Infof("no external hostname specified, not adding /ssh/authorized_keys endpoint")
- mux.Handle("/static/", http.StripPrefix("/static", fileServer))
- hgwHandler, err := s.hgw.Handler()
- mux.Handle("/", hgwHandler)
- s.server.Handler = Logger(mux)
- log.Infof("http listening on %s", s.listenAddr)
- return s.server.ListenAndServe()
-func (s *Server) Close() {
- if err := s.hgw.Close(); err != nil {
- log.Warnf("failed to close hgweb: %v", err)
- if err := s.server.Close(); err != nil {
- log.Warnf("failed to shutdown http server: %v", err)
--- a/http/authorized_keys.go Mon Mar 07 01:52:42 2022 -0600
+++ b/http/authorized_keys.go Mon Mar 07 01:55:50 2022 -0600
@@ -10,7 +10,7 @@
"keep.imfreedom.org/grim/hgkeeper/access"
-func AuthorizedKeysHandler(externalHostname, externalPort string) http.Handler {
+func authorizedKeysHandler(externalHostname, externalPort string) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fp := r.URL.Query().Get("fp")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/http/logger.go Mon Mar 07 01:55:50 2022 -0600
@@ -0,0 +1,119 @@
+ log "github.com/sirupsen/logrus" +type loggerResponseWriter struct { +var _ http.ResponseWriter = (*loggerResponseWriter)(nil) +func (w *loggerResponseWriter) Header() http.Header { +func (w *loggerResponseWriter) Write(data []byte) (int, error) { + w.WriteHeader(http.StatusOK) + n, err := w.w.Write(data) +func (w *loggerResponseWriter) WriteHeader(statusCode int) { + w.statusCode = statusCode + w.w.WriteHeader(w.statusCode) +func (w *loggerResponseWriter) StatusCode() int { +func (w *loggerResponseWriter) Written() int64 { +func getAddr(r *http.Request) string { + // check for the X-Forwarded-For header and use if it we have it + if fwd := r.Header.Get("X-Forwarded-For"); fwd != "" { + // Request.RemoteAddr is ipv4:port or [ipv6]:port so we have to trim off + // we use LastIndex so we can parse IPv6 addresses + if idx := strings.LastIndex(addr, ":"); idx != -1 { + // if the ipv6 was wrapped in [] we need to unwrap it + if idx := strings.Index(addr, "]"); idx != -1 { +func Logger(h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + rw := &loggerResponseWriter{ + // implement the NCSA Combined Log Format + // http://publib.boulder.ibm.com/tividd/td/ITWSA/ITWSA_info45/en_US/HTML/guide/c-logs.html#combined + if user, _, ok := r.BasicAuth(); ok && username != "" { + userAgent := r.UserAgent() + "%s - %s [%s] \"%s %s %s\" %d %d %q %q\n", + time.Now().Format("02/Jan/2006:15:04:05 -0700"), --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/http/server.go Mon Mar 07 01:55:50 2022 -0600
@@ -0,0 +1,75 @@
+ log "github.com/sirupsen/logrus" + "keep.imfreedom.org/grim/hgkeeper/hg" + "keep.imfreedom.org/grim/hgkeeper/hgweb" + externalHostname string +func NewServer(listenAddr string, externalHostname, externalPort string) (*Server, error) { + listenAddr: listenAddr, + externalHostname: externalHostname, + externalPort: externalPort, +func (s *Server) Listen() error { + templatesDir, err := hg.TemplatesDir() + staticPath := filepath.Join(templatesDir, "static") + log.Infof("serving static files from %s", staticPath) + fileServer := http.FileServer(http.Dir(staticPath)) + mux := http.NewServeMux() + if s.externalHostname != "" { + mux.Handle("/ssh/authorized_keys", authorizedKeysHandler(s.externalHostname, s.externalPort)) + log.Infof("added /ssh/authorized_keys endpoint with external hostname %s and export port %s", s.externalHostname, s.externalPort) + log.Infof("no external hostname specified, not adding /ssh/authorized_keys endpoint") + mux.Handle("/static/", http.StripPrefix("/static", fileServer)) + hgwHandler, err := s.hgw.Handler() + mux.Handle("/", hgwHandler) + s.server.Handler = Logger(mux) + log.Infof("http listening on %s", s.listenAddr) + return s.server.ListenAndServe() +func (s *Server) Close() { + if err := s.hgw.Close(); err != nil { + log.Warnf("failed to close hgweb: %v", err) + if err := s.server.Close(); err != nil { + log.Warnf("failed to shutdown http server: %v", err) --- a/serve/command.go Mon Mar 07 01:52:42 2022 -0600
+++ b/serve/command.go Mon Mar 07 01:55:50 2022 -0600
@@ -10,7 +10,7 @@
"keep.imfreedom.org/grim/hgkeeper/access"
"keep.imfreedom.org/grim/hgkeeper/globals"
- "keep.imfreedom.org/grim/hgkeeper/hgweb"
+ "keep.imfreedom.org/grim/hgkeeper/http" "keep.imfreedom.org/grim/hgkeeper/ssh"
@@ -40,7 +40,7 @@
errChan := make(chan error, 10)
var sshServer *ssh.Server
- var hgwebServer *hgweb.Server
+ var httpServer *http.Server log.Info("SSH server has been disabled")
@@ -57,11 +57,11 @@
log.Info("HTTP server has been disabled")
- hgwebServer, err = hgweb.NewServer(c.HTTPAddr, c.ExternalHostname, c.ExternalPort)
+ httpServer, err = http.NewServer(c.HTTPAddr, c.ExternalHostname, c.ExternalPort) - defer hgwebServer.Close()
+ defer httpServer.Close() @@ -74,7 +74,7 @@
- if err := hgwebServer.Listen(); err != nil {
+ if err := httpServer.Listen(); err != nil {