Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more javadoc for proxy2. #1232

Merged
merged 1 commit into from
Mar 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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