github.com/aacfactory/fns@v1.2.86-0.20240310083819-80d667fc0a17/transports/request.go (about)

     1  /*
     2   * Copyright 2023 Wang Min Xiang
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   * 	http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   *
    16   */
    17  
    18  package transports
    19  
    20  import (
    21  	"crypto/tls"
    22  	"github.com/aacfactory/errors"
    23  	"github.com/aacfactory/fns/context"
    24  	"net/http"
    25  )
    26  
    27  var (
    28  	ErrTooBigRequestBody = errors.New(http.StatusRequestEntityTooLarge, "***TOO LARGE BODY***", "fns: request body is too large")
    29  )
    30  
    31  var (
    32  	MethodGet  = []byte(http.MethodGet)
    33  	MethodPost = []byte(http.MethodPost)
    34  )
    35  
    36  type Request interface {
    37  	context.Context
    38  	TLS() bool
    39  	TLSConnectionState() *tls.ConnectionState
    40  	RemoteAddr() []byte
    41  	Proto() []byte
    42  	Host() []byte
    43  	Method() []byte
    44  	SetMethod(method []byte)
    45  	Header() Header
    46  	Cookie(key []byte) (value []byte)
    47  	SetCookie(key []byte, value []byte)
    48  	RequestURI() []byte
    49  	Path() []byte
    50  	Params() Params
    51  	FormValue(name []byte) (value []byte)
    52  	Body() ([]byte, error)
    53  	SetBody(body []byte)
    54  }
    55  
    56  var (
    57  	requestContextKey       = []byte("@fns:context:transports:request")
    58  	requestHeaderContextKey = []byte("@fns:context:transports:request:header")
    59  )
    60  
    61  func WithRequest(ctx context.Context, r Request) context.Context {
    62  	ctx.SetLocalValue(requestContextKey, r)
    63  	return ctx
    64  }
    65  
    66  func TryLoadRequest(ctx context.Context) (Request, bool) {
    67  	r, ok := ctx.(Request)
    68  	if ok {
    69  		return r, ok
    70  	}
    71  	v := ctx.LocalValue(requestContextKey)
    72  	if v == nil {
    73  		return nil, false
    74  	}
    75  	r, ok = v.(Request)
    76  	return r, ok
    77  }
    78  
    79  func LoadRequest(ctx context.Context) Request {
    80  	r, ok := TryLoadRequest(ctx)
    81  	if ok {
    82  		return r
    83  	}
    84  	return nil
    85  }
    86  
    87  func TryLoadRequestHeader(ctx context.Context) (Header, bool) {
    88  	r, has := TryLoadRequest(ctx)
    89  	if !has {
    90  		v := ctx.LocalValue(requestHeaderContextKey)
    91  		if v == nil {
    92  			return nil, false
    93  		}
    94  		header, ok := v.(Header)
    95  		return header, ok
    96  	}
    97  	return r.Header(), has
    98  }
    99  
   100  func WithRequestHeader(ctx context.Context, header Header) context.Context {
   101  	ctx.SetLocalValue(requestHeaderContextKey, header)
   102  	return ctx
   103  }