package
1.2.120
Repository: https://github.com/searking/golang.git
Documentation: pkg.go.dev

# README

Build Status GoDoc Report card Sourcegraph

mux: Connection Mux

mux is a generic Go library to multiplex connections based on their payload. Using mux, you can serve gRPC, SSH, HTTPS, HTTP, Go RPC, and pretty much any other protocol on the same TCP listener.

How-To

Simply create your main listener, create a mux for that listener, and then match connections:

package main

import (
	"context"
	"log"
	"net/http"
	"os"
	"os/signal"
	"strings"

	"github.com/searKing/golang/go/net/mux"
	"golang.org/x/net/http2/hpack"
)

func main() {
	srv := mux.NewServer()
	defer srv.Close()

	// We first match the connection against HTTP2 fields. If matched, the
	// connection will be sent through the "grpcl" listener.
	grpcl := mux.HandleListener(mux.HTTP2HeaderFieldValue(false, strings.EqualFold, hpack.HeaderField{
		Name:  "Content-Type",
		Value: "application/grpc",
	}))
	//Otherwise, we match it againts a websocket upgrade request.
	var wslH = http.Header{}
	wslH.Set("Upgrade", "websocket")
	wsl := mux.HandleListener(mux.HTTP1HeaderEqual(wslH))

	// Otherwise, we match it againts HTTP1 methods. If matched,
	// it is sent through the "httpl" listener.
	httpl := mux.HandleListener(mux.HTTP1Fast())
	// If not matched by HTTP, we assume it is an RPC connection.
	rpcl := mux.HandleListener(mux.Any())

	// Then we used the muxed listeners.
	// See safeServe in github.com/searKing/golang/go/net/mux/mux_helper_test.go
	go serveGRPC(grpcl)
	go serveWS(wsl)
	go serveHTTP(httpl)
	go serveRPC(rpcl)

	idleConnsClosed := make(chan struct{})
	go func() {
		sigint := make(chan os.Signal, 1)
		signal.Notify(sigint, os.Interrupt)
		<-sigint

		// We received an interrupt signal, shut down.
		if err := srv.Shutdown(context.Background()); err != nil {
			// Error from closing listeners, or context timeout:
			log.Printf("mux server Shutdown: %v", err)
		}
		close(idleConnsClosed)
	}()
	if err := srv.ListenAndServe("localhost:0"); err != mux.ErrServerClosed {
		// Error starting or closing listener:
		log.Printf("mux server ListenAndServe: %v", err)
	}
	<-idleConnsClosed
}

Take a look at other examples in the GoDoc.

Docs

Performance

There is room for improvment but, since we are only matching the very first bytes of a connection, the performance overheads on long-lived connections (i.e., RPCs and pipelined HTTP streams) is negligible.

Limitations

  • TLS: net/http uses a type assertion to identify TLS connections; since mux's lookahead-implementing connection wraps the underlying TLS connection, this type assertion fails. Because of that, you can serve HTTPS using mux but http.Request.TLS would not be set in your handlers.

  • Different Protocols on The Same Connection: mux matches the connection when it's accepted. For example, one connection can be either gRPC or REST, but not both. That is, we assume that a client connection is either used for gRPC or REST.

  • Java gRPC Clients: Java gRPC client blocks until it receives a SETTINGS frame from the server. If you are using the Java client to connect to a mux'ed gRPC server please match with writers:

package main

import (
	"strings"

	"github.com/searKing/golang/go/net/mux"
	"golang.org/x/net/http2/hpack"
)

func main() {
	grpcl := mux.HandleListener(mux.HTTP2HeaderFieldValue(false, strings.EqualFold, hpack.HeaderField{
		Name:  "Content-Type",
		Value: "application/grpc",
	}))
	_ = grpcl
}

Thanks to

Copyright and License

Copyright 2019 The searKing Authors. All rights reserved.

Code is released under the MIT license.

# Functions

Any is a Matcher that matches any connection.
No description provided by the author
AnyPrefixMatcher returns a matcher that matches a connection if it starts with any of the strings in strs.
ConnStateSliceContains reports whether sunEnums is within enums.
ConnStateSliceContainsAny reports whether any sunEnum is within enums.
ConnStateValues returns all values of the enum.
GRPC parses the frame header of the first frame to detect whether the connection is an HTTP2 connection.
No description provided by the author
HandleFunc registers the handler function for the given pattern.
No description provided by the author
PRI * HTTP/2.0\r\n\r\n HTTP parses the first line or upto 4096 bytes of the request to see if the connection contains an HTTP request.
HTTP1 parses the first line or upto 4096 bytes of the request to see if the conection contains an HTTP request.
HTTP1Fast only matches the methods in the HTTP request.
HTTP1Header returns true if all headers are expected.
HTTP1HeaderEqual returns a matcher matching the header fields of the first request of an HTTP 1 connection.
HTTP1HeaderPrefix returns a matcher matching the header fields of the first request of an HTTP 1 connection.
HTTP1HeaderValue returns true if all headers are expected, shorthand for HTTP1Header strings.Match for all value in expects.
HTTP2 parses the frame header of the first frame to detect whether the connection is an HTTP2 connection.
HTTP2HeaderField returns a matcher matching the header fields of the first headers frame.
HTTP2HeaderFieldEqual returns a matcher matching the header fields.
HTTP2HeaderFieldPrefix returns a matcher matching the header fields.
HTTP2HeaderFieldValue returns a matcher matching the header fields, registered with the match handler.
ListenAndServe listens on the TCP network address addr and then calls Serve with handler to handle requests on incoming connections.
ListenAndServeTLS acts identically to ListenAndServe, except that it expects HTTPS connections.
No description provided by the author
NewServeMux allocates and returns a new ServeMux.
NewServer wraps NewServerWithContext using the background context.
NewServerWithContext returns a new Server.
NotFound replies to the request with an HTTP 404 not found error.
NotFoundHandler returns a simple request handler that replies to each request with a “404 page not found” reply.
ParseConnStateString retrieves an enum value from the enum constants string name.
No description provided by the author
TLS matches HTTPS requests.
WithErrorLog specifies an optional logger for errors.
WithMaxIdleConns controls the maximum number of idle (keep-alive) connections across all hosts.

# Constants

ConnStateActive represents a connection that has read 1 or more bytes of a request.
ConnStateClosed represents a closed connection.
ConnStateHijacked represents a hijacked connection.
ConnStateIdle represents a connection that has finished handling a request and is in the keep-alive state, waiting for a new request.
ConnStateNew represents a new connection that is expected to send a request immediately.

# Variables

DefaultServeMux is the default ServeMux used by Serve.
ErrAbortHandler is a sentinel panic value to abort a handler.
ErrHijacked is returned by ResponseWriter.Write calls when the underlying connection has been hijacked using the Hijacker interface.
ErrListenerClosed is returned from MuxListener.Accept when the underlying listener is closed.
ErrServerClosed is returned by the Server's Serve, ServeTLS, ListenAndServe, and ListenAndServeTLS methods after a call to Shutdown or Close.
LocalAddrContextKey is a context key.
ServerContextKey is a context key.

# Structs

EmptyServerOption does not alter the configuration.
ServeMux is a net.ServeMux that accepts only the connections that matched.
Server is a multiplexer for network connections.

# Interfaces

No description provided by the author
No description provided by the author
No description provided by the author
A ServerOption sets options.

# Type aliases

A ConnState represents the state of a client connection to a server.
ErrorHandler handles an error and returns whether the mux should continue serving the listener.
HandlerConnFunc is a match that can also write response (say to do handshake).
MatcherFunc is a match that can also write response (say to do handshake).
ServerOptionFunc wraps a function that modifies Server into an implementation of the ServerOption interface.