From 99ef0307e75fecc469f63a82bb72d1b697e14fff Mon Sep 17 00:00:00 2001 From: Stefan Majewsky Date: Wed, 7 Feb 2018 19:58:03 +0100 Subject: finish moving towards new auto-generated Headers implementation Everything in one package once more. The bigger API in *this* package is worth it when we don't have to expose guts to cross package boundaries. --- headers/base.go | 33 ------------- headers/errors.go | 31 ------------- headers/headers.go | 91 ------------------------------------ headers/headers_test.go | 97 -------------------------------------- headers/metadata.go | 52 --------------------- headers/string.go | 60 ------------------------ headers/time.go | 71 ---------------------------- headers/uint64.go | 120 ------------------------------------------------ 8 files changed, 555 deletions(-) delete mode 100644 headers/base.go delete mode 100644 headers/errors.go delete mode 100644 headers/headers.go delete mode 100644 headers/headers_test.go delete mode 100644 headers/metadata.go delete mode 100644 headers/string.go delete mode 100644 headers/time.go delete mode 100644 headers/uint64.go (limited to 'headers') diff --git a/headers/base.go b/headers/base.go deleted file mode 100644 index 3b5b3ec..0000000 --- a/headers/base.go +++ /dev/null @@ -1,33 +0,0 @@ -/****************************************************************************** -* -* Copyright 2018 Stefan Majewsky -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -* -******************************************************************************/ - -package headers - -//Base is an implementation detail. -type Base struct { - H Interface - K string -} - -//Interface is an implementation detail. -type Interface interface { - Clear(string) - Del(string) - Get(string) string - Set(string, string) -} diff --git a/headers/errors.go b/headers/errors.go deleted file mode 100644 index 6c1f5ab..0000000 --- a/headers/errors.go +++ /dev/null @@ -1,31 +0,0 @@ -/****************************************************************************** -* -* Copyright 2018 Stefan Majewsky -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -* -******************************************************************************/ - -package headers - -//MalformedHeaderError is generated when a response from Swift contains a -//malformed header. -type MalformedHeaderError struct { - Key string - ParseError error -} - -//Error implements the builtin/error interface. -func (e MalformedHeaderError) Error() string { - return "Bad header " + e.Key + ": " + e.ParseError.Error() -} diff --git a/headers/headers.go b/headers/headers.go deleted file mode 100644 index 33127a8..0000000 --- a/headers/headers.go +++ /dev/null @@ -1,91 +0,0 @@ -/****************************************************************************** -* -* Copyright 2018 Stefan Majewsky -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -* -******************************************************************************/ - -//Package headers contains helper types for the type-safe representation of -//headers on Swift accounts/containers/objects. -package headers - -import ( - "net/http" - "net/textproto" -) - -//Headers works like http.Header, but does not allow multiple values per key. -// -//If you write the map directly, without using the provided methods, you must -//normalize all keys with textproto.CanonicalMIMEHeaderKey(). Otherwise, the -//results are undefined. -type Headers map[string]string - -//Clear sets the value for the specified header to the empty string. When the -//Headers instance is then sent to the server with Update(), the server will -//delete the value for that header; cf. Del(). -func (h Headers) Clear(key string) { - h.Set(key, "") -} - -//Del deletes a key from the Headers instance. When the Headers instance -//is then sent to the server with Update(), Del() has different effects -//depending on context because of Swift's inconsistent API: -// -//For most writable attributes, a key which has been deleted with Del() will -//remain unchanged on the server. To remove the key on the server, use Clear() -//instead. -// -//For object metadata (but not other object attributes), deleting a key will -//cause that key to be deleted on the server. Del() is identical to Clear() in -//this case. -func (h Headers) Del(key string) { - k := textproto.CanonicalMIMEHeaderKey(key) - delete(h, k) -} - -//Get returns the value for the specified header. -func (h Headers) Get(key string) string { - if h == nil { - return "" - } - k := textproto.CanonicalMIMEHeaderKey(key) - return h[k] -} - -//Set sets a new value for the specified header, possibly overwriting a -//previous value. -func (h Headers) Set(key, value string) { - k := textproto.CanonicalMIMEHeaderKey(key) - h[k] = value -} - -//ToHTTP converts this map into a http.Header. -func (h Headers) ToHTTP() http.Header { - dest := make(http.Header, len(h)) - for k, v := range h { - dest.Set(k, v) - } - return dest -} - -//FromHTTP populates this map with the headers in the given http.Header. When a -//header has multiple values, every value but the first one will be discarded. -func (h Headers) FromHTTP(src http.Header) { - for k, v := range src { - if len(v) > 0 { - h.Set(k, v[0]) - } - } -} diff --git a/headers/headers_test.go b/headers/headers_test.go deleted file mode 100644 index 9724435..0000000 --- a/headers/headers_test.go +++ /dev/null @@ -1,97 +0,0 @@ -/****************************************************************************** -* -* Copyright 2018 Stefan Majewsky -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -* -******************************************************************************/ - -package headers - -import "testing" - -func TestHeaders(t *testing.T) { - h := make(Headers) - h.Set("first", "value1") - h.Set("second-thing", "value2") - - expectHeaders(t, h, map[string]string{ - "First": "value1", - "Second-Thing": "value2", - }) - - expectString(t, h.Get("first"), "value1") - expectString(t, h.Get("First"), "value1") - expectString(t, h.Get("FIRST"), "value1") - - h.Set("first", "changed") - h.Set("third", "") - - expectHeaders(t, h, map[string]string{ - "First": "changed", - "Second-Thing": "value2", - "Third": "", - }) - - h.Clear("second-thing") - h.Clear("fourth-thing") - - expectHeaders(t, h, map[string]string{ - "First": "changed", - "Second-Thing": "", - "Third": "", - "Fourth-Thing": "", - }) - - h.Del("FIRST") - h.Del("second-Thing") - - expectHeaders(t, h, map[string]string{ - "Third": "", - "Fourth-Thing": "", - }) - -} - -func expectString(t *testing.T, actual string, expected string) { - t.Helper() - if actual != expected { - t.Errorf("expected value %q, got %q instead\n", expected, actual) - } -} - -func expectHeaders(t *testing.T, actual Headers, expected map[string]string) { - t.Helper() - reported := make(map[string]bool) - - for k, av := range actual { - ev, exists := expected[k] - if !exists { - ev = "" - } - if av != ev { - t.Errorf(`expected "%s: %s", got "%s: %s" instead`, k, ev, k, av) - reported[k] = true - } - } - - for k, ev := range expected { - av, exists := actual[k] - if !exists { - av = "" - } - if av != ev && !reported[k] { - t.Errorf(`expected "%s: %s", got "%s: %s" instead`, k, ev, k, av) - } - } -} diff --git a/headers/metadata.go b/headers/metadata.go deleted file mode 100644 index 8f07e89..0000000 --- a/headers/metadata.go +++ /dev/null @@ -1,52 +0,0 @@ -/****************************************************************************** -* -* Copyright 2018 Stefan Majewsky -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -* -******************************************************************************/ - -package headers - -//Metadata is a helper type that provides safe access to the metadata headers -//in a schwift.Headers instance. It cannot be directly constructed, but each -//subtype of schwift.Headers has a field "Metadata" of this type. For example: -// -// var hdr ObjectHeaders -// //the following two statements are equivalent -// hdr.Set("X-Object-Meta-Access", "strictly confidential") -// hdr.Metadata.Set("Access", "strictly confidential") -// //because hdr.Metadata is a headers.Metadata instance -type Metadata struct { - Base -} - -//Clear works like Headers.Clear(), but prepends the metadata prefix to the key. -func (m Metadata) Clear(key string) { - m.H.Clear(m.K + key) -} - -//Del works like Headers.Del(), but prepends the metadata prefix to the key. -func (m Metadata) Del(key string) { - m.H.Del(m.K + key) -} - -//Get works like Headers.Get(), but prepends the metadata prefix to the key. -func (m Metadata) Get(key string) string { - return m.H.Get(m.K + key) -} - -//Set works like Headers.Set(), but prepends the metadata prefix to the key. -func (m Metadata) Set(key, value string) { - m.H.Set(m.K+key, value) -} diff --git a/headers/string.go b/headers/string.go deleted file mode 100644 index 9979aef..0000000 --- a/headers/string.go +++ /dev/null @@ -1,60 +0,0 @@ -/****************************************************************************** -* -* Copyright 2018 Stefan Majewsky -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -* -******************************************************************************/ - -package headers - -//String is a helper type that provides type-safe access to a Swift header key -//whose value is a string. It cannot be directly constructed, but some subtypes -//of schwift.Headers have fields of this type. For example: -// -// var hdr AccountHeaders -// //the following two statements are equivalent: -// hdr.Set("X-Container-Read", ".r:*,.rlistings") -// hdr.ReadACL.Set(".r:*,.rlistings") -// //because hdr.ReadACL is a headers.String instance -type String struct { - Base -} - -//Exists checks whether there is a value for this header. -func (f String) Exists() bool { - return f.H.Get(f.K) != "" -} - -//Get returns the value for this header, or the empty string if there is no value. -func (f String) Get() string { - return f.H.Get(f.K) -} - -//Set writes a new value for this header into the corresponding schwift.Headers -//instance. -func (f String) Set(value string) { - f.H.Set(f.K, value) -} - -//Del removes this key from the original schwift.Headers instance, so that the -//key will remain unchanged on the server during Update(). -func (f String) Del() { - f.H.Del(f.K) -} - -//Clear sets this key to an empty string in the original schwift.Headers -//instance, so that the key will be removed on the server during Update(). -func (f String) Clear() { - f.H.Clear(f.K) -} diff --git a/headers/time.go b/headers/time.go deleted file mode 100644 index 5f9209f..0000000 --- a/headers/time.go +++ /dev/null @@ -1,71 +0,0 @@ -/****************************************************************************** -* -* Copyright 2018 Stefan Majewsky -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -* -******************************************************************************/ - -package headers - -import ( - "math" - "strconv" - "time" -) - -//UnixTimeReadonly is a helper type that provides type-safe access to a Swift -//header whose value is a UNIX timestamp. It cannot be directly constructed, -//but some subtypes of schwift.Headers have fields of this type. For example: -// -// var hdr AccountHeaders -// //hdr.Timestamp is a headers.UnixTimeReadonly instance -// hdr.Timestamp.Get() //returns a time.Time -// hdr.Get("X-Timestamp") //returns a string containing a UNIX timestamp -// //refering to the same point in time -type UnixTimeReadonly struct { - Base -} - -//Exists checks whether there is a value for this header. -func (f UnixTimeReadonly) Exists() bool { - return f.H.Get(f.K) != "" -} - -//Get returns the value for this header, or the zero value if there is no value -//(or if it is not a valid timestamp). -func (f UnixTimeReadonly) Get() time.Time { - v, err := strconv.ParseFloat(f.H.Get(f.K), 64) - if err != nil { - return time.Time{} - } - seconds := math.Floor(v) - return time.Unix( - int64(seconds), - int64(1e9*(v-seconds)), - ) -} - -//Validate is only used internally, but needs to be exported to cross package -//boundaries. -func (f UnixTimeReadonly) Validate() error { - val := f.H.Get(f.K) - if val == "" { - return nil - } - _, err := strconv.ParseFloat(val, 64) - if err == nil { - return nil - } - return MalformedHeaderError{f.K, err} -} diff --git a/headers/uint64.go b/headers/uint64.go deleted file mode 100644 index 6e8668b..0000000 --- a/headers/uint64.go +++ /dev/null @@ -1,120 +0,0 @@ -/****************************************************************************** -* -* Copyright 2018 Stefan Majewsky -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -* -******************************************************************************/ - -package headers - -import ( - "strconv" -) - -//Uint64 is a helper type that provides type-safe access to a Swift header -//whose value is an unsigned integer. It cannot be directly constructed, but -//some subtypes of schwift.Headers have fields of this type. For example: -// -// var hdr AccountHeaders -// //the following two statements are equivalent: -// hdr.Set("X-Account-Meta-Quota-Bytes", "1048576") -// hdr.QuotaBytes.Set(1 << 20) -// //because hdr.QuotaBytes is a headers.Uint64 instance -type Uint64 struct { - Base -} - -//Exists checks whether there is a value for this header. -func (f Uint64) Exists() bool { - return f.H.Get(f.K) != "" -} - -//Get returns the value for this header, or 0 if there is no value (or if it is -//not a valid uint64). -func (f Uint64) Get() uint64 { - v, err := strconv.ParseUint(f.H.Get(f.K), 10, 64) - if err != nil { - return 0 - } - return v -} - -//Set writes a new value for this header into the corresponding schwift.Headers -//instance. -func (f Uint64) Set(value uint64) { - f.H.Set(f.K, strconv.FormatUint(value, 10)) -} - -//Del removes this key from the original schwift.Headers instance, so that the -//key will remain unchanged on the server during Update(). -func (f Uint64) Del() { - f.H.Del(f.K) -} - -//Clear sets this key to an empty string in the original schwift.Headers -//instance, so that the key will be removed on the server during Update(). -func (f Uint64) Clear() { - f.H.Clear(f.K) -} - -//Validate is only used internally, but needs to be exported to cross package -//boundaries. -func (f Uint64) Validate() error { - val := f.H.Get(f.K) - if val == "" { - return nil - } - _, err := strconv.ParseUint(val, 10, 64) - if err == nil { - return nil - } - return MalformedHeaderError{f.K, err} -} - -//////////////////////////////////////////////////////////////////////////////// - -//Uint64Readonly is a readonly variant of Uint64. It is used for fields that -//cannot be set by the client. -type Uint64Readonly struct { - Base -} - -//Exists checks whether there is a value for this header. -func (f Uint64Readonly) Exists() bool { - return f.H.Get(f.K) != "" -} - -//Get returns the value for this header, or 0 if there is no value (or if it is -//not a valid uint64). -func (f Uint64Readonly) Get() uint64 { - v, err := strconv.ParseUint(f.H.Get(f.K), 10, 64) - if err != nil { - return 0 - } - return v -} - -//Validate is only used internally, but needs to be exported to cross package -//boundaries. -func (f Uint64Readonly) Validate() error { - val := f.H.Get(f.K) - if val == "" { - return nil - } - _, err := strconv.ParseUint(val, 10, 64) - if err == nil { - return nil - } - return MalformedHeaderError{f.K, err} -} -- cgit v1.2.3