httpheader

package module
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 29, 2023 License: MIT Imports: 8 Imported by: 31

README

go-httpheader

go-httpheader is a Go library for encoding structs into Header fields.

Build Status Coverage Status Go Report Card GoDoc

install

go get github.com/mozillazg/go-httpheader

usage

package main

import (
	"fmt"
	"net/http"

	"github.com/mozillazg/go-httpheader"
)

type Options struct {
	hide         string
	ContentType  string `header:"Content-Type"`
	Length       int
	XArray       []string `header:"X-Array"`
	TestHide     string   `header:"-"`
	IgnoreEmpty  string   `header:"X-Empty,omitempty"`
	IgnoreEmptyN string   `header:"X-Empty-N,omitempty"`
	CustomHeader http.Header
}

func main() {
	opt := Options{
		hide:         "hide",
		ContentType:  "application/json",
		Length:       2,
		XArray:       []string{"test1", "test2"},
		TestHide:     "hide",
		IgnoreEmptyN: "n",
		CustomHeader: http.Header{
			"X-Test-1": []string{"233"},
			"X-Test-2": []string{"666"},
		},
	}
	h, _ := httpheader.Header(opt)
	fmt.Printf("%#v", h)
	// h:
	// http.Header{
	//	"X-Test-1":     []string{"233"},
	//	"X-Test-2":     []string{"666"},
	//	"Content-Type": []string{"application/json"},
	//	"Length":       []string{"2"},
	//	"X-Array":      []string{"test1", "test2"},
	//	"X-Empty-N":    []string{"n"},
	// }
	
	// decode
	var decode Options
	httpheader.Decode(h, &decode)
}

Documentation

Overview

Package httpheader implements encoding of structs into http.Header fields.

As a simple example:

type Options struct {
	ContentType  string `header:"Content-Type"`
	Length       int
}

opt := Options{"application/json", 2}
h, _ := httpheader.Header(opt)
fmt.Printf("%#v", h)
// will output:
// http.Header{"Content-Type":[]string{"application/json"},"Length":[]string{"2"}}

The exact mapping between Go values and http.Header is described in the documentation for the Header() function.

Index

Examples

Constants

View Source
const Version = "0.3.1"

Version ...

Variables

This section is empty.

Functions

func Decode added in v0.3.0

func Decode(header http.Header, v interface{}) error

Decode expects to be passed an http.Header and a struct, and parses header into the struct recursively using the same rules as Header (see above)

Example
type Options struct {
	ContentType  string `header:"Content-Type"`
	Length       int
	Bool         bool
	BoolInt      bool      `header:"Bool-Int,int"`
	XArray       []string  `header:"X-Array"`
	TestHide     string    `header:"-"`
	IgnoreEmpty  string    `header:"X-Empty,omitempty"`
	IgnoreEmptyN string    `header:"X-Empty-N,omitempty"`
	CreatedAt    time.Time `header:"Created-At"`
	UpdatedAt    time.Time `header:"Update-At,unix"`
	CustomHeader http.Header
}
h := http.Header{
	"Bool":         []string{"true"},
	"Bool-Int":     []string{"1"},
	"X-Test-1":     []string{"233"},
	"X-Test-2":     []string{"666"},
	"Content-Type": []string{"application/json"},
	"Length":       []string{"2"},
	"X-Array":      []string{"test1", "test2"},
	"X-Empty-N":    []string{"n"},
	"Update-At":    []string{"978352496"},
	"Created-At":   []string{"Sat, 01 Jan 2000 12:34:56 GMT"},
}
var opt Options
err := httpheader.Decode(h, &opt)
fmt.Println(err)
fmt.Println(opt.ContentType)
fmt.Println(opt.Length)
fmt.Println(opt.BoolInt)
fmt.Println(opt.XArray)
fmt.Println(opt.UpdatedAt)
Output:

<nil>
application/json
2
true
[test1 test2]
2001-01-01 12:34:56 +0000 UTC

func Encode added in v0.3.0

func Encode(v interface{}) (http.Header, error)

Encode is an alias of Header function

func Header(v interface{}) (http.Header, error)

Header returns the http.Header encoding of v.

Header expects to be passed a struct, and traverses it recursively using the following encoding rules.

Each exported struct field is encoded as a Header field unless

  • the field's tag is "-", or
  • the field is empty and its tag specifies the "omitempty" option

The empty values are false, 0, any nil pointer or interface value, any array slice, map, or string of length zero, and any time.Time that returns true for IsZero().

The Header field name defaults to the struct field name but can be specified in the struct field's tag value. The "header" key in the struct field's tag value is the key name, followed by an optional comma and options. For example:

// Field is ignored by this package.
Field int `header:"-"`

// Field appears as Header field "X-Name".
Field int `header:"X-Name"`

// Field appears as Header field "X-Name" and the field is omitted if
// its value is empty
Field int `header:"X-Name,omitempty"`

// Field appears as Header field "Field" (the default), but the field
// is skipped if empty.  Note the leading comma.
Field int `header:",omitempty"`

For encoding individual field values, the following type-dependent rules apply:

Boolean values default to encoding as the strings "true" or "false". Including the "int" option signals that the field should be encoded as the strings "1" or "0".

time.Time values default to encoding as RFC1123("Mon, 02 Jan 2006 15:04:05 GMT") timestamps. Including the "unix" option signals that the field should be encoded as a Unix time (see time.Unix())

Slice and Array values default to encoding as multiple Header values of the same name. example: X-Name: []string{"Tom", "Jim"}, etc.

http.Header values will be used to extend the Header fields.

Anonymous struct fields are usually encoded as if their inner exported fields were fields in the outer struct, subject to the standard Go visibility rules. An anonymous struct field with a name given in its Header tag is treated as having that name, rather than being anonymous.

Non-nil pointer values are encoded as the value pointed to.

All other values are encoded using their default string representation.

Multiple fields that encode to the same Header filed name will be included as multiple Header values of the same name.

Example
type Options struct {
	ContentType  string `header:"Content-Type"`
	Length       int
	Bool         bool
	BoolInt      bool      `header:"Bool-Int,int"`
	XArray       []string  `header:"X-Array"`
	TestHide     string    `header:"-"`
	IgnoreEmpty  string    `header:"X-Empty,omitempty"`
	IgnoreEmptyN string    `header:"X-Empty-N,omitempty"`
	CreatedAt    time.Time `header:"Created-At"`
	UpdatedAt    time.Time `header:"Update-At,unix"`
	CustomHeader http.Header
}

opt := Options{
	ContentType:  "application/json",
	Length:       2,
	Bool:         true,
	BoolInt:      true,
	XArray:       []string{"test1", "test2"},
	TestHide:     "hide",
	IgnoreEmptyN: "n",
	CreatedAt:    time.Date(2000, 1, 1, 12, 34, 56, 0, time.UTC),
	UpdatedAt:    time.Date(2001, 1, 1, 12, 34, 56, 0, time.UTC),
	CustomHeader: http.Header{
		"X-Test-1": []string{"233"},
		"X-Test-2": []string{"666"},
	},
}
h, err := httpheader.Header(opt)
fmt.Println(err)
printHeader(h)
Output:

<nil>
Bool: []string{"true"}
Bool-Int: []string{"1"}
Content-Type: []string{"application/json"}
Created-At: []string{"Sat, 01 Jan 2000 12:34:56 GMT"}
Length: []string{"2"}
Update-At: []string{"978352496"}
X-Array: []string{"test1", "test2"}
X-Empty-N: []string{"n"}
X-Test-1: []string{"233"}
X-Test-2: []string{"666"}

Types

type Decoder added in v0.3.0

type Decoder interface {
	DecodeHeader(header http.Header, key string) error
}

Decoder is an interface implemented by any type that wishes to decode itself from Header fields in a non-standard way.

Example
// type DecodeArg struct {
// 	arg string
// }
//
// func (d *DecodeArg) DecodeHeader(header http.Header, key string) error {
// 	value := header.Get(key)
// 	d.arg = value
// 	return nil
// }

var s struct {
	Arg DecodeArg
}
h := http.Header{}
h.Set("Arg", "foobar")
err := httpheader.Decode(h, &s)
fmt.Println(err)
fmt.Println(s.Arg.arg)
Output:

<nil>
foobar

type Encoder

type Encoder interface {
	EncodeHeader(key string, v *http.Header) error
}

Encoder is an interface implemented by any type that wishes to encode itself into Header fields in a non-standard way.

Example
// type EncodedArgs []string
//
// func (e EncodedArgs) EncodeHeader(key string, v *http.Header) error {
// 	for i, arg := range e {
// 	v.Set(fmt.Sprintf("%s.%d", key, i), arg)
// }
// 	return nil
// }

s := struct {
	Args EncodedArgs `header:"Args"`
}{Args: EncodedArgs{"a", "b", "c"}}

h, err := httpheader.Header(s)
fmt.Println(err)
printHeader(h)
Output:

<nil>
Args.0: []string{"a"}
Args.1: []string{"b"}
Args.2: []string{"c"}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL