func (p *Protocol) Receive(ctx context.Context) (binding.Message, error) {
	if ctx == nil {
		return nil, fmt.Errorf("nil Context")
	}
	msg, fn, err := p.Respond(ctx)
	if msg != nil {
		return binding.WithFinish(msg, func(err error) {
			if fn != nil {
				_ = fn(ctx, nil, nil)
			}
		}), err
	} else {
		return nil, err
	}
}
Receive the next incoming HTTP request as a CloudEvent.
Returns non-nil error if the incoming HTTP request fails to parse as a CloudEvent
Returns io.EOF if the receiver is closed.
package http
import (
	"bytes"
	"context"
	"errors"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"sync"
	"sync/atomic"
	"time"
	"github.com/cloudevents/sdk-go/v2/binding"
	cecontext "github.com/cloudevents/sdk-go/v2/context"
	"github.com/cloudevents/sdk-go/v2/event"
	"github.com/cloudevents/sdk-go/v2/protocol"
)
const (
	DefaultShutdownTimeout = time.Minute * 1
)
type msgErr struct {
	msg    *Message
	respFn protocol.ResponseFn
	err    error
}
var defaultRetriableErrors = map[int]string{
	404: "Not Found",
	413: "Payload Too Large",
	425: "Too Early",
	429: "Too Many Requests",
	502: "Bad Gateway",
	503: "Service Unavailable",
	504: "Gateway Timeout",
}
type Protocol struct {
	Target          *url.URL
	RequestTemplate *http.Request
	Client          *http.Client
	incoming        chan msgErr
	OptionsHandlerFn http.HandlerFunc
	WebhookConfig    *WebhookConfig
	GetHandlerFn    http.HandlerFunc
	DeleteHandlerFn http.HandlerFunc
	ShutdownTimeout time.Duration
	Port int
	Path string
	reMu sync.Mutex
	Handler *http.ServeMux
	listener          atomic.Value
	roundTripper      http.RoundTripper
	server            *http.Server
	handlerRegistered bool
	middleware        []Middleware
	limiter           RateLimiter
	isRetriableFunc IsRetriable
}
func New(opts ...Option) (*Protocol, error) {
	p := &Protocol{
		incoming: make(chan msgErr),
		Port:     -1,
	}
	if err := p.applyOptions(opts...); err != nil {
		return nil, err
	}
	if p.Client == nil {
		p.Client = http.DefaultClient
	}
	if p.roundTripper != nil {
		p.Client.Transport = p.roundTripper
	}
	if p.ShutdownTimeout == 0 {
		p.ShutdownTimeout = DefaultShutdownTimeout
	}
	if p.isRetriableFunc == nil {
		p.isRetriableFunc = defaultIsRetriableFunc
	}
	if p.limiter == nil {
		p.limiter = noOpLimiter{}
	}
	return p, nil
}
var NewObserved = New
func (p *Protocol) applyOptions(opts ...Option) error {
	for _, fn := range opts {
		if err := fn(p); err != nil {
			return err
		}
	}
	return nil
}
func (p *Protocol) Send(ctx context.Context, m binding.Message, transformers ...binding.Transformer) error {
	if ctx == nil {
		return fmt.Errorf("nil Context")
	} else if m == nil {
		return fmt.Errorf("nil Message")
	}
	msg, err := p.Request(ctx, m, transformers...)
	if msg != nil {
		defer func() { _ = msg.Finish(err) }()
	}
	if err != nil && !protocol.IsACK(err) {
		var res *Result
		if protocol.ResultAs(err, &res) {
			if message, ok := msg.(*Message); ok {
				buf := new(bytes.Buffer)
				buf.ReadFrom(message.BodyReader)
				errorStr := buf.String()
				err = NewResult(res.StatusCode, "%s", errorStr)
			}
		}
	}
	return err
}
func (p *Protocol) Request(ctx context.Context, m binding.Message, transformers ...binding.Transformer) (binding.Message, error) {
	if ctx == nil {
		return nil, fmt.Errorf("nil Context")
	} else if m == nil {
		return nil, fmt.Errorf("nil Message")
	}
	var err error
	defer func() { _ = m.Finish(err) }()
	req := p.makeRequest(ctx)
	if p.Client == nil || req == nil || req.URL == nil {
		return nil, fmt.Errorf("not initialized: %#v", p)
	}
	if err = WriteRequest(ctx, m, req, transformers...); err != nil {
		return nil, err
	}
	return p.do(ctx, req)
}
func (p *Protocol) makeRequest(ctx context.Context) *http.Request {
	req := &http.Request{
		Method: http.MethodPost,
		Header: HeaderFrom(ctx),
	}
	if p.RequestTemplate != nil {
		req.Method = p.RequestTemplate.Method
		req.URL = p.RequestTemplate.URL
		req.Close = p.RequestTemplate.Close
		req.Host = p.RequestTemplate.Host
		copyHeadersEnsure(p.RequestTemplate.Header, &req.Header)
	}
	if p.Target != nil {
		req.URL = p.Target
	}
	if target := cecontext.TargetFrom(ctx); target != nil {
		req.URL = target
	}
	return req.WithContext(ctx)
}
func copyHeadersEnsure(from http.Header, to *http.Header) {
	if len(from) > 0 {
		if *to == nil {
			*to = http.Header{}
		}
		copyHeaders(from, *to)
	}
}
func copyHeaders(from, to http.Header) {
	if from == nil || to == nil {
		return
	}
	for header, values := range from {
		for _, value := range values {
			to.Add(header, value)
		}
	}
}