1 /* 2 * Copyright (C) 2015 Square, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.squareup.okhttp; 17 18 import java.io.EOFException; 19 import java.io.IOException; 20 import java.util.ArrayList; 21 import java.util.List; 22 import okio.Buffer; 23 import okio.BufferedSource; 24 25 /** 26 * A test from the <a href="https://github.com/w3c/web-platform-tests/tree/master/url">Web Platform 27 * URL test suite</a>. Each test is a line of the file {@code urltestdata.txt}; the format is 28 * informally specified by its JavaScript parser {@code urltestparser.js}; with which this class 29 * attempts to be compatible. 30 * 31 * <p>Each line of the urltestdata.text file specifies a test. Lines look like this: <pre> {@code 32 * 33 * http://example\t.\norg http://example.org/foo/bar s:http h:example.org p:/ 34 * }</pre> 35 */ 36 public final class WebPlatformUrlTestData { 37 String input; 38 String base; 39 String scheme = ""; 40 String username = ""; 41 String password = null; 42 String host = ""; 43 String port = ""; 44 String path = ""; 45 String query = ""; 46 String fragment = ""; 47 expectParseFailure()48 public boolean expectParseFailure() { 49 return scheme.isEmpty(); 50 } 51 set(String name, String value)52 private void set(String name, String value) { 53 switch (name) { 54 case "s": 55 scheme = value; 56 break; 57 case "u": 58 username = value; 59 break; 60 case "pass": 61 password = value; 62 break; 63 case "h": 64 host = value; 65 break; 66 case "port": 67 port = value; 68 break; 69 case "p": 70 path = value; 71 break; 72 case "q": 73 query = value; 74 break; 75 case "f": 76 fragment = value; 77 break; 78 default: 79 throw new IllegalArgumentException("unexpected attribute: " + value); 80 } 81 } 82 toString()83 @Override public String toString() { 84 return String.format("Parsing: <%s> against <%s>", input, base); 85 } 86 load(BufferedSource source)87 public static List<WebPlatformUrlTestData> load(BufferedSource source) throws IOException { 88 List<WebPlatformUrlTestData> list = new ArrayList<>(); 89 for (String line; (line = source.readUtf8Line()) != null; ) { 90 if (line.isEmpty() || line.startsWith("#")) continue; 91 92 int i = 0; 93 String[] parts = line.split(" "); 94 WebPlatformUrlTestData element = new WebPlatformUrlTestData(); 95 element.input = unescape(parts[i++]); 96 97 String base = i < parts.length ? parts[i++] : null; 98 element.base = (base == null || base.isEmpty()) 99 ? list.get(list.size() - 1).base 100 : unescape(base); 101 102 for (; i < parts.length; i++) { 103 String piece = parts[i]; 104 if (piece.startsWith("#")) continue; 105 String[] nameAndValue = piece.split(":", 2); 106 element.set(nameAndValue[0], unescape(nameAndValue[1])); 107 } 108 109 list.add(element); 110 } 111 return list; 112 } 113 114 private static String unescape(String s) throws EOFException { 115 Buffer in = new Buffer().writeUtf8(s); 116 StringBuilder result = new StringBuilder(); 117 while (!in.exhausted()) { 118 int c = in.readUtf8CodePoint(); 119 if (c != '\\') { 120 result.append((char) c); 121 continue; 122 } 123 124 switch (in.readUtf8CodePoint()) { 125 case '\\': 126 result.append('\\'); 127 break; 128 case '#': 129 result.append('#'); 130 break; 131 case 'n': 132 result.append('\n'); 133 break; 134 case 'r': 135 result.append('\r'); 136 break; 137 case 's': 138 result.append(' '); 139 break; 140 case 't': 141 result.append('\t'); 142 break; 143 case 'f': 144 result.append('\f'); 145 break; 146 case 'u': 147 result.append((char) Integer.parseInt(in.readUtf8(4), 16)); 148 break; 149 default: 150 throw new IllegalArgumentException("unexpected escape character in " + s); 151 } 152 } 153 154 return result.toString(); 155 } 156 } 157