func (s *serverHandler) serveSync(c *quic.Conn, events []transport.Event) {
	for _, e := range events {
		switch e.Type {
		case transport.EventStreamReadable:
			err := s.handleStreamReadable(c, e.Data)
			if err != nil {
				c.CloseWithError(transport.ApplicationError, err.Error())
				return
			}
		case transport.EventStreamWritable:
			err := s.handleStreamWritable(c, e.Data)
			if err != nil {
				c.CloseWithError(transport.ApplicationError, err.Error())
				return
			}
		case transport.EventConnClosed:
			for _, f := range s.getResponses(c) {
				f.f.Close()
			}
		}
	}
}
serveSync demonstrates using synchronous Stream APIs.
package main
import (
	"bufio"
	"crypto/tls"
	"flag"
	"fmt"
	"io"
	"log"
	"net"
	"net/url"
	"os"
	"os/signal"
	"path"
	"path/filepath"
	"strings"
	"syscall"
	"time"
	"github.com/goburrow/quic"
	"github.com/goburrow/quic/transport"
	"golang.org/x/crypto/acme"
	"golang.org/x/crypto/acme/autocert"
)
type serverCommand struct{}
func (serverCommand) Name() string {
	return "server"
}
func (serverCommand) Desc() string {
	return "start a QUIC server."
}
func (serverCommand) Run(args []string) error {
	cmd := flag.NewFlagSet("server", flag.ExitOnError)
	listenAddr := cmd.String("listen", ":4433", "listen on the given IP:port")
	certFile := cmd.String("cert", "", "TLS certificate path")
	keyFile := cmd.String("key", "", "TLS certificate key path")
	domains := cmd.String("domains", "", "allowed host names for ACME (separated by a comma)")
	cacheDir := cmd.String("cache", ".", "certificate cache directory when using ACME")
	root := cmd.String("root", "www", "root directory")
	qlogPath := cmd.String("qlog", "", "qlog directory or file path")
	logLevel := cmd.Int("v", 2, "log verbose: 0=off 1=error 2=info 3=debug 4=trace")
	useAsync := cmd.Bool("async", false, "use asynchronous Stream APIs")
	enableRetry := cmd.Bool("retry", false, "enable address validation using Retry packet")
	cmd.Usage = func() {
		fmt.Fprintln(cmd.Output(), "Usage: quiwi server [arguments]")
		cmd.PrintDefaults()
	}
	cmd.Parse(args)
	config := newConfig()
	if *certFile != "" {
		cert, err := tls.LoadX509KeyPair(*certFile, *keyFile)
		if err != nil {
			return err
		}
		config.TLS.Certificates = []tls.Certificate{cert}
	}
	if *domains != "" {
		acme := acmeHandler{
			domains:  *domains,
			cacheDir: *cacheDir,
		}
		err := acme.listen(config.TLS)
		if err != nil {
			return err
		}
		defer acme.Close()
		go acme.serve()
	}
	if len(config.TLS.Certificates) == 0 && config.TLS.GetCertificate == nil && config.TLS.GetConfigForClient == nil {
		return fmt.Errorf("TLS certificate must be set")
	}
	server := quic.NewServer(config)
	server.SetHandler(&serverHandler{
		root:  *root,
		async: *useAsync,
	})
	if *enableRetry {
		server.SetAddressVerifier(quic.NewAddressVerifier())
	}
	if *qlogPath == "" {
		server.SetLogger(*logLevel, os.Stderr)
	} else {
		qw, err := newQLogWriter(*qlogPath, "server-")
		if err != nil {
			return err
		}
		defer qw.Close()
		go qw.process()
		server.SetLogger(*logLevel, qw)
	}
	sigCh := make(chan os.Signal, 3)
	signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT)
	go func() {
		<-sigCh
		server.Close()
	}()
	return server.ListenAndServe(*listenAddr)
}
type serverHandler struct {
	root  string
	async bool
}
func (s *serverHandler) Serve(c *quic.Conn, events []transport.Event) {
	if s.async {
		s.serveAsync(c, events)
	} else {
		s.serveSync(c, events)
	}
}