blob: 08bc9e3d6c7e06e94020633850d73b4975b1834d [file] [log] [blame]
/*
* Copyright (C) 2015 Square, Inc.
*
* 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 com.squareup.okhttp;
import java.io.EOFException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import okio.Buffer;
import okio.BufferedSource;
/**
* A test from the <a href="https://github.com/w3c/web-platform-tests/tree/master/url">Web Platform
* URL test suite</a>. Each test is a line of the file {@code urltestdata.txt}; the format is
* informally specified by its JavaScript parser {@code urltestparser.js}; with which this class
* attempts to be compatible.
*
* <p>Each line of the urltestdata.text file specifies a test. Lines look like this: <pre> {@code
* http://example\t.\norg http://example.org/foo/bar s:http h:example.org p:/
* }
*/
public final class WebPlatformUrlTestData {
String input;
String base;
String scheme = "";
String username = "";
String password = null;
String host = "";
String port = "";
String path = "";
String query = "";
String fragment = "";
public boolean expectParseFailure() {
return scheme.isEmpty();
}
private void set(String name, String value) {
switch (name) {
case "s":
scheme = value;
break;
case "u":
username = value;
break;
case "pass":
password = value;
break;
case "h":
host = value;
break;
case "port":
port = value;
break;
case "p":
path = value;
break;
case "q":
query = value;
break;
case "f":
fragment = value;
break;
default:
throw new IllegalArgumentException("unexpected attribute: " + value);
}
}
@Override public String toString() {
return String.format("Parsing: <%s> against <%s>", input, base);
}
public static List<WebPlatformUrlTestData> load(BufferedSource source) throws IOException {
List<WebPlatformUrlTestData> list = new ArrayList<>();
for (String line; (line = source.readUtf8Line()) != null; ) {
if (line.isEmpty() || line.startsWith("#")) continue;
int i = 0;
String[] parts = line.split(" ");
WebPlatformUrlTestData element = new WebPlatformUrlTestData();
element.input = unescape(parts[i++]);
String base = i < parts.length ? parts[i++] : null;
element.base = (base == null || base.isEmpty())
? list.get(list.size() - 1).base
: unescape(base);
for (; i < parts.length; i++) {
String piece = parts[i];
if (piece.startsWith("#")) continue;
String[] nameAndValue = piece.split(":", 2);
element.set(nameAndValue[0], unescape(nameAndValue[1]));
}
list.add(element);
}
return list;
}
private static String unescape(String s) throws EOFException {
Buffer in = new Buffer().writeUtf8(s);
StringBuilder result = new StringBuilder();
while (!in.exhausted()) {
int c = in.readUtf8CodePoint();
if (c != '\\') {
result.append((char) c);
continue;
}
switch (in.readUtf8CodePoint()) {
case '\\':
result.append('\\');
break;
case '#':
result.append('#');
break;
case 'n':
result.append('\n');
break;
case 'r':
result.append('\r');
break;
case 's':
result.append(' ');
break;
case 't':
result.append('\t');
break;
case 'f':
result.append('\f');
break;
case 'u':
result.append((char) Integer.parseInt(in.readUtf8(4), 16));
break;
default:
throw new IllegalArgumentException("unexpected escape character in " + s);
}
}
return result.toString();
}
}