| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to you 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 org.apache.jmeter.protocol.http.util |
| |
| import spock.lang.Specification |
| import spock.lang.Unroll |
| |
| @Unroll |
| class HTTPUtilsSpec extends Specification { |
| |
| def "getEncoding returns #expectedEncoding from #contentType"() { |
| expect: |
| ConversionUtils.getEncodingFromContentType(contentType) == expectedEncoding |
| where: |
| contentType | expectedEncoding |
| "charset=utf8" | "utf8" |
| "charset=\"utf8\"" | "utf8" |
| "text/plain ;charset=utf8" | "utf8" |
| "text/html ;charset=utf8;charset=def" | "utf8" |
| "xyx" | null |
| "charset=" | null |
| ";charset=;" | null |
| ";charset=no-such-charset;" | null |
| } |
| |
| def "makeRelativeURL works with a trailing file"() { |
| given: |
| URL baseURL = new URL("http://192.168.0.1/a/b/c") |
| when: |
| def relativeURL = ConversionUtils.makeRelativeURL(baseURL, path) |
| then: |
| relativeURL == new URL(expectedURL) |
| where: |
| path | expectedURL |
| "d" | "http://192.168.0.1/a/b/d" |
| "../d" | "http://192.168.0.1/a/d" |
| "../../d" | "http://192.168.0.1/d" |
| "../../../d" | "http://192.168.0.1/d" |
| "../../../../d" | "http://192.168.0.1/d" |
| "/../d" | "http://192.168.0.1/../d" |
| "./d" | "http://192.168.0.1/a/b/d" |
| } |
| |
| def "makeRelativeURL works with a trailing directory"() { |
| given: |
| URL baseURL = new URL("http://192.168.0.1/a/b/c/") |
| when: |
| def relativeURL = ConversionUtils.makeRelativeURL(baseURL, path) |
| then: |
| relativeURL == new URL(expectedURL) |
| where: |
| path | expectedURL |
| "d" | "http://192.168.0.1/a/b/c/d" |
| "../d" | "http://192.168.0.1/a/b/d" |
| "../../d" | "http://192.168.0.1/a/d" |
| "../../../d" | "http://192.168.0.1/d" |
| "../../../../d" | "http://192.168.0.1/d" |
| "/../d" | "http://192.168.0.1/../d" |
| "./d" | "http://192.168.0.1/a/b/c/d" |
| } |
| |
| // Test that location urls with a protocol are passed unchanged |
| def "makeRelativeURL given invalid path '#path' returns '#path'"() { |
| given: |
| URL baseURL = new URL("http://ahost.invalid/a/b/c") |
| when: |
| def relativeURL = ConversionUtils.makeRelativeURL(baseURL, path) |
| then: |
| relativeURL == new URL(path) |
| where: |
| path << ["http://host.invalid/e", |
| "https://host.invalid/e", |
| "http://host.invalid:8081/e", |
| "https://host.invalid:8081/e"] |
| } |
| |
| def "removeSlashDotDot given a url or path #urlOrPath returns #expectedUrl"() { |
| expect: |
| ConversionUtils.removeSlashDotDot(urlOrPath) == expectedUrl |
| where: |
| urlOrPath | expectedUrl |
| "/path/" | "/path/" |
| "http://host/" | "http://host/" |
| "http://host/one" | "http://host/one" |
| "/one/../two" | "/two" |
| "http://host:8080/one/../two" | "http://host:8080/two" |
| "http://host:8080/one/../two/" | "http://host:8080/two/" |
| "http://usr@host:8080/one/../two/" | "http://usr@host:8080/two/" |
| "http://host:8080/one/../two/?query#anchor" | "http://host:8080/two/?query#anchor" |
| "one/two/.." | "one" |
| "../../path" | "../../path" |
| "/one/.." | "/" |
| "/one/../" | "/" |
| "/one/..?a" | "/?a" |
| "http://host/one/../one" | "http://host/one" |
| "http://host/one/two/../../one/two" | "http://host/one/two" |
| "http://host/.." | "http://host/.." |
| "http://host/../abc" | "http://host/../abc" |
| } |
| |
| def testSanitizeUrl() { |
| expect: |
| ConversionUtils.sanitizeUrl(new URL(input)) == new URI(expected) |
| where: |
| input | expected |
| 'http://localhost/' | 'http://localhost/' // normal, no encoding needed |
| 'http://192.168.0.1/' | 'http://192.168.0.1/' // normal, no encoding needed |
| 'http://host/a/b/c|d' | 'http://host/a/b/c%7Cd' // pipe needs encoding |
| 'http://host:8080/%5B%5D' | 'http://host:8080/%5B%5D' // already encoded |
| 'http://host:8080/?%5B%5D' | 'http://host:8080/?%5B%5D' //already encoded |
| 'http://host:8080/?!£$*():@~;\'\"%^{}[]<>|\\#' | 'http://host:8080/?!£$*():@~;\'%22%25%5E%7B%7D[]%3C%3E%7C%5C#' // unencoded query |
| 'http://host/?!£$*():@~;\'%22%25%5E%7B%7D[]%3C%3E%7C%5C#' | 'http://host/?!£$*():@~;\'%22%25%5E%7B%7D[]%3C%3E%7C%5C#' // encoded |
| 'http://host:8080/!£$*():@~;\'"%^{}[]<>|\\#' | 'http://host:8080/!£$*():@~;\'%22%25%5E%7B%7D%5B%5D%3C%3E%7C%5C#' // unencoded path |
| 'http://host/!£$*():@~;\'%22%25%5E%7B%7D%5B%5D%3C%3E%7C%5C#' | 'http://host/!£$*():@~;\'%22%25%5E%7B%7D%5B%5D%3C%3E%7C%5C#' // encoded |
| 'http://host/?%25%5B%5D!@$%^*()#' | 'http://host/?%2525%255B%255D!@$%25%5E*()#' |
| 'http://host/?%2525%255B%255D!@$%25%5E*()#' | 'http://host/?%2525%255B%255D!@$%25%5E*()#' |
| 'http://host/%5B%5D?[]!@$%^*()#' | 'http://host/%255B%255D?[]!@$%25%5E*()#' |
| 'http://host/%255B%255D?[]!@$%25%5E*()#' | 'http://host/%255B%255D?[]!@$%25%5E*()#' |
| 'http://host/IqGo6EM1JEVZ+MSRJqUSo@qhjVMSFBTs/37/0/1' | 'http://host/IqGo6EM1JEVZ+MSRJqUSo@qhjVMSFBTs/37/0/1' |
| 'http://host/test?getItem={someID}' | 'http://host/test?getItem=%7BsomeID%7D' |
| } |
| } |