Skip to content
This repository was archived by the owner on Aug 30, 2022. It is now read-only.
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package org.eclipse.californium.core;

import java.net.URI;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
Expand All @@ -33,14 +34,19 @@
import org.eclipse.californium.core.coap.CoAP.Code;
import org.eclipse.californium.core.coap.CoAP.ResponseCode;
import org.eclipse.californium.core.coap.CoAP.Type;
import org.eclipse.californium.core.coap.OptionSet;
import org.eclipse.californium.core.coap.Response;
import org.eclipse.californium.core.network.Endpoint;
import org.eclipse.californium.core.network.Exchange;
import org.eclipse.californium.core.observe.ObserveNotificationOrderer;
import org.eclipse.californium.core.observe.ObserveRelation;
import org.eclipse.californium.core.observe.ObserveRelationContainer;
import org.eclipse.californium.core.server.ServerMessageDeliverer;
import org.eclipse.californium.core.server.resources.AcceptDefaultSupport;
import org.eclipse.californium.core.server.resources.AcceptSupport;
import org.eclipse.californium.core.server.resources.CoapExchange;
import org.eclipse.californium.core.server.resources.ETagDefaultSupport;
import org.eclipse.californium.core.server.resources.ETagSupport;
import org.eclipse.californium.core.server.resources.Resource;
import org.eclipse.californium.core.server.resources.ResourceAttributes;
import org.eclipse.californium.core.server.resources.ResourceObserver;
Expand Down Expand Up @@ -159,6 +165,12 @@ public class CoapResource implements Resource {
/* The notification orderer. */
private ObserveNotificationOrderer notificationOrderer;

/* Support for ETags */
private ETagSupport etagSupport;

/* Support for Accept */
private AcceptSupport acceptSupport;

/**
* Constructs a new resource with the specified name.
*
Expand All @@ -184,8 +196,9 @@ public CoapResource(String name, boolean visible) {
this.observers = new CopyOnWriteArrayList<ResourceObserver>();
this.observeRelations = new ObserveRelationContainer();
this.notificationOrderer = new ObserveNotificationOrderer();
this.etagSupport = createETagSupport();
this.acceptSupport = createAcceptSupport();
}


/**
* Handles any request in the given exchange. By default it responds
Expand All @@ -201,6 +214,13 @@ public CoapResource(String name, boolean visible) {
@Override
public void handleRequest(final Exchange exchange) {
Code code = exchange.getRequest().getCode();

if (code == Code.GET && validateETag(exchange))
return;

if (expectsUnacceptableFormat(exchange))
return;

switch (code) {
case GET: handleGET(new CoapExchange(exchange, this)); break;
case POST: handlePOST(new CoapExchange(exchange, this)); break;
Expand All @@ -209,6 +229,57 @@ public void handleRequest(final Exchange exchange) {
}
}

/**
* Compares the ETags of the request with the current ETag from the
* {@link ETagSupport}. If an ETag matches, the method automatically
* responds with a 2.03 (Valid) and returns true. If there is no ETag or if
* there is not ETagSupport object, the method returns false.
*
* @param exchange the exchange
* @return true, if the request has a valid ETag, false otherwise
*/
public boolean validateETag(Exchange exchange) {
ETagSupport support = getETagSupport();
OptionSet options = exchange.getRequest().getOptions();
if (options.getETagCount() > 0 && support != null) {
byte[] current = support.getCurrentETag();
for (byte[] etag:options.getETags())
if (Arrays.equals(etag, current)) {
Response response = new Response(ResponseCode.VALID);
response.getOptions().addETag(current);
exchange.sendResponse(response);
return true;
}
}
return false;
}

/**
* Compares the accept value of the request with the accept values of the
* AcceptSupport object (ASO). If the request has no accept value, it is
* considered to accept anything. If there is no ASO, the resource is
* considered to accept any request (it still can send a Not-Acceptable
* response). Only if the request has an accept value and the ASO does not
* accept it, this method responds with a 4.06 (Not Acceptable) and returns
* true. The {@link AcceptDefaultSupport} by default accepts everything.
*
* @param exchange the exchange
* @return true, if the request does NOT accept the content format of this
* resource
*/
public boolean expectsUnacceptableFormat(Exchange exchange) {
AcceptSupport support = getAcceptSupport();
OptionSet options = exchange.getRequest().getOptions();
if (options.hasAccept() && support != null) {
if (! support.isAcceptable(options.getAccept())) {
Response response = new Response(ResponseCode.NOT_ACCEPTABLE);
exchange.sendResponse(response);
return true;
}
}
return false;
}

/**
* Handles the GET request in the given CoAPExchange. By default it
* responds with a 4.05 (Method Not Allowed). Override this method to
Expand Down Expand Up @@ -677,7 +748,7 @@ public void removeObserveRelation(ObserveRelation relation) {
}

/**
* Returns the number of observe realtions that this resource has to CoAP
* Returns the number of observe relations that this resource has to CoAP
* clients.
*
* @return the observer count
Expand Down Expand Up @@ -718,6 +789,60 @@ protected void notifyObserverRelations() {
relation.notifyObservers();
}
}

/**
* Creates a new ETagSupport object.
*
* @return an ETagSupport object
*/
protected ETagSupport createETagSupport() {
return new ETagDefaultSupport();
}

/**
* Creates a new AcceptSupport object.
*
* @return an AcceptSupport object
*/
protected AcceptSupport createAcceptSupport() {
return new AcceptDefaultSupport();
}

/**
* Gets the ETagSupport object or null if none is present.
*
* @return the ETagSupport object
*/
public ETagSupport getETagSupport() {
return etagSupport;
}

/**
* Sets the ETag support object.
*
* @param support the new ETag support object
*/
public void setETagSupport(ETagSupport support) {
this.etagSupport = support;
}

/**
* Gets the AcceptSupport object or null if none is present.
*
* @return the AcceptSupport object
*/
public AcceptSupport getAcceptSupport() {
return acceptSupport;
}

/**
* Sets the accept support object.
*
* @param support the new accept support obejct
*/
public void setAcceptSupport(AcceptSupport support) {
this.acceptSupport = support;
}

/* (non-Javadoc)
* @see org.eclipse.californium.core.server.resources.Resource#getChildren()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package org.eclipse.californium.core.server.resources;

import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

/**
* The default implementation for supporting accept options in resources. An
* instance of AcceptDefaultSupport contains a set with all acceptable content
* formats. <b>If it holds no value at all, then ALL content formats are
* considered accepted</b>.
*/
public class AcceptDefaultSupport implements AcceptSupport {

/** The acceptable content formats. */
private Set<Integer> acceptables;

/**
* Instantiates a support object for accept options.
*/
public AcceptDefaultSupport() {
acceptables = new CopyOnWriteArraySet<Integer>();
}

/* (non-Javadoc)
* @see org.eclipse.californium.core.server.resources.AcceptSupport#addAcceptable(int)
*/
public void addAcceptable(int... acceptableValues) {
for (int acc:acceptableValues)
acceptables.add(acc);
}

/* (non-Javadoc)
* @see org.eclipse.californium.core.server.resources.AcceptSupport#removeAcceptable(int)
*/
public void removeAcceptable(int... values) {
for (int val:values)
acceptables.remove(val);
}

/* (non-Javadoc)
* @see org.eclipse.californium.core.server.resources.AcceptSupport#accepts(int)
*/
public boolean isAcceptable(int acceptable) {
return acceptables.isEmpty() || acceptables.contains(acceptable);
}

/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "AcceptDefaultSupport("+acceptables.toString()+")";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.eclipse.californium.core.server.resources;

/**
* An AcceptSupport object supports a resource in checking if the requested
* content format (accept option) of a request is consistent with the content
* format(s) the resource provides.
*/
public interface AcceptSupport {

/**
* Adds the specified values to the acceptable content format requests.
*
* @param acceptableValues the acceptable values
*/
public void addAcceptable(int... acceptableValues);

/**
* Removes the specified values from the acceptable content format requests.
*
* @param values the values
*/
public void removeAcceptable(int... values);

/**
* Returns true if the specified content format can be provided.
*
* @param acceptable the requested content format
* @return true, if the accept request can be met
*/
public boolean isAcceptable(int acceptable);

}
Loading