github.com/aacfactory/fns@v1.2.86-0.20240310083819-80d667fc0a17/transports/standard/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 standard
    19  
    20  import (
    21  	"crypto/tls"
    22  	se "errors"
    23  	"github.com/aacfactory/errors"
    24  	"github.com/aacfactory/fns/commons/bytex"
    25  	"github.com/aacfactory/fns/context"
    26  	"github.com/aacfactory/fns/transports"
    27  	"github.com/valyala/bytebufferpool"
    28  	"io"
    29  	"net/http"
    30  )
    31  
    32  const (
    33  	securedSchema = "https"
    34  )
    35  
    36  type Request struct {
    37  	context.Context
    38  	maxBodySize int
    39  	request     *http.Request
    40  }
    41  
    42  func (r *Request) TLS() bool {
    43  	return r.request.URL.Scheme == securedSchema
    44  }
    45  
    46  func (r *Request) TLSConnectionState() *tls.ConnectionState {
    47  	return r.request.TLS
    48  }
    49  
    50  func (r *Request) RemoteAddr() []byte {
    51  	return bytex.FromString(r.request.RemoteAddr)
    52  }
    53  
    54  func (r *Request) Proto() []byte {
    55  	return bytex.FromString(r.request.Proto)
    56  }
    57  
    58  func (r *Request) Host() []byte {
    59  	return bytex.FromString(r.request.Host)
    60  }
    61  
    62  func (r *Request) Method() []byte {
    63  	return bytex.FromString(r.request.Method)
    64  }
    65  
    66  func (r *Request) SetMethod(method []byte) {
    67  	r.request.Method = bytex.ToString(method)
    68  }
    69  
    70  func (r *Request) Cookie(key []byte) (value []byte) {
    71  	cookie, cookieErr := r.request.Cookie(bytex.ToString(key))
    72  	if se.Is(cookieErr, http.ErrNoCookie) {
    73  		return
    74  	}
    75  	value = bytex.FromString(cookie.Value)
    76  	return
    77  }
    78  
    79  func (r *Request) SetCookie(key []byte, value []byte) {
    80  	r.request.AddCookie(&http.Cookie{
    81  		Name:  bytex.ToString(key),
    82  		Value: bytex.ToString(value),
    83  	})
    84  }
    85  
    86  func (r *Request) Header() transports.Header {
    87  	return WrapHttpHeader(r.request.Header)
    88  }
    89  
    90  func (r *Request) RequestURI() []byte {
    91  	return bytex.FromString(r.request.RequestURI)
    92  }
    93  
    94  func (r *Request) Path() []byte {
    95  	return bytex.FromString(r.request.URL.Path)
    96  }
    97  
    98  func (r *Request) Params() transports.Params {
    99  	return &Params{
   100  		values: r.request.URL.Query(),
   101  	}
   102  }
   103  
   104  func (r *Request) FormValue(name []byte) (value []byte) {
   105  	return []byte(r.request.FormValue(string(name)))
   106  }
   107  
   108  func (r *Request) Body() ([]byte, error) {
   109  	buf := bytebufferpool.Get()
   110  	defer bytebufferpool.Put(buf)
   111  	b := bytex.Acquire4KBuffer()
   112  	defer bytex.Release4KBuffer(b)
   113  	for {
   114  		n, readErr := r.request.Body.Read(b)
   115  		if n > 0 {
   116  			_, _ = buf.Write(b[0:n])
   117  		}
   118  		if readErr != nil {
   119  			if readErr == io.EOF {
   120  				break
   121  			}
   122  			return nil, errors.Warning("fns: read request body failed").WithCause(readErr)
   123  		}
   124  		if r.maxBodySize > 0 {
   125  			if buf.Len() > r.maxBodySize {
   126  				return nil, transports.ErrTooBigRequestBody
   127  			}
   128  		}
   129  	}
   130  	return buf.Bytes(), nil
   131  }
   132  
   133  func (r *Request) SetBody(body []byte) {
   134  	if len(body) == 0 {
   135  		return
   136  	}
   137  	if r.request.Body != nil {
   138  		_ = r.request.Body.Close()
   139  	}
   140  	r.request.Body = bytex.NewReadCloser(body)
   141  }