Skip to content

Commit

Permalink
Add more javadoc for proxy2.
Browse files Browse the repository at this point in the history
Rename ProxyMessageDeliverer into ForwardProxyMessageDeliverer.

Signed-off-by: Achim Kraus <achim.kraus@bosch.io>
  • Loading branch information
Achim Kraus committed Mar 17, 2020
1 parent 72bb7cc commit 8cd6db0
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 29 deletions.
2 changes: 2 additions & 0 deletions californium-proxy2/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@
<groupId>org.revapi</groupId>
<artifactId>revapi-maven-plugin</artifactId>
<configuration>
<!-- proxy2 is in development and doesn't grant a stable API! -->
<oldVersion>2.0.0</oldVersion>
<analysisConfiguration combine.children="append">
<revapi.ignore>
<item>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.eclipse.californium.core.coap.OptionSet;
import org.eclipse.californium.core.coap.Request;
import org.eclipse.californium.elements.util.StringUtil;
import org.eclipse.californium.proxy2.resources.ForwardProxyMessageDeliverer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -43,15 +44,17 @@ public class CoapUriTranslator {
public static final ResponseCode STATUS_TRANSLATION_ERROR = ResponseCode.BAD_GATEWAY;

/**
* Get destination schem for request.
* Get destination scheme of request for forward-proxy processing.
*
* If a Proxy-URI is provided, that is used to determine the scheme.
* Otherwise the {@link OptionSet#getProxyScheme()} is, if available, or the
* scheme of the request in absence of the other schemes.
*
* @param incomingRequest the original request
* @return scheme destination scheme
* @return destination scheme, or {@code null}, to bypass the forward-proxy
* processing.
* @throws TranslationException the translation exception
* @see ForwardProxyMessageDeliverer
*/
public String getDestinationScheme(Request incomingRequest) throws TranslationException {
if (incomingRequest == null) {
Expand Down Expand Up @@ -81,11 +84,13 @@ public String getDestinationScheme(Request incomingRequest) throws TranslationEx
*
* In container deployments the receiving local interface may differ from
* the exposed one. That interface may be required, if the request doesn't
* contain a uri-host- or uri-port-option. In that case, the interface is
* contain a uri-host or uri-port option. In that case, the interface is
* used to fill in the missing information. This default implementation
* returns {@code null}.
* returns {@code null} and so requires, that the requests contains the
* uri-host and uri-port option.
*
* @param incomingRequest the received request.
* @param incomingRequest the received request. The request's destination
* contains the address of the local receiving interface.
* @return exposed interface. {@code null}, if not available.
*/
public InetSocketAddress getExposedInterface(Request incomingRequest) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,9 @@ public void handle(HttpRequest httpRequest, final HttpAsyncExchange httpExchange
// if (Bench_Help.DO_LOG)
LOGGER.info("Received HTTP request and translate to {}", coapRequest);
coapRequest.setSourceContext(new AddressEndpointContext(source));
// use destination of incoming request to keep the receiving interface.
coapRequest.setDestinationContext(new AddressEndpointContext(endpoint));
// handle the requset
// handle the request
Exchange exchange = new Exchange(coapRequest, Origin.REMOTE, null) {

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,31 @@
import org.slf4j.LoggerFactory;

/**
* Proxy message deliverer
* Forward proxy message deliverer
*
* Delivers message either to proxy resources registered for the destination
* scheme, or, to local resources using the requests path.
*
* A request is considered for the forward-proxy, if either
* <ul>
* <li>a proxy-uri or a proxy-scheme option is contained, or,</li>
* <li>a uri-host and/or uri-port option is contained in the request, and the
* destination defined by this options is not contained in the exposed service
* addresses</li>
* </ul>
* For request considered for the forward-proxy, the destination scheme is
* determined by calling {@link CoapUriTranslator#getDestinationScheme(Request)}
* of the provided translator. If a {@link ProxyCoapResource} was added, which
* handles this destination scheme, the request delivered to that resource. For
* none-compliant proxies, the translater implementation may return {@code null}
* for special request to bypass the forward-proxy processing.
*
* Requests not processed by the forward-proxy are processed as standard request
* by the coap-server.
*/
public class ProxyMessageDeliverer extends ServerMessageDeliverer {
public class ForwardProxyMessageDeliverer extends ServerMessageDeliverer {

private static final Logger LOGGER = LoggerFactory.getLogger(ProxyMessageDeliverer.class);
private static final Logger LOGGER = LoggerFactory.getLogger(ForwardProxyMessageDeliverer.class);

/**
* Translator to determine destination scheme.
Expand Down Expand Up @@ -74,12 +91,16 @@ public class ProxyMessageDeliverer extends ServerMessageDeliverer {
private final Set<Integer> exposedPorts;

/**
* Create message deliverer with proxy support.
* Create message deliverer with forward-proxy support.
*
* @param root root resource of coap-proxy-server
* @param translater translator for coap-request-uri's
* @param translater translator for destination-scheme.
* {@link CoapUriTranslator#getDestinationScheme(Request)} is
* used to determine this destination scheme for forward-proxy
* implementations. The translater may return {@code null} to
* bypass the forward-proxy processing for a request.
*/
public ProxyMessageDeliverer(Resource root, CoapUriTranslator translater) {
public ForwardProxyMessageDeliverer(Resource root, CoapUriTranslator translater) {
super(root);
this.translater = translater;
this.scheme2resource = new HashMap<String, Resource>();
Expand All @@ -97,7 +118,7 @@ public ProxyMessageDeliverer(Resource root, CoapUriTranslator translater) {
* @throws NullPointerException if {@code null} is provided
* @throws IllegalArgumentException if list is empty
*/
public ProxyMessageDeliverer addExposedServiceAddresses(InetSocketAddress... exposed) {
public ForwardProxyMessageDeliverer addExposedServiceAddresses(InetSocketAddress... exposed) {
if (exposed == null) {
throw new NullPointerException("exposed interfaces must not be null!");
}
Expand Down Expand Up @@ -132,13 +153,13 @@ public ProxyMessageDeliverer addExposedServiceAddresses(InetSocketAddress... exp
}

/**
* Add proxy coap resources for standard forward proxies.
* Add proxy coap resources as standard forward-proxies.
*
* @param proxies list of proxy resources.
* @throws NullPointerException if {@code null} is provided
* @throws IllegalArgumentException if list is empty
*/
public ProxyMessageDeliverer addProxyCoapResources(ProxyCoapResource... proxies) {
public ForwardProxyMessageDeliverer addProxyCoapResources(ProxyCoapResource... proxies) {
if (proxies == null) {
throw new NullPointerException("proxies must not be null!");
}
Expand Down Expand Up @@ -169,15 +190,18 @@ protected Resource findResource(Exchange exchange) {
OptionSet options = request.getOptions();
boolean proxyOption = options.hasProxyUri() || options.hasProxyScheme();
boolean hostOption = options.hasUriHost() || options.hasUriPort();
boolean local = true;

if (hostOption && !proxyOption && !exposedServices.isEmpty()) {
// check, if proxy is destination.
if (hostOption && !exposedServices.isEmpty()) {
// check, if proxy is final destination.
Integer port = options.getUriPort();
String host = options.getUriHost();
if (host == null) {
if (exposedPorts.contains(port)) {
// proxy is destination
hostOption = false;
} else {
local = false;
}
} else {
if (port == null) {
Expand All @@ -186,6 +210,8 @@ protected Resource findResource(Exchange exchange) {
if (exposedHosts.contains(address)) {
// proxy is destination
hostOption = false;
} else {
local = false;
}
} catch (UnknownHostException e) {
// destination not reachable
Expand All @@ -196,31 +222,53 @@ protected Resource findResource(Exchange exchange) {
if (destination.isUnresolved() || exposedServices.contains(destination)) {
// destination not reachable or proxy is destination
hostOption = false;
} else {
local = false;
}
}
}
}

if (proxyOption || hostOption) {
try {
String scheme = translater.getDestinationScheme(request);
if (scheme != null) {
scheme = scheme.toLowerCase();
resource = scheme2resource.get(scheme);
if (resource != null && request.getDestinationContext() == null) {
preserveReceivingInterface(exchange);
}
} else {
local = true;
}
} catch (TranslationException e) {
LOGGER.debug("Bad proxy request", e);
}
}
if (resource == null) {
if (resource == null && local) {
// try to find local resource
resource = super.findResource(exchange);
}
if (resource != null && request.getDestinationContext() == null) {
if (exchange.getEndpoint() != null) {
// set local receiving addess as destination
request.setDestinationContext(new AddressEndpointContext(exchange.getEndpoint().getAddress()));
}
}
return resource;
}

/**
* Preserve the address of the local receiving interface in the requests
* destination.
*
* The destination maybe required for forward-proxies, if uri-host or
* uri-port options are missing. The
* {@link CoapUriTranslator#getExposedInterface(Request)} is intended to
* provide the mapping of local interfaces to exposed interfaces. If this
* mapping s not possible, all request for the forward-proxy requires the
* uri-host and uri-port option to be contained!
*
* @param exchange exchange with request and receiving endpoint
*/
private void preserveReceivingInterface(Exchange exchange) {
if (exchange.getEndpoint() != null) {
exchange.getRequest()
.setDestinationContext(new AddressEndpointContext(exchange.getEndpoint().getAddress()));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,49 @@
import org.eclipse.californium.core.CoapResource;
import org.eclipse.californium.core.coap.Request;
import org.eclipse.californium.core.network.Exchange;
import org.eclipse.californium.core.server.ServerMessageDeliverer;
import org.eclipse.californium.proxy2.Coap2CoapTranslator;
import org.eclipse.californium.proxy2.Coap2HttpTranslator;
import org.eclipse.californium.proxy2.EndpointPool;
import org.eclipse.californium.proxy2.Http2CoapTranslator;
import org.eclipse.californium.proxy2.TranslationException;

/**
* Resource that forwards a coap request.
*
* According <a href="https://tools.ietf.org/html/rfc7252#section-5.7">RFC 7252,
* 5.7 Proxying</a> proxies are classified into <a href=
* "https://tools.ietf.org/html/rfc7252#section-5.7.2">Forward-Proxies</a> and
* <a href=
* "https://tools.ietf.org/html/rfc7252#section-5.7.3">Reverse-Proxies</a>.
*
* The forward-proxies operates in a generic way. The destination to sent the
* request by the proxy is contained in the request itself. It is provided in
* the coap-options (Uri-Host, Uri-Port, Uri-Path, Uri-Query, and Proxy-Scheme,
* or Proxy-Uri). This is very similar to a http proxy, where the http-request
* including the destination host, is sent to the http-proxy.
*
* The reverse-proxies instead are specific. They don't use the above options to
* define the destination, instead this destination is defined by configuration
* or/and information in the request.
*
* Over the time, it seems, that these two variants got mixed. One reason for
* that may be the fact, that the Proxy-URI is the only standard option, which
* may contain more than 255 bytes. That mix makes it hard to implement a proxy
* functionality, especially, if such none-compliant cases should be also
* considered.
*
* This {@link ProxyCoapResource} supports both variants adapting the conversion
* using custom implementations of {@link Coap2CoapTranslator} or
* {@link Http2CoapTranslator}. Forward proxies are implemented replacing the
* default {@link ServerMessageDeliverer} by
* {@link ForwardProxyMessageDeliverer} and add {@link ProxyCoapClientResource}
* and/or {@link ProxyHttpClientResource} to this message-forwarded. Reverse
* proxies are implemented using
* {@link #createReverseProxy(String, boolean, boolean, boolean, URI, EndpointPool...)}.
* If a reverse proxy requires a customized conversion, add a customized
* {@link ProxyCoapClientResource} and/or {@link ProxyHttpClientResource} to the
* coap-server.
*/
public abstract class ProxyCoapResource extends CoapResource {

Expand All @@ -53,17 +89,19 @@ public ProxyCoapResource(String name, boolean visible, boolean accept) {
}

/**
* Set of supported destination schemes.
* Set of supported destination schemes for forward-proxy.
*
* @return set of supported destination schemes.
* @return set of supported destination schemes for forward-proxy.
* {@code null} for reverse-proxy.
* @see ForwardProxyMessageDeliverer
*/
public abstract Set<String> getDestinationSchemes();

@Override
public abstract void handleRequest(final Exchange exchange);

/**
* Create reverse proxy for fixed destination.
* Create reverse-proxy for fixed destination.
*
* @param name name of the resource
* @param visible visibility of the resource
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
import org.eclipse.californium.proxy2.resources.ProxyCoapClientResource;
import org.eclipse.californium.proxy2.resources.ProxyCoapResource;
import org.eclipse.californium.proxy2.resources.ProxyHttpClientResource;
import org.eclipse.californium.proxy2.resources.ProxyMessageDeliverer;
import org.eclipse.californium.proxy2.resources.ForwardProxyMessageDeliverer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -147,7 +147,7 @@ public CrossExampleProxy2(NetworkConfig config) throws IOException {
// Forwards requests Coap to Coap or Coap to Http server
coapProxyServer = new CoapServer(config, coapPort);
MessageDeliverer local = coapProxyServer.getMessageDeliverer();
ProxyMessageDeliverer proxyMessageDeliverer = new ProxyMessageDeliverer(coapProxyServer.getRoot(), translater);
ForwardProxyMessageDeliverer proxyMessageDeliverer = new ForwardProxyMessageDeliverer(coapProxyServer.getRoot(), translater);
proxyMessageDeliverer.addProxyCoapResources(coap2coap, coap2http);
proxyMessageDeliverer.addExposedServiceAddresses(new InetSocketAddress(coapPort));
coapProxyServer.setMessageDeliverer(proxyMessageDeliverer);
Expand Down

0 comments on commit 8cd6db0

Please sign in to comment.