I'm trying to expose a Jackrabbit Oak repository through a servlet. While I'm able to successfully retrieve and edit a .docx
file with LibreOffice Writer, Microsoft Word does not work.
I'm making use of:
- Jackrabbit Oak version 1.8.4
- Jackrabbit version 2.17.5
- LibreOffice Writer version 6.1.3.2
The version of Word not working is:
- Version 1708
- Microsoft Office 365 ProPlus.
I access the documents similarly in both editors by using the open document dialogue and putting in http://localhost:8080/helloworld-singleton/repository/default/test.docx
I've setup a simple servlet using the OpenSecurityProvider
that exposes a repository that copies a local copy of a simple .docx document:
public class SimpleWebdavServlet extends SimpleWebdavServlet {
private static Repository repository;
public Repository getRepository() {
return getRepositoryInternal();
}
static Repository getRepositoryInternal() {
try {
if (repository == null) {
Jcr jcr = new Jcr().with(new OpenSecurityProvider());
repository = jcr.createRepository();
Session session = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
Node rootNode = session.getRootNode();
if (!rootNode.hasNode("test.docx")) {
importFile(session, rootNode);
}
session.save();
}
} catch (FileNotFoundException | RepositoryException e) {
e.printStackTrace();
}
return repository;
}
private static void importFile(Session session, Node rootNode) throws FileNotFoundException, RepositoryException {
FileInputStream is = new FileInputStream(new File("C:\\test.docx"));
ValueFactory valueFactory = session.getValueFactory();
Binary contentValue = valueFactory.createBinary(is);
Node fileNode = rootNode.addNode("test.docx", "nt:file");
fileNode.addMixin("mix:referenceable");
Node resNode = fileNode.addNode("jcr:content", "nt:resource");
resNode.setProperty("jcr:mimeType", "application/octet-stream");
resNode.setProperty("jcr:data", contentValue);
Calendar lastModified = Calendar.getInstance();
lastModified.setTimeInMillis(lastModified.getTimeInMillis());
resNode.setProperty("jcr:lastModified", lastModified);
session.save();
}
}
This servlet is configured through the following web.xml
:
<web-app>
<display-name>Jackrabbit Webdav</display-name>
<servlet>
<servlet-name>Webdav</servlet-name>
<servlet-class>org.jboss.as.quickstarts.singleton.SimpleWebdavServlet</servlet-class>
<init-param>
<param-name>resource-path-prefix</param-name>
<param-value>/repository</param-value>
</init-param>
<init-param>
<param-name>missing-auth-mapping</param-name>
<param-value>admin:admin</param-value>
</init-param>
<init-param>
<param-name>resource-config</param-name>
<param-value>/WEB-INF/config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Webdav</servlet-name>
<url-pattern>/repository/*</url-pattern>
</servlet-mapping>
</web-app>
With this code, I would have expected that I would be able to open the document in Word, edit it, and save the changes to the server - Like I'm able to in LibreOffice Writer.
Instead with Word, the document is opened with protected view, attempt to save changes, you're only prompted to save a local copy of it.
I've tried to make a similar servlet for another JCR Implementation ModeShape, and experienced no problems with the persisting documents through Word there.
As a possible explanation while debugging internally within Jackrabbit, a noticeable difference between the editors is that LibreOffice Writer sends over null
in the Authorization
header, while Word sends Bearer
in the Authorization
header for several of it's requests. All of these requests are then ignored due to the exception of org.apache.jackrabbit.webdav.DavException: Unable to decode authorization.
Does anybody know why Word does not work as expected in this case?