use of org.apache.hc.core5.http.HeaderElements in project californium by eclipse.
the class CrossProtocolTranslator method getCoapOptions.
/**
* Gets the coap options starting from an array of http headers.
*
* The content-type is not handled by this method. The method iterates over
* an array of headers and for each of them tries to find a mapping in the
* properties file, if the mapping does not exists it skips the header
* ignoring it. The method handles separately certain headers which are
* translated to options (such as accept or cache-control) whose content
* should be semantically checked or requires ad-hoc translation. Otherwise,
* the headers content is translated with the appropriate format required by
* the mapped option.
*
* @param headers array of http headers
* @param etagTranslator translator for etag
* @return list of CoAP options.
* @throws NullPointerException if headers is {@code null}
*/
public List<Option> getCoapOptions(Header[] headers, EtagTranslator etagTranslator) {
if (headers == null) {
throw new NullPointerException("http header must not be null!");
}
Option accept = null;
float acceptQualifier = 0.0F;
List<Option> optionList = new LinkedList<Option>();
// iterate over the headers
for (Header header : headers) {
try {
String headerName = header.getName().toLowerCase();
// get the mapping from the property file
Integer coapOption = translationMapping.getCoapOption(headerName);
// ignore the header if not found in the properties file
if (coapOption == null) {
continue;
}
int optionNumber = coapOption;
// payload
if (optionNumber == OptionNumberRegistry.CONTENT_FORMAT) {
continue;
}
// get the value of the current header
String headerValue = header.getValue().trim();
// values
if (optionNumber == OptionNumberRegistry.ACCEPT) {
final ParserCursor cursor = new ParserCursor(0, headerValue.length());
HeaderElement[] headerElements = parser.parseElements(headerValue, cursor);
for (HeaderElement element : headerElements) {
float qualifier = 1.0F;
String mimeType = element.getName();
NameValuePair q = element.getParameterByName("q");
if (q != null) {
try {
qualifier = Float.parseFloat(q.getValue());
} catch (NumberFormatException ex) {
}
}
if (accept == null || acceptQualifier < qualifier) {
int coapContentType = MediaTypeRegistry.UNDEFINED;
String headerFragment = mimeType.trim();
if (headerFragment.contains("*")) {
int[] coapContentTypes = MediaTypeRegistry.parseWildcard(headerFragment);
if (coapContentTypes.length > 0) {
coapContentType = coapContentTypes[0];
}
} else {
coapContentType = getCoapMediaType(headerFragment, MediaTypeRegistry.UNDEFINED);
}
if (coapContentType != MediaTypeRegistry.UNDEFINED) {
accept = new Option(optionNumber, coapContentType);
acceptQualifier = qualifier;
}
}
}
} else if (optionNumber == OptionNumberRegistry.MAX_AGE) {
int maxAge = -1;
final ParserCursor cursor = new ParserCursor(0, headerValue.length());
HeaderElement[] headerElements = parser.parseElements(headerValue, cursor);
for (HeaderElement element : headerElements) {
if (element.getName().equalsIgnoreCase("no-cache")) {
maxAge = 0;
break;
} else if (element.getName().equalsIgnoreCase("max-age")) {
String value = element.getValue();
try {
maxAge = Integer.parseInt(value);
break;
} catch (NumberFormatException e) {
LOGGER.debug("Cannot convert cache control '{}' in max-age option", value, e);
}
}
}
if (maxAge >= 0) {
// create the option
Option option = new Option(optionNumber, maxAge);
optionList.add(option);
}
} else if (optionNumber == OptionNumberRegistry.ETAG) {
byte[] etag = etagTranslator.getCoapEtag(headerValue);
Option option = new Option(optionNumber, etag);
optionList.add(option);
} else if (optionNumber == OptionNumberRegistry.IF_MATCH) {
byte[] etag = etagTranslator.getCoapEtag(headerValue);
Option option = new Option(optionNumber, etag);
optionList.add(option);
} else if (optionNumber == OptionNumberRegistry.IF_NONE_MATCH) {
if (headerValue.equals("*")) {
Option option = new Option(optionNumber, Bytes.EMPTY);
optionList.add(option);
} else {
LOGGER.debug("'if-none-match' with etag '{}' is not supported!", headerValue);
}
} else if (optionNumber == OptionNumberRegistry.LOCATION_PATH) {
try {
URI uri = new URI(headerValue);
OptionSet set = new OptionSet();
String value = uri.getPath();
if (value != null) {
set.setLocationPath(value);
}
value = uri.getQuery();
if (value != null) {
set.setLocationQuery(value);
}
optionList.addAll(set.asSortedList());
} catch (URISyntaxException e) {
LOGGER.debug("'content-location' with '{}' is not supported!", headerValue, e);
} catch (IllegalArgumentException e) {
LOGGER.debug("'content-location' with '{}' is not supported!", headerValue, e);
}
} else {
// create the option
Option option = new Option(optionNumber);
switch(OptionNumberRegistry.getFormatByNr(optionNumber)) {
case INTEGER:
option.setIntegerValue(Integer.parseInt(headerValue));
break;
case OPAQUE:
option.setValue(headerValue.getBytes(ISO_8859_1));
break;
case EMPTY:
option.setValue(Bytes.EMPTY);
break;
case STRING:
default:
option.setStringValue(headerValue);
break;
}
optionList.add(option);
}
} catch (RuntimeException e) {
LOGGER.debug("Could not parse header line {}: {}", header, e.getMessage());
}
}
if (accept != null) {
optionList.add(accept);
}
return optionList;
}
Aggregations