1 package org.opendaylight.controller.netconf.nettyutil.handler;
3 import com.google.common.base.Preconditions;
4 import org.openexi.proc.HeaderOptionsOutputType;
5 import org.openexi.proc.common.EXIOptions;
6 import org.openexi.proc.common.EXIOptionsException;
7 import org.openexi.proc.common.GrammarOptions;
8 import org.openexi.proc.grammars.GrammarCache;
9 import org.openexi.sax.EXIReader;
10 import org.openexi.sax.Transmogrifier;
11 import org.openexi.sax.TransmogrifierException;
12 import org.xml.sax.EntityResolver;
13 import org.xml.sax.InputSource;
15 public final class NetconfEXICodec {
17 * NETCONF is XML environment, so the use of EXI cookie is not really needed. Adding it
18 * decreases efficiency of encoding by adding human-readable 4 bytes "EXI$" to the head
19 * of the stream. This is really useful, so let's output it now.
21 private static final boolean OUTPUT_EXI_COOKIE = true;
23 * OpenEXI does not allow us to directly prevent resolution of external entities. In order
24 * to prevent XXE attacks, we reuse a single no-op entity resolver.
26 private static final EntityResolver ENTITY_RESOLVER = new EntityResolver() {
28 public InputSource resolveEntity(final String publicId, final String systemId) {
29 return new InputSource();
33 private final EXIOptions exiOptions;
35 public NetconfEXICodec(final EXIOptions exiOptions) {
36 this.exiOptions = Preconditions.checkNotNull(exiOptions);
39 private GrammarCache getGrammarCache() {
40 short go = GrammarOptions.DEFAULT_OPTIONS;
41 if (exiOptions.getPreserveComments()) {
42 go = GrammarOptions.addCM(go);
44 if (exiOptions.getPreserveDTD()) {
45 go = GrammarOptions.addDTD(go);
47 if (exiOptions.getPreserveNS()) {
48 go = GrammarOptions.addNS(go);
50 if (exiOptions.getPreservePIs()) {
51 go = GrammarOptions.addPI(go);
54 return new GrammarCache(null, go);
57 EXIReader getReader() throws EXIOptionsException {
58 final EXIReader r = new EXIReader();
59 r.setPreserveLexicalValues(exiOptions.getPreserveLexicalValues());
60 r.setGrammarCache(getGrammarCache());
61 r.setEntityResolver(ENTITY_RESOLVER);
65 Transmogrifier getTransmogrifier() throws EXIOptionsException, TransmogrifierException {
66 final Transmogrifier transmogrifier = new Transmogrifier();
67 transmogrifier.setAlignmentType(exiOptions.getAlignmentType());
68 transmogrifier.setBlockSize(exiOptions.getBlockSize());
69 transmogrifier.setGrammarCache(getGrammarCache());
70 transmogrifier.setOutputCookie(OUTPUT_EXI_COOKIE);
71 transmogrifier.setOutputOptions(HeaderOptionsOutputType.all);
72 transmogrifier.setResolveExternalGeneralEntities(false);
73 return transmogrifier;