File: hostnameparams.go

package info (click to toggle)
golang-github-seancfoley-ipaddress-go 1.5.4-3
  • links: PTS, VCS
  • area: main
  • in suites: experimental, forky, sid, trixie
  • size: 3,700 kB
  • sloc: makefile: 3
file content (242 lines) | stat: -rw-r--r-- 10,305 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
//
// Copyright 2020-2022 Sean C Foley
//
// 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 addrstrparam

// CopyHostNameParams produces an immutable copy of the original HostNameParams.
// Copying a HostNameParams created by a HostNameParamsBuilder is unnecessary since it is already immutable.
func CopyHostNameParams(orig HostNameParams) HostNameParams {
	if p, ok := orig.(*hostNameParameters); ok {
		return p
	}
	return new(HostNameParamsBuilder).Set(orig).ToParams()
}

// HostNameParams provides parameters for parsing host name strings.
//
// This allows you to control the validation performed by HostName.
//
// HostName uses a default permissive HostNameParams object when you do not specify one.
//
// If you wish to use parameters different from the default, then use this interface.  Immutable instances can be constructed with HostNameParamsBuilder.
type HostNameParams interface {
	// AllowsEmpty determines if an empty host string is considered valid.
	// The parser will first parse as an empty address, if allowed by the nested IPAddressStringParams.
	// Otherwise, it will be considered an empty host if this returns true, or an invalid host if it returns false.
	AllowsEmpty() bool

	// GetPreferredVersion indicates the version to prefer when resolving host names.
	GetPreferredVersion() IPVersion

	// AllowsBracketedIPv4 allows bracketed IPv4 addresses like "[1.2.3.4]".
	AllowsBracketedIPv4() bool

	// AllowsBracketedIPv6 allows bracketed IPv6 addresses like "[1::2]".
	AllowsBracketedIPv6() bool

	// NormalizesToLowercase indicates whether to normalize the host name to lowercase characters when parsing.
	NormalizesToLowercase() bool

	// AllowsIPAddress allows a host name to specify an IP address or subnet.
	AllowsIPAddress() bool

	// AllowsPort allows a host name to specify a port.
	AllowsPort() bool

	// AllowsService allows a host name to specify a service, which typically maps to a port.
	AllowsService() bool

	// ExpectsPort indicates whether a port should be inferred from a host like 1:2:3:4::80 that is ambiguous if a port might have been appended.
	// The final segment would normally be considered part of the address, but can be interpreted as a port instead.
	ExpectsPort() bool

	// GetIPAddressParams returns the parameters that apply specifically to IP addresses and subnets, whenever a host name specifies an IP addresses or subnet.
	GetIPAddressParams() IPAddressStringParams
}

// hostNameParameters has parameters for parsing host name strings.
// They are immutable and can be constructed using an HostNameParamsBuilder.
type hostNameParameters struct {
	ipParams ipAddressStringParameters

	preferredVersion IPVersion

	noEmpty, noBracketedIPv4, noBracketedIPv6,
	noNormalizeToLower, noIPAddress, noPort, noService, expectPort bool
}

// AllowsEmpty determines if an empty host string is considered valid.
// The parser will first parse as an empty address, if allowed by the nested IPAddressStringParams.
// Otherwise, it will be considered an empty host if this returns true, or an invalid host if it returns false.
func (params *hostNameParameters) AllowsEmpty() bool {
	return !params.noEmpty
}

// GetPreferredVersion indicates the version to prefer when resolving host names.
func (params *hostNameParameters) GetPreferredVersion() IPVersion {
	return params.preferredVersion
}

// AllowsBracketedIPv4 allows bracketed IPv4 addresses like "[1.2.3.4]".
func (params *hostNameParameters) AllowsBracketedIPv4() bool {
	return !params.noBracketedIPv4
}

// AllowsBracketedIPv6 allows bracketed IPv6 addresses like "[1::2]".
func (params *hostNameParameters) AllowsBracketedIPv6() bool {
	return !params.noBracketedIPv6
}

// NormalizesToLowercase indicates whether to normalize the host name to lowercase characters when parsing.
func (params *hostNameParameters) NormalizesToLowercase() bool {
	return !params.noNormalizeToLower
}

// AllowsIPAddress allows a host name to specify an IP address or subnet.
func (params *hostNameParameters) AllowsIPAddress() bool {
	return !params.noIPAddress
}

// AllowsPort allows a host name to specify a port.
func (params *hostNameParameters) AllowsPort() bool {
	return !params.noPort
}

// AllowsService allows a host name to specify a service, which typically maps to a port.
func (params *hostNameParameters) AllowsService() bool {
	return !params.noService
}

// ExpectsPort indicates whether a port should be inferred from a host like 1:2:3:4::80 that is ambiguous if a port might have been appended.
// The final segment would normally be considered part of the address, but can be interpreted as a port instead.
func (params *hostNameParameters) ExpectsPort() bool {
	return params.expectPort
}

// GetIPAddressParams returns the parameters that apply specifically to IP addresses and subnets, whenever a host name specifies an IP addresses or subnet.
func (params *hostNameParameters) GetIPAddressParams() IPAddressStringParams {
	return &params.ipParams
}

// HostNameParamsBuilder builds an immutable HostNameParams for controlling parsing of host names.
type HostNameParamsBuilder struct {
	hostNameParameters

	ipAddressBuilder IPAddressStringParamsBuilder
}

// ToParams returns an immutable HostNameParams instance built by this builder.
func (builder *HostNameParamsBuilder) ToParams() HostNameParams {
	// We do not return a pointer to builder.hostNameParameters because that would make it possible to change params
	// by continuing to use the same builder,
	// and we want immutable objects for concurrency-safety,
	// so we cannot allow it
	result := builder.hostNameParameters
	result.ipParams = *builder.ipAddressBuilder.ToParams().(*ipAddressStringParameters)
	return &result
}

// GetIPAddressParamsBuilder returns a builder that builds the IPAddressStringParams for the HostNameParams being built by this builder.
func (builder *HostNameParamsBuilder) GetIPAddressParamsBuilder() (result *IPAddressStringParamsBuilder) {
	result = &builder.ipAddressBuilder
	result.parent = builder
	return
}

// Set populates this builder with the values from the given HostNameParams.
func (builder *HostNameParamsBuilder) Set(params HostNameParams) *HostNameParamsBuilder {
	if p, ok := params.(*hostNameParameters); ok {
		builder.hostNameParameters = *p
	} else {
		builder.hostNameParameters = hostNameParameters{
			preferredVersion:   params.GetPreferredVersion(),
			noEmpty:            !params.AllowsEmpty(),
			noBracketedIPv4:    !params.AllowsBracketedIPv4(),
			noBracketedIPv6:    !params.AllowsBracketedIPv6(),
			noNormalizeToLower: !params.NormalizesToLowercase(),
			noIPAddress:        !params.AllowsIPAddress(),
			noPort:             !params.AllowsPort(),
			noService:          !params.AllowsService(),
			expectPort:         params.ExpectsPort(),
		}
	}
	builder.SetIPAddressParams(params.GetIPAddressParams())
	return builder
}

// SetIPAddressParams populates this builder with the values from the given IPAddressStringParams.
func (builder *HostNameParamsBuilder) SetIPAddressParams(params IPAddressStringParams) *HostNameParamsBuilder {
	//builder.ipAddressBuilder = *ToIPAddressStringParamsBuilder(params)
	builder.ipAddressBuilder.Set(params)
	return builder
}

// AllowEmpty dictates whether an empty host string is considered valid.
// The parser will first parse as an empty address, if allowed by the nested IPAddressStringParams.
// Otherwise, this setting dictates whether it will be considered an invalid host.
func (builder *HostNameParamsBuilder) AllowEmpty(allow bool) *HostNameParamsBuilder {
	builder.hostNameParameters.noEmpty = !allow
	return builder
}

// SetPreferredVersion dictates the version to prefer when resolving host names.
func (builder *HostNameParamsBuilder) SetPreferredVersion(version IPVersion) *HostNameParamsBuilder {
	builder.hostNameParameters.preferredVersion = version
	return builder
}

// AllowBracketedIPv4 dictates whether to allow bracketed IPv4 addresses like "[1.2.3.4]".
func (builder *HostNameParamsBuilder) AllowBracketedIPv4(allow bool) *HostNameParamsBuilder {
	builder.hostNameParameters.noBracketedIPv4 = !allow
	return builder
}

// AllowBracketedIPv6 dictates whether to allow bracketed IPv6 addresses like "[1::2]".
func (builder *HostNameParamsBuilder) AllowBracketedIPv6(allow bool) *HostNameParamsBuilder {
	builder.hostNameParameters.noBracketedIPv6 = !allow
	return builder
}

// NormalizeToLowercase dictates whether to normalize the host name to lowercase characters when parsing.
func (builder *HostNameParamsBuilder) NormalizeToLowercase(allow bool) *HostNameParamsBuilder {
	builder.hostNameParameters.noNormalizeToLower = !allow
	return builder
}

// AllowIPAddress dictates whether to allow a host name to specify an IP address or subnet.
func (builder *HostNameParamsBuilder) AllowIPAddress(allow bool) *HostNameParamsBuilder {
	builder.hostNameParameters.noIPAddress = !allow
	return builder
}

// AllowPort dictates whether to allow a host name to specify a port.
func (builder *HostNameParamsBuilder) AllowPort(allow bool) *HostNameParamsBuilder {
	builder.hostNameParameters.noPort = !allow
	return builder
}

// AllowService dictates whether to allow a host name to specify a service, which typically maps to a port.
func (builder *HostNameParamsBuilder) AllowService(allow bool) *HostNameParamsBuilder {
	builder.hostNameParameters.noService = !allow
	return builder
}

// ExpectPort dictates whether a port should be inferred from a host like 1:2:3:4::80 that is ambiguous if a port might have been appended.
// The final segment would normally be considered part of the address, but can be interpreted as a port instead.
func (builder *HostNameParamsBuilder) ExpectPort(expect bool) *HostNameParamsBuilder {
	builder.hostNameParameters.expectPort = expect
	return builder
}