Skip to content

Commit

Permalink
Remove http2 requirement (#106)
Browse files Browse the repository at this point in the history
  • Loading branch information
ostcar committed Feb 5, 2021
1 parent 572383e commit 020bb29
Show file tree
Hide file tree
Showing 7 changed files with 11 additions and 164 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
/autoupdate
cert
app.cover
app.cover
6 changes: 1 addition & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
dev-cert:
mkdir -p ./cert/
mkcert -cert-file ./cert/autoupdate.pem -key-file ./cert/autoupdate-key.pem localhost

app-cover:
go test ./cmd/autoupdate/ --coverpkg=./... --coverprofile=app.cover
go tool cover -html=app.cover

build-dev:
docker build . --target development --tag os3-autoupdate-dev
docker build . --target development --tag os3-autoupdate-dev
18 changes: 4 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,12 @@ To work, the service needs running OpenSlides 3 instance. It reads the data from
redis, gets autoupdates via redis and authenticates request via the openslides
service.

IMPORTANT: The data are sent via an open http-connection. All browsers limit the
amount of open http1.1 connections to a domain. For this service to work, the
browser has to connect to the service with http2 and therefore needs https.

## Install and Start

The service requires https. If no certificat is given, the service creates and
uses an inmemory self signed certificat. To create a valid certificat for
development, the tool [mkcert](https://github.com/FiloSottile/mkcert) can be
used. If `mkcert` is installed, the make target `make dev-cert` can be used to
create a certivicate for the autoupdate-service on localhost.

With created certificates, use the environment varialbe CERT_DIR to use them.

```
CERT_DIR=cert autoupdate
```
## Install and Start


### With Go
Expand Down Expand Up @@ -179,8 +171,6 @@ The service can be configured with the following environment variables:
* `AUTOUPDATE_PORT`:Port to listen on. The default is `8002`.
* `AUTOUPDATE_HOST`: The device where the service starts. The default is an
empty string which starts the service on every device.
* `CERT_DIR`: Path where the tls certificates and the keys are. If emtpy, the
server creates a self signed inmemory certificat. The default is empty.
* `MESSAGE_BUS_HOST`: Host of the redis server for reading. The default is
`localhost`.
* `MESSAGE_BUS_PORT`: Port of the redis server for reading. The default is
Expand Down
72 changes: 3 additions & 69 deletions cmd/autoupdate/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@ package main

import (
"context"
"crypto/tls"
"encoding/json"
"fmt"
"log"
"net"
"net/http"
"os"
"os/signal"
"path"
"strconv"
"syscall"
"time"
Expand Down Expand Up @@ -75,18 +72,16 @@ func main() {
mux := http.NewServeMux()
autoupdatehttp.RegisterAll(mux, auth, a, n)

// Create tls http2 server.
// Create http server.
listenAddr := getEnv("AUTOUPDATE_HOST", "") + ":" + getEnv("AUTOUPDATE_PORT", "8002")
srv := &http.Server{Handler: mux}
ln, err := tlsListener(listenAddr)
srv := &http.Server{Addr: listenAddr, Handler: mux}
if err != nil {
log.Fatalf("Can not create tls listener: %v", err)
}
defer ln.Close()

go func() {
fmt.Printf("Listen on %s\n", listenAddr)
if err := srv.Serve(ln); err != http.ErrServerClosed {
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
log.Fatalf("HTTP Server failed: %v", err)
}
}()
Expand Down Expand Up @@ -156,67 +151,6 @@ func testRedis(conn *redis.Redis, readAddr, writeAddr string) {
fmt.Printf("Connected to Redis at %s (read) and %s (write)\n", readAddr, writeAddr)
}

const (
generalCertName = "cert.pem"
generalKeyName = "key.pem"
specialCertName = "autoupdate.pem"
specialKeyName = "autoupdate-key.pem"
)

func getCert() (tls.Certificate, error) {
certDir := getEnv("CERT_DIR", "")
if certDir == "" {
cert, err := autoupdatehttp.GenerateCert()
if err != nil {
return tls.Certificate{}, fmt.Errorf("creating new certificate: %w", err)
}
fmt.Println("Use inmemory self signed certificate")
return cert, nil
}
certFile := path.Join(certDir, specialCertName)
if _, err := os.Stat(certFile); os.IsNotExist(err) {
certFile2 := path.Join(certDir, generalCertName)
if _, err := os.Stat(certFile); os.IsNotExist(err) {
return tls.Certificate{}, fmt.Errorf("%s or %s has to exist", certFile, certFile2)
}
certFile = certFile2
}

keyFile := path.Join(certDir, specialKeyName)
if _, err := os.Stat(keyFile); os.IsNotExist(err) {
keyFile2 := path.Join(certDir, generalKeyName)
if _, err := os.Stat(keyFile); os.IsNotExist(err) {
return tls.Certificate{}, fmt.Errorf("%s or %s has to exist", keyFile, keyFile2)
}
keyFile = keyFile2
}

cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
return tls.Certificate{}, fmt.Errorf("loading certificates from %s and %s: %w", certFile, keyFile, err)
}
fmt.Printf("Use certificate %s with key %s\n", certFile, keyFile)

return cert, nil
}

func tlsListener(listenAddr string) (net.Listener, error) {
cert, err := getCert()
if err != nil {
return nil, fmt.Errorf("get certificate: %w", err)
}

tlsConf := new(tls.Config)
tlsConf.NextProtos = []string{"h2"}
tlsConf.Certificates = []tls.Certificate{cert}

ln, err := net.Listen("tcp", listenAddr)
if err != nil {
return nil, fmt.Errorf("create tcp listener: %w", err)
}
return tls.NewListener(ln, tlsConf), nil
}

func openslidesRequiredUsers() map[string]func(json.RawMessage) (map[int]bool, string, error) {
return map[string]func(json.RawMessage) (map[int]bool, string, error){
"agenda/list-of-speakers": agenda.RequiredSpeakers,
Expand Down
57 changes: 0 additions & 57 deletions internal/http/cert.go

This file was deleted.

15 changes: 1 addition & 14 deletions internal/http/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,17 +253,6 @@ func (f errHandleFunc) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
}

func http2Middleware(next errHandleFunc) errHandleFunc {
return func(w http.ResponseWriter, r *http.Request) error {
// Only allow http2 requests.
if !r.ProtoAtLeast(2, 0) {
return invalidRequestError{fmt.Errorf("Only http2 is supported")}
}

return next(w, r)
}
}

func getOrPOSTMiddleware(next errHandleFunc) errHandleFunc {
return func(w http.ResponseWriter, r *http.Request) error {
// Only allow GET or POST requests.
Expand All @@ -277,9 +266,7 @@ func getOrPOSTMiddleware(next errHandleFunc) errHandleFunc {

// middleware combines all necessary middlewares.
func middleware(next errHandleFunc, auther Auther) errHandleFunc {
r := authMiddleware(getOrPOSTMiddleware(next), auther)
r = http2Middleware(r)
return r
return authMiddleware(getOrPOSTMiddleware(next), auther)
}

func authMiddleware(next errHandleFunc, auther Auther) errHandleFunc {
Expand Down
4 changes: 1 addition & 3 deletions internal/http/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,7 @@ func TestAutoupdateFirstData(t *testing.T) {

mux := http.NewServeMux()
ahttp.Autoupdate(mux, a, auther)
srv := httptest.NewUnstartedServer(mux)
srv.EnableHTTP2 = true
srv.StartTLS()
srv := httptest.NewServer(mux)
defer srv.Close()

ctx, cancel := context.WithCancel(context.Background())
Expand Down

0 comments on commit 020bb29

Please sign in to comment.