Atlas › Test

valid_param_not_quoted

Exact test identity: go.temporal.io/server/common/nexus/nexusrpc/TestDecodeLink/valid_param_not_quoted

Package
go.temporal.io/server/common/nexus/nexusrpc
Suite / test hierarchy
TestDecodeLink/valid_param_not_quoted
Test
valid_param_not_quoted
Introduced at
api.go ×2 Frontier kind: Joint frontier
Covered ranges
22
Covered lines
45
Covered files
1

Covered source

Expand a file to inspect source; the > gutter marks covered lines.

go.temporal.io/server/common/nexus/nexusrpc/api.go 45 covered LOC · 22 ranges

Open complete file

152 // decodeLink decodes the Nexus-Link header values.
153 // It must have the same format of HTTP Link header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Link
154 > func decodeLink(encodedLink string) (nexus.Link, error) { api.go
155 > var link nexus.Link
156 > encodedLink = strings.TrimSpace(encodedLink)
157 > if len(encodedLink) == 0 {
158 return link, errors.New("failed to parse link header: value is empty")
159 }
160
161 > if encodedLink[0] != '<' { api.go
162 return link, fmt.Errorf("failed to parse link header: invalid format: %s", encodedLink)
163 }
164 > urlEnd := strings.Index(encodedLink, ">") api.go
165 > if urlEnd == -1 {
166 return link, fmt.Errorf("failed to parse link header: invalid format: %s", encodedLink)
167 }
168 > urlStr := strings.TrimSpace(encodedLink[1:urlEnd]) api.go
169 > if len(urlStr) == 0 {
170 return link, errors.New("failed to parse link header: url is empty")
171 }
172 > u, err := url.Parse(urlStr) api.go
173 > if err != nil {
174 return link, fmt.Errorf("failed to parse link header: invalid url: %s", urlStr)
175 }
176 > if err := validateLinkURL(u); err != nil { api.go
177 return link, fmt.Errorf("failed to parse link header: %w", err)
178 }
179 > link.URL = u api.go
180 >
181 > params := strings.Split(encodedLink[urlEnd+1:], ";")
182 > // must contain at least one semi-colon, and first param must be empty since
183 > // it corresponds to the url part parsed above.
184 > if len(params) < 2 {
185 return link, fmt.Errorf("failed to parse link header: invalid format: %s", encodedLink)
186 }
187 > if strings.TrimSpace(params[0]) != "" { api.go
188 return link, fmt.Errorf("failed to parse link header: invalid format: %s", encodedLink)
189 }
190
191 > typeKeyFound := false api.go
192 > for _, param := range params[1:] {
193 > param = strings.TrimSpace(param)
194 > if len(param) == 0 {
195 return link, fmt.Errorf("failed to parse link header: parameter is empty: %s", encodedLink)
196 }
197 > kv := strings.SplitN(param, "=", 2) api.go
198 > if len(kv) != 2 {
199 return link, fmt.Errorf("failed to parse link header: invalid parameter format: %s", param)
200 }
201 > key := strings.TrimSpace(kv[0]) api.go
202 > val := strings.TrimSpace(kv[1])
203 > if strings.HasPrefix(val, `"`) != strings.HasSuffix(val, `"`) {
204 return link, fmt.Errorf(
205 "failed to parse link header: parameter value missing double-quote: %s",
207 )
208 }
209 > if strings.HasPrefix(val, `"`) { api.go
210 val = val[1 : len(val)-1]
211 }
212 > if key == linkTypeKey { api.go
213 > if err := validateLinkType(val); err != nil {
214 return link, fmt.Errorf("failed to parse link header: %w", err)
215 }
216 > link.Type = val api.go
217 > typeKeyFound = true
218 }
219 }
220 > if !typeKeyFound { api.go
221 return link, fmt.Errorf(
222 "failed to parse link header: %q key not found: %s",
226 }
227
228 > return link, nil api.go
229 }
230
231 > func validateLinkURL(value *url.URL) error { api.go
232 > if value == nil || value.String() == "" {
233 return errors.New("url is empty")
234 }
235 > _, err := url.ParseQuery(value.RawQuery) api.go
236 > if err != nil {
237 return fmt.Errorf("url query not percent-encoded: %s", value)
238 }
239 > return nil api.go
240 }
241
242 > func validateLinkType(value string) error { api.go
243 > if len(value) == 0 {
244 return errors.New("link type is empty")
245 }
246 > for _, c := range value { api.go
247 > if (c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && (c < '0' || c > '9') && c != '_' && c != '.' && c != '/' {
248 return errors.New("link type contains invalid char (valid chars: alphanumeric, '_', '.', '/')")
249 }
250 }
251 > return nil api.go
252 }
253