Skip to content

Commit

Permalink
Merge pull request #79 from microsoft/andrueastman/responseHeaders
Browse files Browse the repository at this point in the history
Adds response headers to API Exception
  • Loading branch information
andrueastman authored Apr 26, 2023
2 parents 846526e + a1784b7 commit 47c17a4
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 98 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

## [0.20.0] - 2023-04-12

### Added

- Adds response headers to Api Error class

### Changed

## [0.19.1] - 2023-04-12

### Added
Expand Down
3 changes: 2 additions & 1 deletion api_error.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import "fmt"
type ApiError struct {
Message string
ResponseStatusCode int
ResponseHeaders *ResponseHeaders
}

func (e *ApiError) Error() string {
Expand All @@ -18,5 +19,5 @@ func (e *ApiError) Error() string {

// NewApiError creates a new ApiError instance
func NewApiError() *ApiError {
return &ApiError{}
return &ApiError{ResponseHeaders: NewResponseHeaders()}
}
111 changes: 111 additions & 0 deletions headers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package abstractions

import "strings"

type header struct {
headers map[string]map[string]struct{}
}

type void struct{}

var voidInstance void

func normalizeHeaderKey(key string) string {
return strings.ToLower(strings.Trim(key, " "))
}

//Add adds a new header or append a new value to an existing header
func (r *header) Add(key string, value string, additionalValues ...string) {
normalizedKey := normalizeHeaderKey(key)
if normalizedKey == "" || value == "" {
return
}
if r.headers == nil {
r.headers = make(map[string]map[string]struct{})
}
if r.headers[normalizedKey] == nil {
r.headers[normalizedKey] = make(map[string]struct{})
}
r.headers[normalizedKey][value] = voidInstance
for _, v := range additionalValues {
r.headers[normalizedKey][v] = voidInstance
}
}

//Get returns the values for the specific header
func (r *header) Get(key string) []string {
if r.headers == nil {
return nil
}
normalizedKey := normalizeHeaderKey(key)
if r.headers[normalizedKey] == nil {
return make([]string, 0)
}
values := make([]string, 0, len(r.headers[normalizedKey]))
for k := range r.headers[normalizedKey] {
values = append(values, k)
}
return values
}

//Remove removes the specific header and all its values
func (r *header) Remove(key string) {
if r.headers == nil {
return
}
normalizedKey := normalizeHeaderKey(key)
delete(r.headers, normalizedKey)
}

//RemoveValue remove the value for the specific header
func (r *header) RemoveValue(key string, value string) {
if r.headers == nil {
return
}
normalizedKey := normalizeHeaderKey(key)
if r.headers[normalizedKey] == nil {
return
}
delete(r.headers[normalizedKey], value)
if len(r.headers[normalizedKey]) == 0 {
delete(r.headers, normalizedKey)
}
}

//ContainsKey check if the key exists in the headers
func (r *header) ContainsKey(key string) bool {
if r.headers == nil {
return false
}
normalizedKey := normalizeHeaderKey(key)
return r.headers[normalizedKey] != nil
}

//Clear clear all headers
func (r *header) Clear() {
r.headers = nil
}

//AddAll adds all headers from the other headers
func (r *header) AddAll(other *header) {
if other == nil || other.headers == nil {
return
}
for k, v := range other.headers {
for k2 := range v {
r.Add(k, k2)
}
}
}

//ListKeys returns all the keys in the headers
func (r *header) ListKeys() []string {
if r.headers == nil {
return make([]string, 0)
}
keys := make([]string, 0, len(r.headers))
for k := range r.headers {
keys = append(keys, k)
}
return keys
}
100 changes: 3 additions & 97 deletions request_headers.go
Original file line number Diff line number Diff line change
@@ -1,100 +1,18 @@
package abstractions

import "strings"

//RequestHeaders represents a collection of request headers
type RequestHeaders struct {
headers map[string]map[string]struct{}
header
}

//NewRequestHeaders creates a new RequestHeaders
func NewRequestHeaders() *RequestHeaders {
return &RequestHeaders{
headers: make(map[string]map[string]struct{}),
header{make(map[string]map[string]struct{})},
}
}

func (r *RequestHeaders) normalizeHeaderKey(key string) string {
return strings.ToLower(strings.Trim(key, " "))
}

type void struct{}

var voidInstance void

//Add adds a new header or append a new value to an existing header
func (r *RequestHeaders) Add(key string, value string, additionalValues ...string) {
normalizedKey := r.normalizeHeaderKey(key)
if normalizedKey == "" || value == "" {
return
}
if r.headers == nil {
r.headers = make(map[string]map[string]struct{})
}
if r.headers[normalizedKey] == nil {
r.headers[normalizedKey] = make(map[string]struct{})
}
r.headers[normalizedKey][value] = voidInstance
for _, v := range additionalValues {
r.headers[normalizedKey][v] = voidInstance
}
}

//Get returns the values for the specific header
func (r *RequestHeaders) Get(key string) []string {
if r.headers == nil {
return nil
}
normalizedKey := r.normalizeHeaderKey(key)
if r.headers[normalizedKey] == nil {
return make([]string, 0)
}
values := make([]string, 0, len(r.headers[normalizedKey]))
for k := range r.headers[normalizedKey] {
values = append(values, k)
}
return values
}

//Remove removes the specific header and all its values
func (r *RequestHeaders) Remove(key string) {
if r.headers == nil {
return
}
normalizedKey := r.normalizeHeaderKey(key)
delete(r.headers, normalizedKey)
}

//RemoveValue remove the value for the specific header
func (r *RequestHeaders) RemoveValue(key string, value string) {
if r.headers == nil {
return
}
normalizedKey := r.normalizeHeaderKey(key)
if r.headers[normalizedKey] == nil {
return
}
delete(r.headers[normalizedKey], value)
if len(r.headers[normalizedKey]) == 0 {
delete(r.headers, normalizedKey)
}
}

//ContainsKey check if the key exists in the headers
func (r *RequestHeaders) ContainsKey(key string) bool {
if r.headers == nil {
return false
}
normalizedKey := r.normalizeHeaderKey(key)
return r.headers[normalizedKey] != nil
}

//Clear clear all headers
func (r *RequestHeaders) Clear() {
r.headers = nil
}

//AddAll adds all headers from the other RequestHeaders
//AddAll adds all headers from the other headers
func (r *RequestHeaders) AddAll(other *RequestHeaders) {
if other == nil || other.headers == nil {
return
Expand All @@ -105,15 +23,3 @@ func (r *RequestHeaders) AddAll(other *RequestHeaders) {
}
}
}

//ListKeys returns all the keys in the headers
func (r *RequestHeaders) ListKeys() []string {
if r.headers == nil {
return make([]string, 0)
}
keys := make([]string, 0, len(r.headers))
for k := range r.headers {
keys = append(keys, k)
}
return keys
}
25 changes: 25 additions & 0 deletions response_headers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package abstractions

//ResponseHeaders represents a collection of response headers
type ResponseHeaders struct {
header
}

//NewResponseHeaders creates a new ResponseHeaders
func NewResponseHeaders() *ResponseHeaders {
return &ResponseHeaders{
header{make(map[string]map[string]struct{})},
}
}

//AddAll adds all headers from the other headers
func (r *ResponseHeaders) AddAll(other *ResponseHeaders) {
if other == nil || other.headers == nil {
return
}
for k, v := range other.headers {
for k2 := range v {
r.Add(k, k2)
}
}
}

0 comments on commit 47c17a4

Please sign in to comment.