-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Headers improvements #23
base: master
Are you sure you want to change the base?
Changes from 1 commit
4739e13
aacdd8b
16a0ee7
79f4756
311a9d0
f5c76b0
3bf8be7
72f7beb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,10 +12,13 @@ | |
package protocol | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"strconv" | ||
"strings" | ||
"time" | ||
|
||
"github.com/google/uuid" | ||
) | ||
|
||
const ( | ||
|
@@ -72,15 +75,16 @@ const ( | |
HeaderContentType = "content-type" | ||
) | ||
|
||
// Headers represents all Ditto-specific headers along with additional HTTP/etc. headers | ||
// Headers represents all Ditto-specific headers along with additional HTTP/etc. Headers | ||
// that can be applied depending on the transport used. | ||
// For the pre-defined headers, the values are in the row type. The getter methods are provided | ||
// to get the header value in specified type. | ||
// | ||
// The header values in this map should be serialized. | ||
// The provided getter methods returns the header values which is associated with this definition's key. | ||
// See https://www.eclipse.org/ditto/protocol-specification.html | ||
type Headers map[string]interface{} | ||
|
||
// CorrelationID returns the 'correlation-id' header value if it is presented. | ||
// If the header value is not presented, the CorrelationID returns empty string. | ||
// If the header value is not presented, the 'correlation-id' header value will be generated in UUID format. | ||
// | ||
// If there are two headers differing only in capitalization CorrelationID returns the first value. | ||
// To use the provided key to get the value, access the map directly. | ||
|
@@ -90,10 +94,10 @@ func (h Headers) CorrelationID() string { | |
return v.(string) | ||
} | ||
} | ||
return "" | ||
return uuid.New().String() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If initially missing, on every invocation of CorrelationID() a newly generated id would be returned. |
||
} | ||
|
||
// Timeout returns the 'timeout' header value if it is presented | ||
// Timeout returns the 'timeout' header value if it is presented. | ||
// The default and maximum value is duration of 60 seconds. | ||
// If the header value is not presented, the Timout returns the default value. | ||
// | ||
|
@@ -134,7 +138,7 @@ func parseTimeout(timeout string) (time.Duration, error) { | |
t = time.Duration(i) * time.Second | ||
} | ||
} | ||
if t >= 0 && t < time.Hour { | ||
if t >= 0 && t <= 60*time.Second { | ||
return t, nil | ||
} | ||
} | ||
|
@@ -284,7 +288,7 @@ func (h Headers) ReplyTo() string { | |
} | ||
|
||
// Version returns the 'version' header value if it is presented. | ||
// If the header value is not presented, the Version returns 0. | ||
// If the header value is not presented, the Version returns 2. | ||
// | ||
// If there are two headers differing only in capitalization, the Version returns the first value. | ||
// To use the provided key to get the value, access the map directly. | ||
|
@@ -294,7 +298,7 @@ func (h Headers) Version() int64 { | |
return v.(int64) | ||
} | ||
} | ||
return 0 | ||
return 2 | ||
} | ||
|
||
// ContentType returns the 'content-type' header value if it is presented. | ||
|
@@ -325,44 +329,26 @@ func (h Headers) Generic(id string) interface{} { | |
return nil | ||
} | ||
|
||
// // MarshalJSON marshels Headers. | ||
// func (h *Headers) MarshalJSON() ([]byte, error) { | ||
// // TODO validation | ||
// // convert - timeout - ditto timeout string | ||
// // error for invalid values | ||
// return json.Marshal(h.Values) | ||
// } | ||
|
||
// UnmarshalJSON unmarshels Headers. | ||
// func (h *Headers) UnmarshalJSON(data []byte) error { | ||
// var m map[string]interface{} | ||
|
||
// if err := json.Unmarshal(data, &m); err != nil { | ||
// return err | ||
// } | ||
|
||
// for k := range m { | ||
// // TODO for all headers | ||
// // error for ivalid values | ||
// if strings.EqualFold(k, HeaderTimeout) && m[k] != nil { | ||
// m[k] = parseTimeout(m[k].(string)) | ||
// } | ||
// } | ||
|
||
// h.Values = m | ||
|
||
// return nil | ||
// } | ||
|
||
// UnmarshalJSON unmarshels Headers. | ||
// func (h *Headers) UnmarshalJSON(data []byte) error { | ||
// temp := make(map[string]interface{}) | ||
// if err := json.Unmarshal(data, &temp); err != nil { | ||
// return err | ||
// } | ||
// *h = temp | ||
// return nil | ||
// } | ||
// | ||
// The header names are case-insensitive and case-preserving. | ||
// If there is the same header name as the provided and the difference is | ||
// in capitalization the new header name will be set. | ||
func (h *Headers) UnmarshalJSON(data []byte) error { | ||
temp := make(map[string]interface{}) | ||
if err := json.Unmarshal(data, &temp); err != nil { | ||
return err | ||
} | ||
for k := range temp { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this cleaning needed? In the generic case the initial headers are empty. |
||
for k1 := range *h { | ||
if strings.EqualFold(k, k1) { | ||
delete(*h, k1) | ||
} | ||
} | ||
} | ||
*h = temp | ||
return nil | ||
} | ||
|
||
// With sets new Headers to the existing. | ||
func (h Headers) With(opts ...HeaderOpt) Headers { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove it. |
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,7 @@ package protocol | |
|
||
import ( | ||
"strconv" | ||
"strings" | ||
"time" | ||
) | ||
|
||
|
@@ -188,8 +189,17 @@ func WithContentType(contentType string) HeaderOpt { | |
} | ||
|
||
// WithGeneric sets the value of the provided key header. | ||
// | ||
// The header names are case-insensitive and case-preserving. | ||
// If there is the same header name as the provided and the difference is | ||
// in capitalization the new header name will be set. | ||
func WithGeneric(headerID string, value interface{}) HeaderOpt { | ||
return func(headers Headers) error { | ||
for k := range headers { | ||
if strings.EqualFold(k, headerID) { | ||
delete(headers, k) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The user might want to add several different headers with keys only differing in the capitalization. In this case the user should directly use the exported map? |
||
} | ||
} | ||
headers[headerID] = value | ||
return nil | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there are more than one headers differing only in capitalization CorrelationID returns the first met value.