mirror of
https://github.com/google/nomulus.git
synced 2025-05-13 16:07:15 +02:00
RDAP: Display truncation notice for large nameserver result sets
The ICAAN Operational Profile dictates that a notice be added to the RDAP search results response when there are more objects than the server's chosen result set size. This CL handles the fixes for nameserver searches. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=135411617
This commit is contained in:
parent
43c67403fa
commit
5c5499d598
5 changed files with 456 additions and 57 deletions
|
@ -573,11 +573,11 @@ public class RdapJsonFormatter {
|
||||||
new ImmutableMap.Builder<>();
|
new ImmutableMap.Builder<>();
|
||||||
ImmutableList<String> v4Addresses = v4AddressesBuilder.build();
|
ImmutableList<String> v4Addresses = v4AddressesBuilder.build();
|
||||||
if (!v4Addresses.isEmpty()) {
|
if (!v4Addresses.isEmpty()) {
|
||||||
ipAddressesBuilder.put("v4", v4Addresses);
|
ipAddressesBuilder.put("v4", Ordering.natural().immutableSortedCopy(v4Addresses));
|
||||||
}
|
}
|
||||||
ImmutableList<String> v6Addresses = v6AddressesBuilder.build();
|
ImmutableList<String> v6Addresses = v6AddressesBuilder.build();
|
||||||
if (!v6Addresses.isEmpty()) {
|
if (!v6Addresses.isEmpty()) {
|
||||||
ipAddressesBuilder.put("v6", v6Addresses);
|
ipAddressesBuilder.put("v6", Ordering.natural().immutableSortedCopy(v6Addresses));
|
||||||
}
|
}
|
||||||
ImmutableMap<String, ImmutableList<String>> ipAddresses = ipAddressesBuilder.build();
|
ImmutableMap<String, ImmutableList<String>> ipAddresses = ipAddressesBuilder.build();
|
||||||
if (!ipAddresses.isEmpty()) {
|
if (!ipAddresses.isEmpty()) {
|
||||||
|
|
|
@ -16,6 +16,7 @@ package google.registry.rdap;
|
||||||
|
|
||||||
import static google.registry.model.EppResourceUtils.loadByForeignKey;
|
import static google.registry.model.EppResourceUtils.loadByForeignKey;
|
||||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||||
|
import static google.registry.rdap.RdapIcannStandardInformation.TRUNCATION_NOTICES;
|
||||||
import static google.registry.request.Action.Method.GET;
|
import static google.registry.request.Action.Method.GET;
|
||||||
import static google.registry.request.Action.Method.HEAD;
|
import static google.registry.request.Action.Method.HEAD;
|
||||||
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
||||||
|
@ -24,6 +25,7 @@ import com.google.common.base.Optional;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSortedSet;
|
import com.google.common.collect.ImmutableSortedSet;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.primitives.Booleans;
|
import com.google.common.primitives.Booleans;
|
||||||
import google.registry.config.ConfigModule.Config;
|
import google.registry.config.ConfigModule.Config;
|
||||||
import google.registry.model.domain.DomainResource;
|
import google.registry.model.domain.DomainResource;
|
||||||
|
@ -85,7 +87,7 @@ public class RdapNameserverSearchAction extends RdapActionBase {
|
||||||
if (Booleans.countTrue(nameParam.isPresent(), ipParam.isPresent()) != 1) {
|
if (Booleans.countTrue(nameParam.isPresent(), ipParam.isPresent()) != 1) {
|
||||||
throw new BadRequestException("You must specify either name=XXXX or ip=YYYY");
|
throw new BadRequestException("You must specify either name=XXXX or ip=YYYY");
|
||||||
}
|
}
|
||||||
ImmutableList<ImmutableMap<String, Object>> results;
|
RdapSearchResults results;
|
||||||
if (nameParam.isPresent()) {
|
if (nameParam.isPresent()) {
|
||||||
// syntax: /rdap/nameservers?name=exam*.com
|
// syntax: /rdap/nameservers?name=exam*.com
|
||||||
if (!LDH_PATTERN.matcher(nameParam.get()).matches()) {
|
if (!LDH_PATTERN.matcher(nameParam.get()).matches()) {
|
||||||
|
@ -98,23 +100,24 @@ public class RdapNameserverSearchAction extends RdapActionBase {
|
||||||
// syntax: /rdap/nameservers?ip=1.2.3.4
|
// syntax: /rdap/nameservers?ip=1.2.3.4
|
||||||
results = searchByIp(ipParam.get(), now);
|
results = searchByIp(ipParam.get(), now);
|
||||||
}
|
}
|
||||||
if (results.isEmpty()) {
|
if (results.jsonList().isEmpty()) {
|
||||||
throw new NotFoundException("No nameservers found");
|
throw new NotFoundException("No nameservers found");
|
||||||
}
|
}
|
||||||
ImmutableMap.Builder<String, Object> jsonBuilder = new ImmutableMap.Builder<>();
|
ImmutableMap.Builder<String, Object> jsonBuilder = new ImmutableMap.Builder<>();
|
||||||
jsonBuilder.put("nameserverSearchResults", results);
|
jsonBuilder.put("nameserverSearchResults", results.jsonList());
|
||||||
RdapJsonFormatter.addTopLevelEntries(
|
RdapJsonFormatter.addTopLevelEntries(
|
||||||
jsonBuilder,
|
jsonBuilder,
|
||||||
BoilerplateType.NAMESERVER,
|
BoilerplateType.NAMESERVER,
|
||||||
ImmutableList.<ImmutableMap<String, Object>>of(),
|
results.isTruncated()
|
||||||
|
? TRUNCATION_NOTICES : ImmutableList.<ImmutableMap<String, Object>>of(),
|
||||||
ImmutableList.<ImmutableMap<String, Object>>of(),
|
ImmutableList.<ImmutableMap<String, Object>>of(),
|
||||||
rdapLinkBase);
|
rdapLinkBase);
|
||||||
return jsonBuilder.build();
|
return jsonBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Searches for nameservers by name, returning a JSON array of nameserver info maps. */
|
/** Searches for nameservers by name, returning a JSON array of nameserver info maps. */
|
||||||
private ImmutableList<ImmutableMap<String, Object>>
|
private RdapSearchResults searchByName(
|
||||||
searchByName(final RdapSearchPattern partialStringQuery, final DateTime now) {
|
final RdapSearchPattern partialStringQuery, final DateTime now) {
|
||||||
// Handle queries without a wildcard -- just load by foreign key.
|
// Handle queries without a wildcard -- just load by foreign key.
|
||||||
if (!partialStringQuery.getHasWildcard()) {
|
if (!partialStringQuery.getHasWildcard()) {
|
||||||
HostResource hostResource =
|
HostResource hostResource =
|
||||||
|
@ -122,18 +125,21 @@ public class RdapNameserverSearchAction extends RdapActionBase {
|
||||||
if (hostResource == null) {
|
if (hostResource == null) {
|
||||||
throw new NotFoundException("No nameservers found");
|
throw new NotFoundException("No nameservers found");
|
||||||
}
|
}
|
||||||
return ImmutableList.of(
|
return RdapSearchResults.create(
|
||||||
RdapJsonFormatter.makeRdapJsonForHost(
|
ImmutableList.of(
|
||||||
hostResource, false, rdapLinkBase, rdapWhoisServer, now, OutputDataType.FULL));
|
RdapJsonFormatter.makeRdapJsonForHost(
|
||||||
|
hostResource, false, rdapLinkBase, rdapWhoisServer, now, OutputDataType.FULL)),
|
||||||
|
false);
|
||||||
// Handle queries with a wildcard, but no suffix. There are no pending deletes for hosts, so we
|
// Handle queries with a wildcard, but no suffix. There are no pending deletes for hosts, so we
|
||||||
// can call queryUndeleted.
|
// can call queryUndeleted.
|
||||||
} else if (partialStringQuery.getSuffix() == null) {
|
} else if (partialStringQuery.getSuffix() == null) {
|
||||||
return makeSearchResults(
|
return makeSearchResults(
|
||||||
|
// Add 1 so we can detect truncation.
|
||||||
queryUndeleted(
|
queryUndeleted(
|
||||||
HostResource.class,
|
HostResource.class,
|
||||||
"fullyQualifiedHostName",
|
"fullyQualifiedHostName",
|
||||||
partialStringQuery,
|
partialStringQuery,
|
||||||
rdapResultSetMaxSize)
|
rdapResultSetMaxSize + 1)
|
||||||
.list(),
|
.list(),
|
||||||
now);
|
now);
|
||||||
// Handle queries with a wildcard and a suffix. In this case, it is more efficient to do things
|
// Handle queries with a wildcard and a suffix. In this case, it is more efficient to do things
|
||||||
|
@ -161,29 +167,30 @@ public class RdapNameserverSearchAction extends RdapActionBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Searches for nameservers by IP address, returning a JSON array of nameserver info maps. */
|
/** Searches for nameservers by IP address, returning a JSON array of nameserver info maps. */
|
||||||
private ImmutableList<ImmutableMap<String, Object>>
|
private RdapSearchResults searchByIp(final InetAddress inetAddress, DateTime now) {
|
||||||
searchByIp(final InetAddress inetAddress, DateTime now) {
|
|
||||||
return makeSearchResults(
|
return makeSearchResults(
|
||||||
|
// Add 1 so we can detect truncation.
|
||||||
ofy().load()
|
ofy().load()
|
||||||
.type(HostResource.class)
|
.type(HostResource.class)
|
||||||
.filter("inetAddresses", inetAddress.getHostAddress())
|
.filter("inetAddresses", inetAddress.getHostAddress())
|
||||||
.filter("deletionTime", END_OF_TIME)
|
.filter("deletionTime", END_OF_TIME)
|
||||||
.limit(rdapResultSetMaxSize)
|
.limit(rdapResultSetMaxSize + 1)
|
||||||
.list(),
|
.list(),
|
||||||
now);
|
now);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Output JSON for a list of hosts. */
|
/** Output JSON for a list of hosts. */
|
||||||
private ImmutableList<ImmutableMap<String, Object>> makeSearchResults(
|
private RdapSearchResults makeSearchResults(List<HostResource> hosts, DateTime now) {
|
||||||
List<HostResource> hosts, DateTime now) {
|
|
||||||
OutputDataType outputDataType =
|
OutputDataType outputDataType =
|
||||||
(hosts.size() > 1) ? OutputDataType.SUMMARY : OutputDataType.FULL;
|
(hosts.size() > 1) ? OutputDataType.SUMMARY : OutputDataType.FULL;
|
||||||
ImmutableList.Builder<ImmutableMap<String, Object>> jsonBuilder = new ImmutableList.Builder<>();
|
ImmutableList.Builder<ImmutableMap<String, Object>> jsonListBuilder =
|
||||||
for (HostResource host : hosts) {
|
new ImmutableList.Builder<>();
|
||||||
jsonBuilder.add(
|
for (HostResource host : Iterables.limit(hosts, rdapResultSetMaxSize)) {
|
||||||
|
jsonListBuilder.add(
|
||||||
RdapJsonFormatter.makeRdapJsonForHost(
|
RdapJsonFormatter.makeRdapJsonForHost(
|
||||||
host, false, rdapLinkBase, rdapWhoisServer, now, outputDataType));
|
host, false, rdapLinkBase, rdapWhoisServer, now, outputDataType));
|
||||||
}
|
}
|
||||||
return jsonBuilder.build();
|
ImmutableList<ImmutableMap<String, Object>> jsonList = jsonListBuilder.build();
|
||||||
|
return RdapSearchResults.create(jsonList, jsonList.size() < hosts.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,10 +17,12 @@ package google.registry.rdap;
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static google.registry.testing.DatastoreHelper.createTld;
|
import static google.registry.testing.DatastoreHelper.createTld;
|
||||||
import static google.registry.testing.DatastoreHelper.persistResource;
|
import static google.registry.testing.DatastoreHelper.persistResource;
|
||||||
|
import static google.registry.testing.DatastoreHelper.persistResources;
|
||||||
import static google.registry.testing.DatastoreHelper.persistSimpleResources;
|
import static google.registry.testing.DatastoreHelper.persistSimpleResources;
|
||||||
import static google.registry.testing.FullFieldsTestEntityHelper.makeAndPersistHostResource;
|
import static google.registry.testing.FullFieldsTestEntityHelper.makeAndPersistHostResource;
|
||||||
import static google.registry.testing.FullFieldsTestEntityHelper.makeContactResource;
|
import static google.registry.testing.FullFieldsTestEntityHelper.makeContactResource;
|
||||||
import static google.registry.testing.FullFieldsTestEntityHelper.makeDomainResource;
|
import static google.registry.testing.FullFieldsTestEntityHelper.makeDomainResource;
|
||||||
|
import static google.registry.testing.FullFieldsTestEntityHelper.makeHostResource;
|
||||||
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrar;
|
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrar;
|
||||||
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrarContacts;
|
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrarContacts;
|
||||||
import static google.registry.testing.TestDataHelper.loadFileWithSubstitutions;
|
import static google.registry.testing.TestDataHelper.loadFileWithSubstitutions;
|
||||||
|
@ -39,6 +41,7 @@ import google.registry.testing.AppEngineRule;
|
||||||
import google.registry.testing.FakeClock;
|
import google.registry.testing.FakeClock;
|
||||||
import google.registry.testing.FakeResponse;
|
import google.registry.testing.FakeResponse;
|
||||||
import google.registry.testing.InjectRule;
|
import google.registry.testing.InjectRule;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.json.simple.JSONValue;
|
import org.json.simple.JSONValue;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
@ -60,6 +63,7 @@ public class RdapNameserverSearchActionTest {
|
||||||
|
|
||||||
private final RdapNameserverSearchAction action = new RdapNameserverSearchAction();
|
private final RdapNameserverSearchAction action = new RdapNameserverSearchAction();
|
||||||
|
|
||||||
|
private DomainResource domainCatLol;
|
||||||
private HostResource hostNs1CatLol;
|
private HostResource hostNs1CatLol;
|
||||||
private HostResource hostNs2CatLol;
|
private HostResource hostNs2CatLol;
|
||||||
private HostResource hostNs1Cat2Lol;
|
private HostResource hostNs1Cat2Lol;
|
||||||
|
@ -105,21 +109,20 @@ public class RdapNameserverSearchActionTest {
|
||||||
makeAndPersistHostResource("ns1.cat.1.test", "1.2.3.6", clock.nowUtc().minusYears(1));
|
makeAndPersistHostResource("ns1.cat.1.test", "1.2.3.6", clock.nowUtc().minusYears(1));
|
||||||
|
|
||||||
// create a domain so that we can use it as a test nameserver search string suffix
|
// create a domain so that we can use it as a test nameserver search string suffix
|
||||||
DomainResource domainCatLol =
|
domainCatLol = persistResource(
|
||||||
persistResource(
|
makeDomainResource(
|
||||||
makeDomainResource(
|
"cat.lol",
|
||||||
"cat.lol",
|
persistResource(
|
||||||
persistResource(
|
makeContactResource("5372808-ERL", "Goblin Market", "lol@cat.lol")),
|
||||||
makeContactResource("5372808-ERL", "Goblin Market", "lol@cat.lol")),
|
persistResource(
|
||||||
persistResource(
|
makeContactResource("5372808-IRL", "Santa Claus", "BOFH@cat.lol")),
|
||||||
makeContactResource("5372808-IRL", "Santa Claus", "BOFH@cat.lol")),
|
persistResource(makeContactResource("5372808-TRL", "The Raven", "bog@cat.lol")),
|
||||||
persistResource(makeContactResource("5372808-TRL", "The Raven", "bog@cat.lol")),
|
hostNs1CatLol,
|
||||||
hostNs1CatLol,
|
hostNs2CatLol,
|
||||||
hostNs2CatLol,
|
registrar)
|
||||||
registrar)
|
.asBuilder()
|
||||||
.asBuilder()
|
.setSubordinateHosts(ImmutableSet.of("ns1.cat.lol", "ns2.cat.lol"))
|
||||||
.setSubordinateHosts(ImmutableSet.of("ns1.cat.lol", "ns2.cat.lol"))
|
.build());
|
||||||
.build());
|
|
||||||
persistResource(
|
persistResource(
|
||||||
hostNs1CatLol.asBuilder().setSuperordinateDomain(Key.create(domainCatLol)).build());
|
hostNs1CatLol.asBuilder().setSuperordinateDomain(Key.create(domainCatLol)).build());
|
||||||
persistResource(
|
persistResource(
|
||||||
|
@ -129,27 +132,35 @@ public class RdapNameserverSearchActionTest {
|
||||||
action.clock = clock;
|
action.clock = clock;
|
||||||
action.requestPath = RdapNameserverSearchAction.PATH;
|
action.requestPath = RdapNameserverSearchAction.PATH;
|
||||||
action.response = response;
|
action.response = response;
|
||||||
action.rdapResultSetMaxSize = 100;
|
action.rdapResultSetMaxSize = 4;
|
||||||
action.rdapLinkBase = "https://example.tld/rdap/";
|
action.rdapLinkBase = "https://example.tld/rdap/";
|
||||||
action.rdapWhoisServer = null;
|
action.rdapWhoisServer = null;
|
||||||
action.ipParam = Optional.absent();
|
action.ipParam = Optional.absent();
|
||||||
action.nameParam = Optional.absent();
|
action.nameParam = Optional.absent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Object generateExpectedJson(String expectedOutputFile) {
|
||||||
|
return generateExpectedJson(null, null, null, null, null, expectedOutputFile);
|
||||||
|
}
|
||||||
|
|
||||||
private Object generateExpectedJson(String name, String expectedOutputFile) {
|
private Object generateExpectedJson(String name, String expectedOutputFile) {
|
||||||
return generateExpectedJson(name, null, null, null, null, expectedOutputFile);
|
return generateExpectedJson(name, null, null, null, null, expectedOutputFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object generateExpectedJson(
|
private Object generateExpectedJson(
|
||||||
String name,
|
@Nullable String name,
|
||||||
String punycodeName,
|
@Nullable String punycodeName,
|
||||||
String handle,
|
@Nullable String handle,
|
||||||
String ipAddressType,
|
@Nullable String ipAddressType,
|
||||||
String ipAddress,
|
@Nullable String ipAddress,
|
||||||
String expectedOutputFile) {
|
String expectedOutputFile) {
|
||||||
ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<>();
|
ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<>();
|
||||||
builder.put("NAME", name);
|
if (name != null) {
|
||||||
builder.put("PUNYCODENAME", (punycodeName == null) ? name : punycodeName);
|
builder.put("NAME", name);
|
||||||
|
}
|
||||||
|
if ((name != null) || (punycodeName != null)) {
|
||||||
|
builder.put("PUNYCODENAME", (punycodeName == null) ? name : punycodeName);
|
||||||
|
}
|
||||||
if (handle != null) {
|
if (handle != null) {
|
||||||
builder.put("HANDLE", handle);
|
builder.put("HANDLE", handle);
|
||||||
}
|
}
|
||||||
|
@ -182,6 +193,21 @@ public class RdapNameserverSearchActionTest {
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void createManyHosts(int numHosts) {
|
||||||
|
ImmutableList.Builder<HostResource> hostsBuilder = new ImmutableList.Builder<>();
|
||||||
|
ImmutableSet.Builder<String> subordinateHostsBuilder = new ImmutableSet.Builder<>();
|
||||||
|
for (int i = 1; i <= numHosts; i++) {
|
||||||
|
String hostName = String.format("ns%d.cat.lol", i);
|
||||||
|
subordinateHostsBuilder.add(hostName);
|
||||||
|
hostsBuilder.add(makeHostResource(hostName, "5.5.5.1", "5.5.5.2"));
|
||||||
|
}
|
||||||
|
persistResources(hostsBuilder.build());
|
||||||
|
domainCatLol = persistResource(
|
||||||
|
domainCatLol.asBuilder()
|
||||||
|
.setSubordinateHosts(subordinateHostsBuilder.build())
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInvalidPath_rejected() throws Exception {
|
public void testInvalidPath_rejected() throws Exception {
|
||||||
action.requestPath = RdapDomainSearchAction.PATH + "/path";
|
action.requestPath = RdapDomainSearchAction.PATH + "/path";
|
||||||
|
@ -328,6 +354,46 @@ public class RdapNameserverSearchActionTest {
|
||||||
generateActualJsonWithName("dog*");
|
generateActualJsonWithName("dog*");
|
||||||
assertThat(response.getStatus()).isEqualTo(404);
|
assertThat(response.getStatus()).isEqualTo(404);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNameMatch_nontruncatedResultSet() throws Exception {
|
||||||
|
createManyHosts(4);
|
||||||
|
assertThat(generateActualJsonWithName("ns*.cat.lol"))
|
||||||
|
.isEqualTo(generateExpectedJson("rdap_nontruncated_hosts.json"));
|
||||||
|
assertThat(response.getStatus()).isEqualTo(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNameMatch_truncatedResultSet() throws Exception {
|
||||||
|
createManyHosts(5);
|
||||||
|
assertThat(generateActualJsonWithName("ns*.cat.lol"))
|
||||||
|
.isEqualTo(generateExpectedJson("rdap_truncated_hosts.json"));
|
||||||
|
assertThat(response.getStatus()).isEqualTo(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNameMatch_reallyTruncatedResultSet() throws Exception {
|
||||||
|
createManyHosts(9);
|
||||||
|
assertThat(generateActualJsonWithName("ns*.cat.lol"))
|
||||||
|
.isEqualTo(generateExpectedJson("rdap_truncated_hosts.json"));
|
||||||
|
assertThat(response.getStatus()).isEqualTo(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNameMatchDeletedHost_foundTheOtherHost() throws Exception {
|
||||||
|
persistResource(
|
||||||
|
hostNs1Cat2Lol.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build());
|
||||||
|
assertThat(generateActualJsonWithIp("bad:f00d:cafe::15:beef"))
|
||||||
|
.isEqualTo(
|
||||||
|
generateExpectedJsonForNameserver(
|
||||||
|
"ns2.cat.lol",
|
||||||
|
null,
|
||||||
|
"4-ROID",
|
||||||
|
"v6",
|
||||||
|
"bad:f00d:cafe::15:beef",
|
||||||
|
"rdap_host.json"));
|
||||||
|
assertThat(response.getStatus()).isEqualTo(200);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAddressMatchV4Address_found() throws Exception {
|
public void testAddressMatchV4Address_found() throws Exception {
|
||||||
|
@ -341,7 +407,7 @@ public class RdapNameserverSearchActionTest {
|
||||||
@Test
|
@Test
|
||||||
public void testAddressMatchV6Address_foundMultiple() throws Exception {
|
public void testAddressMatchV6Address_foundMultiple() throws Exception {
|
||||||
assertThat(generateActualJsonWithIp("bad:f00d:cafe::15:beef"))
|
assertThat(generateActualJsonWithIp("bad:f00d:cafe::15:beef"))
|
||||||
.isEqualTo(generateExpectedJson("ns1.cat.external", "rdap_multiple_hosts.json"));
|
.isEqualTo(generateExpectedJson("rdap_multiple_hosts.json"));
|
||||||
assertThat(response.getStatus()).isEqualTo(200);
|
assertThat(response.getStatus()).isEqualTo(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,18 +442,26 @@ public class RdapNameserverSearchActionTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNameMatchDeletedHost_foundTheOtherHost() throws Exception {
|
public void testAddressMatch_nontruncatedResultSet() throws Exception {
|
||||||
persistResource(
|
createManyHosts(4);
|
||||||
hostNs1Cat2Lol.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build());
|
assertThat(generateActualJsonWithIp("5.5.5.1"))
|
||||||
assertThat(generateActualJsonWithIp("bad:f00d:cafe::15:beef"))
|
.isEqualTo(generateExpectedJson("rdap_nontruncated_hosts.json"));
|
||||||
.isEqualTo(
|
assertThat(response.getStatus()).isEqualTo(200);
|
||||||
generateExpectedJsonForNameserver(
|
}
|
||||||
"ns2.cat.lol",
|
|
||||||
null,
|
@Test
|
||||||
"4-ROID",
|
public void testAddressMatch_truncatedResultSet() throws Exception {
|
||||||
"v6",
|
createManyHosts(5);
|
||||||
"bad:f00d:cafe::15:beef",
|
assertThat(generateActualJsonWithIp("5.5.5.1"))
|
||||||
"rdap_host.json"));
|
.isEqualTo(generateExpectedJson("rdap_truncated_hosts.json"));
|
||||||
|
assertThat(response.getStatus()).isEqualTo(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddressMatch_reallyTruncatedResultSet() throws Exception {
|
||||||
|
createManyHosts(9);
|
||||||
|
assertThat(generateActualJsonWithIp("5.5.5.1"))
|
||||||
|
.isEqualTo(generateExpectedJson("rdap_truncated_hosts.json"));
|
||||||
assertThat(response.getStatus()).isEqualTo(200);
|
assertThat(response.getStatus()).isEqualTo(200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
155
javatests/google/registry/rdap/testdata/rdap_nontruncated_hosts.json
vendored
Normal file
155
javatests/google/registry/rdap/testdata/rdap_nontruncated_hosts.json
vendored
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
{
|
||||||
|
"nameserverSearchResults" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"objectClassName" : "nameserver",
|
||||||
|
"handle" : "14-ROID",
|
||||||
|
"status" : ["active"],
|
||||||
|
"ldhName" : "ns1.cat.lol",
|
||||||
|
"links" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"value" : "https://example.tld/rdap/nameserver/ns1.cat.lol",
|
||||||
|
"rel" : "self",
|
||||||
|
"type" : "application/rdap+json",
|
||||||
|
"href" : "https://example.tld/rdap/nameserver/ns1.cat.lol"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ipAddresses" :
|
||||||
|
{
|
||||||
|
"v4" : ["5.5.5.1", "5.5.5.2"]
|
||||||
|
},
|
||||||
|
"remarks": [
|
||||||
|
{
|
||||||
|
"title": "Incomplete Data",
|
||||||
|
"description": [
|
||||||
|
"Summary data only. For complete data, send a specific query for the object."
|
||||||
|
],
|
||||||
|
"type": "object truncated due to unexplainable reasons"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"objectClassName" : "nameserver",
|
||||||
|
"handle" : "15-ROID",
|
||||||
|
"status" : ["active"],
|
||||||
|
"ldhName" : "ns2.cat.lol",
|
||||||
|
"links" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"value" : "https://example.tld/rdap/nameserver/ns2.cat.lol",
|
||||||
|
"rel" : "self",
|
||||||
|
"type" : "application/rdap+json",
|
||||||
|
"href" : "https://example.tld/rdap/nameserver/ns2.cat.lol"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ipAddresses" :
|
||||||
|
{
|
||||||
|
"v4" : ["5.5.5.1", "5.5.5.2"]
|
||||||
|
},
|
||||||
|
"remarks": [
|
||||||
|
{
|
||||||
|
"title": "Incomplete Data",
|
||||||
|
"description": [
|
||||||
|
"Summary data only. For complete data, send a specific query for the object."
|
||||||
|
],
|
||||||
|
"type": "object truncated due to unexplainable reasons"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"objectClassName" : "nameserver",
|
||||||
|
"handle" : "16-ROID",
|
||||||
|
"status" : ["active"],
|
||||||
|
"ldhName" : "ns3.cat.lol",
|
||||||
|
"links" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"value" : "https://example.tld/rdap/nameserver/ns3.cat.lol",
|
||||||
|
"rel" : "self",
|
||||||
|
"type" : "application/rdap+json",
|
||||||
|
"href" : "https://example.tld/rdap/nameserver/ns3.cat.lol"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ipAddresses" :
|
||||||
|
{
|
||||||
|
"v4" : ["5.5.5.1", "5.5.5.2"]
|
||||||
|
},
|
||||||
|
"remarks": [
|
||||||
|
{
|
||||||
|
"title": "Incomplete Data",
|
||||||
|
"description": [
|
||||||
|
"Summary data only. For complete data, send a specific query for the object."
|
||||||
|
],
|
||||||
|
"type": "object truncated due to unexplainable reasons"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"objectClassName" : "nameserver",
|
||||||
|
"handle" : "17-ROID",
|
||||||
|
"status" : ["active"],
|
||||||
|
"ldhName" : "ns4.cat.lol",
|
||||||
|
"links" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"value" : "https://example.tld/rdap/nameserver/ns4.cat.lol",
|
||||||
|
"rel" : "self",
|
||||||
|
"type" : "application/rdap+json",
|
||||||
|
"href" : "https://example.tld/rdap/nameserver/ns4.cat.lol"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ipAddresses" :
|
||||||
|
{
|
||||||
|
"v4" : ["5.5.5.1", "5.5.5.2"]
|
||||||
|
},
|
||||||
|
"remarks": [
|
||||||
|
{
|
||||||
|
"title": "Incomplete Data",
|
||||||
|
"description": [
|
||||||
|
"Summary data only. For complete data, send a specific query for the object."
|
||||||
|
],
|
||||||
|
"type": "object truncated due to unexplainable reasons"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rdapConformance" : ["rdap_level_0"],
|
||||||
|
"notices" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"title" : "RDAP Terms of Service",
|
||||||
|
"description" :
|
||||||
|
[
|
||||||
|
"By querying our Domain Database, you are agreeing to comply with these terms so please read them carefully.",
|
||||||
|
"Any information provided is 'as is' without any guarantee of accuracy.",
|
||||||
|
"Please do not misuse the Domain Database. It is intended solely for query-based access.",
|
||||||
|
"Don't use the Domain Database to allow, enable, or otherwise support the transmission of mass unsolicited, commercial advertising or solicitations.",
|
||||||
|
"Don't access our Domain Database through the use of high volume, automated electronic processes that send queries or data to the systems of Charleston Road Registry or any ICANN-accredited registrar.",
|
||||||
|
"You may only use the information contained in the Domain Database for lawful purposes.",
|
||||||
|
"Do not compile, repackage, disseminate, or otherwise use the information contained in the Domain Database in its entirety, or in any substantial portion, without our prior written permission.",
|
||||||
|
"We may retain certain details about queries to our Domain Database for the purposes of detecting and preventing misuse.",
|
||||||
|
"We reserve the right to restrict or deny your access to the database if we suspect that you have failed to comply with these terms.",
|
||||||
|
"We reserve the right to modify this agreement at any time."
|
||||||
|
],
|
||||||
|
"links" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"value" : "https://example.tld/rdap/help/tos",
|
||||||
|
"rel" : "alternate",
|
||||||
|
"href" : "https://www.registry.google/about/rdap/tos.html",
|
||||||
|
"type" : "text/html"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"remarks" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"description" :
|
||||||
|
[
|
||||||
|
"This response conforms to the RDAP Operational Profile for gTLD Registries and Registrars version 1.0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
163
javatests/google/registry/rdap/testdata/rdap_truncated_hosts.json
vendored
Normal file
163
javatests/google/registry/rdap/testdata/rdap_truncated_hosts.json
vendored
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
{
|
||||||
|
"nameserverSearchResults" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"objectClassName" : "nameserver",
|
||||||
|
"handle" : "14-ROID",
|
||||||
|
"status" : ["active"],
|
||||||
|
"ldhName" : "ns1.cat.lol",
|
||||||
|
"links" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"value" : "https://example.tld/rdap/nameserver/ns1.cat.lol",
|
||||||
|
"rel" : "self",
|
||||||
|
"type" : "application/rdap+json",
|
||||||
|
"href" : "https://example.tld/rdap/nameserver/ns1.cat.lol"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ipAddresses" :
|
||||||
|
{
|
||||||
|
"v4" : ["5.5.5.1", "5.5.5.2"]
|
||||||
|
},
|
||||||
|
"remarks": [
|
||||||
|
{
|
||||||
|
"title": "Incomplete Data",
|
||||||
|
"description": [
|
||||||
|
"Summary data only. For complete data, send a specific query for the object."
|
||||||
|
],
|
||||||
|
"type": "object truncated due to unexplainable reasons"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"objectClassName" : "nameserver",
|
||||||
|
"handle" : "15-ROID",
|
||||||
|
"status" : ["active"],
|
||||||
|
"ldhName" : "ns2.cat.lol",
|
||||||
|
"links" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"value" : "https://example.tld/rdap/nameserver/ns2.cat.lol",
|
||||||
|
"rel" : "self",
|
||||||
|
"type" : "application/rdap+json",
|
||||||
|
"href" : "https://example.tld/rdap/nameserver/ns2.cat.lol"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ipAddresses" :
|
||||||
|
{
|
||||||
|
"v4" : ["5.5.5.1", "5.5.5.2"]
|
||||||
|
},
|
||||||
|
"remarks": [
|
||||||
|
{
|
||||||
|
"title": "Incomplete Data",
|
||||||
|
"description": [
|
||||||
|
"Summary data only. For complete data, send a specific query for the object."
|
||||||
|
],
|
||||||
|
"type": "object truncated due to unexplainable reasons"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"objectClassName" : "nameserver",
|
||||||
|
"handle" : "16-ROID",
|
||||||
|
"status" : ["active"],
|
||||||
|
"ldhName" : "ns3.cat.lol",
|
||||||
|
"links" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"value" : "https://example.tld/rdap/nameserver/ns3.cat.lol",
|
||||||
|
"rel" : "self",
|
||||||
|
"type" : "application/rdap+json",
|
||||||
|
"href" : "https://example.tld/rdap/nameserver/ns3.cat.lol"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ipAddresses" :
|
||||||
|
{
|
||||||
|
"v4" : ["5.5.5.1", "5.5.5.2"]
|
||||||
|
},
|
||||||
|
"remarks": [
|
||||||
|
{
|
||||||
|
"title": "Incomplete Data",
|
||||||
|
"description": [
|
||||||
|
"Summary data only. For complete data, send a specific query for the object."
|
||||||
|
],
|
||||||
|
"type": "object truncated due to unexplainable reasons"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"objectClassName" : "nameserver",
|
||||||
|
"handle" : "17-ROID",
|
||||||
|
"status" : ["active"],
|
||||||
|
"ldhName" : "ns4.cat.lol",
|
||||||
|
"links" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"value" : "https://example.tld/rdap/nameserver/ns4.cat.lol",
|
||||||
|
"rel" : "self",
|
||||||
|
"type" : "application/rdap+json",
|
||||||
|
"href" : "https://example.tld/rdap/nameserver/ns4.cat.lol"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ipAddresses" :
|
||||||
|
{
|
||||||
|
"v4" : ["5.5.5.1", "5.5.5.2"]
|
||||||
|
},
|
||||||
|
"remarks": [
|
||||||
|
{
|
||||||
|
"title": "Incomplete Data",
|
||||||
|
"description": [
|
||||||
|
"Summary data only. For complete data, send a specific query for the object."
|
||||||
|
],
|
||||||
|
"type": "object truncated due to unexplainable reasons"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rdapConformance" : ["rdap_level_0"],
|
||||||
|
"notices" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"title" : "Search Policy",
|
||||||
|
"type" : "result set truncated due to unexplainable reasons",
|
||||||
|
"description" :
|
||||||
|
[
|
||||||
|
"Search results per query are limited."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title" : "RDAP Terms of Service",
|
||||||
|
"description" :
|
||||||
|
[
|
||||||
|
"By querying our Domain Database, you are agreeing to comply with these terms so please read them carefully.",
|
||||||
|
"Any information provided is 'as is' without any guarantee of accuracy.",
|
||||||
|
"Please do not misuse the Domain Database. It is intended solely for query-based access.",
|
||||||
|
"Don't use the Domain Database to allow, enable, or otherwise support the transmission of mass unsolicited, commercial advertising or solicitations.",
|
||||||
|
"Don't access our Domain Database through the use of high volume, automated electronic processes that send queries or data to the systems of Charleston Road Registry or any ICANN-accredited registrar.",
|
||||||
|
"You may only use the information contained in the Domain Database for lawful purposes.",
|
||||||
|
"Do not compile, repackage, disseminate, or otherwise use the information contained in the Domain Database in its entirety, or in any substantial portion, without our prior written permission.",
|
||||||
|
"We may retain certain details about queries to our Domain Database for the purposes of detecting and preventing misuse.",
|
||||||
|
"We reserve the right to restrict or deny your access to the database if we suspect that you have failed to comply with these terms.",
|
||||||
|
"We reserve the right to modify this agreement at any time."
|
||||||
|
],
|
||||||
|
"links" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"value" : "https://example.tld/rdap/help/tos",
|
||||||
|
"rel" : "alternate",
|
||||||
|
"href" : "https://www.registry.google/about/rdap/tos.html",
|
||||||
|
"type" : "text/html"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"remarks" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"description" :
|
||||||
|
[
|
||||||
|
"This response conforms to the RDAP Operational Profile for gTLD Registries and Registrars version 1.0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue