header.go raw

   1  package httpbinding
   2  
   3  import (
   4  	"encoding/base64"
   5  	"math"
   6  	"math/big"
   7  	"net/http"
   8  	"strconv"
   9  	"strings"
  10  )
  11  
  12  // Headers is used to encode header keys using a provided prefix
  13  type Headers struct {
  14  	header http.Header
  15  	prefix string
  16  }
  17  
  18  // AddHeader returns a HeaderValue used to append values to prefix+key
  19  func (h Headers) AddHeader(key string) HeaderValue {
  20  	return h.newHeaderValue(key, true)
  21  }
  22  
  23  // SetHeader returns a HeaderValue used to set the value of prefix+key
  24  func (h Headers) SetHeader(key string) HeaderValue {
  25  	return h.newHeaderValue(key, false)
  26  }
  27  
  28  func (h Headers) newHeaderValue(key string, append bool) HeaderValue {
  29  	return newHeaderValue(h.header, h.prefix+strings.TrimSpace(key), append)
  30  }
  31  
  32  // HeaderValue is used to encode values to an HTTP header
  33  type HeaderValue struct {
  34  	header http.Header
  35  	key    string
  36  	append bool
  37  }
  38  
  39  func newHeaderValue(header http.Header, key string, append bool) HeaderValue {
  40  	return HeaderValue{header: header, key: strings.TrimSpace(key), append: append}
  41  }
  42  
  43  func (h HeaderValue) modifyHeader(value string) {
  44  	if h.append {
  45  		h.header[h.key] = append(h.header[h.key], value)
  46  	} else {
  47  		h.header[h.key] = append(h.header[h.key][:0], value)
  48  	}
  49  }
  50  
  51  // String encodes the value v as the header string value
  52  func (h HeaderValue) String(v string) {
  53  	h.modifyHeader(v)
  54  }
  55  
  56  // Byte encodes the value v as a query string value
  57  func (h HeaderValue) Byte(v int8) {
  58  	h.Long(int64(v))
  59  }
  60  
  61  // Short encodes the value v as a query string value
  62  func (h HeaderValue) Short(v int16) {
  63  	h.Long(int64(v))
  64  }
  65  
  66  // Integer encodes the value v as the header string value
  67  func (h HeaderValue) Integer(v int32) {
  68  	h.Long(int64(v))
  69  }
  70  
  71  // Long encodes the value v as the header string value
  72  func (h HeaderValue) Long(v int64) {
  73  	h.modifyHeader(strconv.FormatInt(v, 10))
  74  }
  75  
  76  // Boolean encodes the value v as a query string value
  77  func (h HeaderValue) Boolean(v bool) {
  78  	h.modifyHeader(strconv.FormatBool(v))
  79  }
  80  
  81  // Float encodes the value v as a query string value
  82  func (h HeaderValue) Float(v float32) {
  83  	h.float(float64(v), 32)
  84  }
  85  
  86  // Double encodes the value v as a query string value
  87  func (h HeaderValue) Double(v float64) {
  88  	h.float(v, 64)
  89  }
  90  
  91  func (h HeaderValue) float(v float64, bitSize int) {
  92  	switch {
  93  	case math.IsNaN(v):
  94  		h.String(floatNaN)
  95  	case math.IsInf(v, 1):
  96  		h.String(floatInfinity)
  97  	case math.IsInf(v, -1):
  98  		h.String(floatNegInfinity)
  99  	default:
 100  		h.modifyHeader(strconv.FormatFloat(v, 'f', -1, bitSize))
 101  	}
 102  }
 103  
 104  // BigInteger encodes the value v as a query string value
 105  func (h HeaderValue) BigInteger(v *big.Int) {
 106  	h.modifyHeader(v.String())
 107  }
 108  
 109  // BigDecimal encodes the value v as a query string value
 110  func (h HeaderValue) BigDecimal(v *big.Float) {
 111  	if i, accuracy := v.Int64(); accuracy == big.Exact {
 112  		h.Long(i)
 113  		return
 114  	}
 115  	h.modifyHeader(v.Text('e', -1))
 116  }
 117  
 118  // Blob encodes the value v as a base64 header string value
 119  func (h HeaderValue) Blob(v []byte) {
 120  	encodeToString := base64.StdEncoding.EncodeToString(v)
 121  	h.modifyHeader(encodeToString)
 122  }
 123