diff --git a/broker/protocol/journal_spec_extensions_test.go b/broker/protocol/journal_spec_extensions_test.go index a43187b4..b4745235 100644 --- a/broker/protocol/journal_spec_extensions_test.go +++ b/broker/protocol/journal_spec_extensions_test.go @@ -16,6 +16,7 @@ func (s *JournalSuite) TestJournalValidationCases(c *gc.C) { expect string }{ {"a/valid/path/to/a/journal", ""}, // Success. + {"a/valid/path/to/a:journal", ""}, // Success. {"/leading/slash", `cannot begin with '/' \(/leading/slash\)`}, {"trailing/slash/", `must be a clean path \(trailing/slash/\)`}, {"extra-middle//slash", `must be a clean path \(extra-middle//slash\)`}, diff --git a/broker/protocol/label_extensions.go b/broker/protocol/label_extensions.go index c97bb2dc..4b91c4ca 100644 --- a/broker/protocol/label_extensions.go +++ b/broker/protocol/label_extensions.go @@ -12,7 +12,7 @@ import ( func (m Label) Validate() error { if err := ValidateToken(m.Name, TokenSymbols, minLabelLen, maxLabelLen); err != nil { return ExtendContext(err, "Name") - } else if err = ValidateToken(m.Value, pathSymbols, 0, maxLabelValueLen); err != nil { + } else if err = ValidateToken(m.Value, PathSymbols, 0, maxLabelValueLen); err != nil { return ExtendContext(err, "Value") } return nil @@ -452,7 +452,7 @@ func parseSetParts(name, s string) ([]Label, error) { var ( reToken = ` ?([\pL\pN\` + regexp.QuoteMeta(TokenSymbols) + `]{2,})` - rePath = ` ?([\pL\pN\` + regexp.QuoteMeta(pathSymbols) + `]{0,})` + rePath = ` ?([\pL\pN\` + regexp.QuoteMeta(PathSymbols) + `]{0,})` reCommaOrEnd = ` ?(?:,|$)` reParenthetical = ` ?\(([^)]+)\)` diff --git a/broker/protocol/label_extensions_test.go b/broker/protocol/label_extensions_test.go index b5f47918..3e45d53c 100644 --- a/broker/protocol/label_extensions_test.go +++ b/broker/protocol/label_extensions_test.go @@ -16,8 +16,10 @@ func (s *LabelSuite) TestLabelValidationCases(c *gc.C) { }{ {"a-label", "a-value", ""}, // Success. {"a/label", "a%20value", ""}, // Success. + {"a-label", "a:value", ""}, // Success {"a|label", "a-value", `Name: not a valid token \(a|label\)`}, {"a-label", "a|value", `Value: not a valid token \(a|value\)`}, + {"a:label", "a-value", `Name: not a valid token \(a:label\)`}, {"a", "a-value", `Name: invalid length \(1; expected 2 <= length <= 64\)`}, {strings.Repeat("a", maxLabelLen+1), "a-value", `Name: invalid length \(65; expected .*`}, {"a-label", "", ""}, // Success diff --git a/broker/protocol/validator.go b/broker/protocol/validator.go index 47ece109..bdfc3be7 100644 --- a/broker/protocol/validator.go +++ b/broker/protocol/validator.go @@ -69,7 +69,7 @@ func ValidateToken(n, symbols string, min, max int) error { // a "clean" path (as defined by path.Clean), is non-rooted, and consists only // of characters drawn from pathSymbols. func ValidatePathComponent(n string, min, max int) error { - if err := ValidateToken(n, pathSymbols, min, max); err != nil { + if err := ValidateToken(n, PathSymbols, min, max); err != nil { return err } else if n != "" && path.Clean(n) != n { return NewValidationError("must be a clean path (%s)", n) @@ -85,7 +85,7 @@ const ( // which is the allocator KeySpace separator, must not be included in this alphabet. // The alphabet leads with '-' to facilitate escaping in |reToken|. TokenSymbols = "-_+/." - // pathSymbols is allowed runes of strings which form path components. - // It extends TokenSymbols with the '=' and '%' runes. - pathSymbols = TokenSymbols + "=%" + // PathSymbols is allowed runes of strings which form path components. + // It extends TokenSymbols with the '=', '%', and ':' runes. + PathSymbols = TokenSymbols + "=%:" ) diff --git a/consumer/protocol/shard_spec_extensions.go b/consumer/protocol/shard_spec_extensions.go index ec614164..56578269 100644 --- a/consumer/protocol/shard_spec_extensions.go +++ b/consumer/protocol/shard_spec_extensions.go @@ -31,7 +31,7 @@ func NewRoutedShardClient(sc ShardClient, dr pb.DispatchRouter) RoutedShardClien // Validate returns an error if the Shard is not well-formed. func (id ShardID) Validate() error { - if err := pb.ValidateToken(id.String(), pb.TokenSymbols, minShardNameLen, maxShardNameLen); err != nil { + if err := pb.ValidateToken(id.String(), pb.PathSymbols, minShardNameLen, maxShardNameLen); err != nil { return err } return nil diff --git a/consumer/protocol/shard_spec_extensions_test.go b/consumer/protocol/shard_spec_extensions_test.go index 2b6923dc..dd344873 100644 --- a/consumer/protocol/shard_spec_extensions_test.go +++ b/consumer/protocol/shard_spec_extensions_test.go @@ -17,6 +17,7 @@ func (s *SpecSuite) TestShardValidationCases(c *gc.C) { expect string }{ {"a-valid-shard", ""}, // Success. + {"a:valid-shard", ""}, // Success. {"not-$%|-a-token", `not a valid token \(.*\)`}, {"", `invalid length \(0; expected 4 <= .*`}, {"zz", `invalid length \(2; expected 4 <= .*`},