use of org.apache.knox.gateway.util.urltemplate.Matcher in project knox by apache.
the class UrlRewriteProcessor method rewrite.
@Override
public Template rewrite(Resolver resolver, Template inputUri, Direction direction, String ruleName) {
Template outputUri = inputUri;
String serviceRole = null;
if (resolver != null) {
List<String> serviceRoles = resolver.resolve("service.role");
if (serviceRoles != null && !serviceRoles.isEmpty()) {
serviceRole = serviceRoles.get(0);
}
}
UrlRewriteStepProcessorHolder stepHolder = null;
String effectiveRuleName = null;
if (ruleName == null || "*".equals(ruleName)) {
// Used for logging later.
ruleName = null;
Matcher<UrlRewriteRuleProcessorHolder>.Match match = null;
switch(direction) {
case IN:
match = inbound.match(outputUri, serviceRole);
break;
case OUT:
match = outbound.match(outputUri, serviceRole);
break;
}
if (match != null) {
stepHolder = match.getValue();
effectiveRuleName = match.getValue().getRuleName();
}
} else if (!ruleName.isEmpty()) {
stepHolder = rules.get(ruleName);
effectiveRuleName = ruleName;
}
if (stepHolder != null) {
UrlRewriteContext context = new UrlRewriteContextImpl(environment, resolver, functions, direction, inputUri);
try {
UrlRewriteStepStatus stepStatus = stepHolder.process(context);
if (UrlRewriteStepStatus.SUCCESS == stepStatus) {
outputUri = context.getCurrentUrl();
if (ruleName == null) {
LOG.rewroteUrlViaImplicitRule(inputUri, direction, effectiveRuleName, outputUri);
} else {
LOG.rewroteUrlViaExplicitRule(inputUri, direction, effectiveRuleName, outputUri);
}
} else {
LOG.failedToRewriteUrl(inputUri, direction, effectiveRuleName, stepStatus);
outputUri = null;
}
} catch (Exception e) {
LOG.failedToRewriteUrlDueToException(inputUri, direction, effectiveRuleName, e);
outputUri = null;
}
} else {
LOG.noRuleMatchingUrl(inputUri, direction);
}
return outputUri;
}
use of org.apache.knox.gateway.util.urltemplate.Matcher in project knox by apache.
the class UrlRewriteProcessorTest method testSolrRewriteDefaultPort.
@Test
public void testSolrRewriteDefaultPort() throws Exception {
URI inputUri, outputUri;
Matcher<Void> matcher;
Matcher<Void>.Match match;
Template input, pattern, template;
inputUri = new URI("https://hortonworks.sandbox.hdp.24.test/gateway/sandbox/solr/TestCollection/select?q=*.*&wt=json&indent=true");
input = Parser.parseLiteral(inputUri.toString());
pattern = Parser.parseTemplate("*://*:*/**/solr/{collection=**}/{query=**}?{**}");
template = Parser.parseTemplate("http://sandbox.hortonworks.com/solr/{collection=**}/{query=**}?{**}");
matcher = new Matcher<Void>();
matcher.add(pattern, null);
match = matcher.match(input);
outputUri = Expander.expand(template, match.getParams(), null);
final String reWrittenScheme = outputUri.getScheme();
assertEquals("http", reWrittenScheme);
final String reWrittenHost = outputUri.getHost();
assertEquals("sandbox.hortonworks.com", reWrittenHost);
final String reWrittenPath = outputUri.getPath();
assertEquals("/solr/TestCollection/select", reWrittenPath);
// Whole thing is (non-deterministicly ordered around the &s):
// "q=*.*&wt=json&indent=true"
final String reWrittenQuery = outputUri.getQuery();
// Check individual parameters are present, and have the right value.
final Map<String, String> reWrittenParams = mapUrlParameters(reWrittenQuery);
assertTrue(reWrittenParams.containsKey("q"));
assertEquals("*.*", reWrittenParams.get("q"));
assertTrue(reWrittenParams.containsKey("wt"));
assertEquals("json", reWrittenParams.get("wt"));
assertEquals("true", reWrittenParams.get("indent"));
}
use of org.apache.knox.gateway.util.urltemplate.Matcher in project knox by apache.
the class ScopedMatcher method getMatcher.
/**
* Returns a matcher for a given template and processor holder. This method takes into account different scopes in
* addition to template values. If a matcher exists for a template but the scope is different, a new matcher is
* created and returned.
* @param template the template for which a matcher is needed
* @param holder the rule holder that goes along with the template.
* @return a matcher
*/
private Matcher<UrlRewriteRuleProcessorHolder> getMatcher(Template template, UrlRewriteRuleProcessorHolder holder) {
for (Matcher<UrlRewriteRuleProcessorHolder> matcher : matchers) {
UrlRewriteRuleProcessorHolder matchersHolder = matcher.get(template);
if (matchersHolder == null) {
return matcher;
} else if (holder.getScope() == null && matchersHolder.getScope() == null) {
return matcher;
}
}
Matcher<UrlRewriteRuleProcessorHolder> matcher = new Matcher<>();
matchers.add(matcher);
return matcher;
}
use of org.apache.knox.gateway.util.urltemplate.Matcher in project knox by apache.
the class UrlRewriteMatchProcessorExt method process.
@Override
public UrlRewriteStepStatus process(UrlRewriteContext context) throws Exception {
UrlRewriteStepStatus status = UrlRewriteStepStatus.SUCCESS;
if (matcher != null) {
status = UrlRewriteStepStatus.FAILURE;
Matcher.Match match = matcher.match(context.getCurrentUrl());
if (match != null) {
context.addParameters(match.getParams());
status = UrlRewriteStepStatus.SUCCESS;
}
}
return status;
}
use of org.apache.knox.gateway.util.urltemplate.Matcher in project knox by apache.
the class GatewayFilter method doFilter.
@SuppressWarnings("unchecked")
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
// TODO: The resulting pathInfo + query needs to be added to the servlet context somehow so that filters don't need to rebuild it. This is done in HttpClientDispatch right now for example.
String servlet = httpRequest.getServletPath();
String path = httpRequest.getPathInfo();
String query = httpRequest.getQueryString();
String requestPath = (servlet == null ? "" : servlet) + (path == null ? "" : path);
String requestPathWithQuery = requestPath + (query == null ? "" : "?" + query);
Template pathWithQueryTemplate;
try {
pathWithQueryTemplate = Parser.parseLiteral(requestPathWithQuery);
} catch (URISyntaxException e) {
throw new ServletException(e);
}
String contextWithPathAndQuery = httpRequest.getContextPath() + requestPathWithQuery;
LOG.receivedRequest(httpRequest.getMethod(), requestPath);
servletRequest.setAttribute(AbstractGatewayFilter.SOURCE_REQUEST_URL_ATTRIBUTE_NAME, pathWithQueryTemplate);
servletRequest.setAttribute(AbstractGatewayFilter.SOURCE_REQUEST_CONTEXT_URL_ATTRIBUTE_NAME, contextWithPathAndQuery);
Matcher<Chain>.Match match = chains.match(pathWithQueryTemplate);
// if there was no match then look for a default service for the topology
if (match == null) {
Topology topology = (Topology) servletRequest.getServletContext().getAttribute("org.apache.knox.gateway.topology");
if (topology != null) {
String defaultServicePath = topology.getDefaultServicePath();
if (defaultServicePath != null) {
try {
String newPathWithQuery = defaultServicePath + "/" + pathWithQueryTemplate;
match = chains.match(Parser.parseLiteral(newPathWithQuery));
String origUrl = ((HttpServletRequest) servletRequest).getRequestURL().toString();
String url = origUrl;
if (path.equals("/")) {
url += defaultServicePath;
} else {
int index = origUrl.indexOf(path);
url = origUrl.substring(0, index) + "/" + defaultServicePath + path;
}
String contextPath = defaultServicePath;
servletRequest = new ForwardedRequest((HttpServletRequest) servletRequest, contextPath, url);
} catch (URISyntaxException e) {
throw new ServletException(e);
}
}
}
}
assignCorrelationRequestId();
// Populate Audit/correlation parameters
AuditContext auditContext = auditService.getContext();
auditContext.setTargetServiceName(match == null ? null : match.getValue().getResourceRole());
auditContext.setRemoteIp(getRemoteAddress(servletRequest));
auditContext.setRemoteHostname(servletRequest.getRemoteHost());
auditor.audit(Action.ACCESS, contextWithPathAndQuery, ResourceType.URI, ActionOutcome.UNAVAILABLE, RES.requestMethod(((HttpServletRequest) servletRequest).getMethod()));
if (match != null) {
Chain chain = match.getValue();
servletRequest.setAttribute(AbstractGatewayFilter.TARGET_SERVICE_ROLE, chain.getResourceRole());
try {
chain.doFilter(servletRequest, servletResponse);
} catch (IOException | RuntimeException | ThreadDeath | ServletException e) {
LOG.failedToExecuteFilter(e);
auditor.audit(Action.ACCESS, contextWithPathAndQuery, ResourceType.URI, ActionOutcome.FAILURE);
throw e;
} catch (Throwable e) {
LOG.failedToExecuteFilter(e);
auditor.audit(Action.ACCESS, contextWithPathAndQuery, ResourceType.URI, ActionOutcome.FAILURE);
throw new ServletException(e);
} finally {
// Make sure to destroy the correlationContext to prevent threading issues
CorrelationServiceFactory.getCorrelationService().detachContext();
}
} else {
LOG.failedToMatchPath(requestPath);
httpResponse.setStatus(HttpServletResponse.SC_NOT_FOUND);
// Make sure to destroy the correlationContext to prevent threading issues
CorrelationServiceFactory.getCorrelationService().detachContext();
}
// KAM[ Don't do this or the Jetty default servlet will overwrite any response setup by the filter.
// filterChain.doFilter( servletRequest, servletResponse );
// ]
}
Aggregations