mirror of
https://github.com/google/nomulus.git
synced 2025-05-12 22:38:16 +02:00
mv com/google/domain/registry google/registry
This change renames directories in preparation for the great package rename. The repository is now in a broken state because the code itself hasn't been updated. However this should ensure that git correctly preserves history for each file.
This commit is contained in:
parent
a41677aea1
commit
5012893c1d
2396 changed files with 0 additions and 0 deletions
191
java/google/registry/rdap/RdapActionBase.java
Normal file
191
java/google/registry/rdap/RdapActionBase.java
Normal file
|
@ -0,0 +1,191 @@
|
|||
// Copyright 2016 The Domain Registry Authors. All Rights Reserved.
|
||||
//
|
||||
// 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.google.domain.registry.rdap;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.net.HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN;
|
||||
import static com.google.domain.registry.model.ofy.ObjectifyService.ofy;
|
||||
import static com.google.domain.registry.model.registry.Registries.findTldForName;
|
||||
import static com.google.domain.registry.model.registry.Registries.getTlds;
|
||||
import static com.google.domain.registry.util.DateTimeUtils.END_OF_TIME;
|
||||
import static com.google.domain.registry.util.DomainNameUtils.canonicalizeDomainName;
|
||||
import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
|
||||
import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
|
||||
import static javax.servlet.http.HttpServletResponse.SC_OK;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.net.InternetDomainName;
|
||||
import com.google.common.net.MediaType;
|
||||
import com.google.domain.registry.config.ConfigModule.Config;
|
||||
import com.google.domain.registry.model.EppResource;
|
||||
import com.google.domain.registry.request.Action;
|
||||
import com.google.domain.registry.request.HttpException;
|
||||
import com.google.domain.registry.request.HttpException.BadRequestException;
|
||||
import com.google.domain.registry.request.HttpException.NotFoundException;
|
||||
import com.google.domain.registry.request.RequestMethod;
|
||||
import com.google.domain.registry.request.RequestPath;
|
||||
import com.google.domain.registry.request.Response;
|
||||
import com.google.domain.registry.util.FormattingLogger;
|
||||
|
||||
import com.googlecode.objectify.cmd.Query;
|
||||
|
||||
import org.json.simple.JSONValue;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Base RDAP (new WHOIS) action for single-item domain, nameserver and entity requests.
|
||||
*
|
||||
* @see <a href="https://tools.ietf.org/html/rfc7482">
|
||||
* RFC 7482: Registration Data Access Protocol (RDAP) Query Format</a>
|
||||
*/
|
||||
public abstract class RdapActionBase implements Runnable {
|
||||
|
||||
private static final FormattingLogger logger = FormattingLogger.getLoggerForCallerClass();
|
||||
|
||||
/**
|
||||
* Pattern for checking LDH names, which must officially contains only alphanumeric plus dots and
|
||||
* hyphens. In this case, allow the wildcard asterisk as well.
|
||||
*/
|
||||
static final Pattern LDH_PATTERN = Pattern.compile("[-.a-zA-Z0-9*]+");
|
||||
|
||||
private static final MediaType RESPONSE_MEDIA_TYPE = MediaType.create("application", "rdap+json");
|
||||
|
||||
@Inject Response response;
|
||||
@Inject @RequestMethod Action.Method requestMethod;
|
||||
@Inject @RequestPath String requestPath;
|
||||
@Inject @Config("rdapLinkBase") String rdapLinkBase;
|
||||
@Inject @Config("rdapWhoisServer") String rdapWhoisServer;
|
||||
|
||||
/** Returns a string like "domain name" or "nameserver", used for error strings. */
|
||||
abstract String getHumanReadableObjectTypeName();
|
||||
|
||||
/** Returns the servlet action path; used to extract the search string from the incoming path. */
|
||||
abstract String getActionPath();
|
||||
|
||||
/**
|
||||
* Does the actual search and returns an RDAP JSON object.
|
||||
*
|
||||
* @param pathSearchString the search string in the URL path
|
||||
* @param isHeadRequest whether the returned map will actually be used. HTTP HEAD requests don't
|
||||
* actually return anything. However, we usually still want to go through the process of
|
||||
* building a map, to make sure that the request would return a 500 status if it were
|
||||
* invoked using GET. So this field should usually be ignored, unless there's some
|
||||
* expensive task required to create the map which will never result in a request failure.
|
||||
* @param linkBase the base URL for RDAP link structures
|
||||
* @return A map (probably containing nested maps and lists) with the final JSON response data.
|
||||
*/
|
||||
abstract ImmutableMap<String, Object> getJsonObjectForResource(
|
||||
String pathSearchString, boolean isHeadRequest, String linkBase) throws HttpException;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
// Extract what we're searching for from the request path. Some RDAP commands use trailing
|
||||
// data in the path itself (e.g. /rdap/domain/mydomain.com), and some use the query string
|
||||
// (e.g. /rdap/domains?name=mydomain); the query parameters are extracted by the subclasses
|
||||
// directly as needed.
|
||||
response.setHeader(ACCESS_CONTROL_ALLOW_ORIGIN, "*");
|
||||
URI uri = new URI(requestPath);
|
||||
String pathProper = uri.getPath();
|
||||
checkArgument(
|
||||
pathProper.startsWith(getActionPath()),
|
||||
"%s doesn't start with %s", pathProper, getActionPath());
|
||||
ImmutableMap<String, Object> rdapJson =
|
||||
getJsonObjectForResource(
|
||||
pathProper.substring(getActionPath().length()),
|
||||
requestMethod == Action.Method.HEAD,
|
||||
rdapLinkBase);
|
||||
response.setStatus(SC_OK);
|
||||
if (requestMethod != Action.Method.HEAD) {
|
||||
response.setPayload(JSONValue.toJSONString(rdapJson));
|
||||
}
|
||||
response.setContentType(MediaType.create("application", "rdap+json"));
|
||||
} catch (HttpException e) {
|
||||
setError(e.getResponseCode(), e.getResponseCodeString(), e.getMessage());
|
||||
} catch (URISyntaxException | IllegalArgumentException e) {
|
||||
setError(SC_BAD_REQUEST, "Bad Request", "Not a valid " + getHumanReadableObjectTypeName());
|
||||
} catch (RuntimeException e) {
|
||||
setError(SC_INTERNAL_SERVER_ERROR, "Internal Server Error", "An error was encountered");
|
||||
logger.severe(e, "Exception encountered while processing RDAP command");
|
||||
}
|
||||
}
|
||||
|
||||
void setError(int status, String title, String description) {
|
||||
response.setStatus(status);
|
||||
try {
|
||||
if (requestMethod != Action.Method.HEAD) {
|
||||
response.setPayload(
|
||||
JSONValue.toJSONString(RdapJsonFormatter.makeError(status, title, description)));
|
||||
}
|
||||
response.setContentType(RESPONSE_MEDIA_TYPE);
|
||||
} catch (Exception ex) {
|
||||
if (requestMethod != Action.Method.HEAD) {
|
||||
response.setPayload("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void validateDomainName(String name) {
|
||||
try {
|
||||
Optional<InternetDomainName> tld = findTldForName(InternetDomainName.from(name));
|
||||
if (!tld.isPresent() || !getTlds().contains(tld.get().toString())) {
|
||||
throw new NotFoundException(name + " not found");
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new BadRequestException(
|
||||
name + " is not a valid " + getHumanReadableObjectTypeName());
|
||||
}
|
||||
}
|
||||
|
||||
String canonicalizeName(String name) {
|
||||
name = canonicalizeDomainName(name);
|
||||
if (name.endsWith(".")) {
|
||||
name = name.substring(0, name.length() - 1);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles prefix searches in cases where there are no pending deletes. In such cases, it is
|
||||
* sufficient to check whether {@code deletionTime} is equal to {@code END_OF_TIME}, because any
|
||||
* other value means it has already been deleted. This allows us to use an equality query for the
|
||||
* deletion time.
|
||||
*
|
||||
* @param clazz the type of resource to be queried
|
||||
* @param filterField the database field of interest
|
||||
* @param partialStringQuery the details of the search string
|
||||
* @param resultSetMaxSize the maximum number of results to return
|
||||
* @return the results of the query
|
||||
*/
|
||||
static <T extends EppResource> Query<T> queryUndeleted(
|
||||
Class<T> clazz,
|
||||
String filterField,
|
||||
RdapSearchPattern partialStringQuery,
|
||||
int resultSetMaxSize) {
|
||||
checkArgument(partialStringQuery.getHasWildcard(), "search string doesn't have wildcard");
|
||||
return ofy().load()
|
||||
.type(clazz)
|
||||
.filter(filterField + " >=", partialStringQuery.getInitialString())
|
||||
.filter(filterField + " <", partialStringQuery.getNextInitialString())
|
||||
.filter("deletionTime", END_OF_TIME)
|
||||
.limit(resultSetMaxSize);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue