I am currently developing a MS Word Office Addin using the JavaScript interface provided by Microsoft. I made a test implementation using a Django backend, where everything worked fine.
However for the final product I have to integrate functionality with an existing Java Backend that runs in multiple configurations, which are out of my control. Consisting of Vaadin for the UI and mostly Tomcat (but not always) as a Servlet Container.
I've run into the problem that the IFrame that runs inside Word, appends an unwanted and malformed _host_info to the request URL, that contains un-urlencoded pipe characters. e.g: Tomcat Log:
"GET /myapp/?_host_Info=Word|Win32|16.01|en-US HTTP/1.1" 200 2101
This malformed URL produces the following exception:
java.lang.RuntimeException: Invalid location URI received from client.
... full stack trace at bottom of the post...
Caused by: java.net.URISyntaxException: Illegal character in query at index 45: https://localhost:8443/myapp/?_host_Info=Word|Win32|16.01|en-US
As far as I know, I have no control, on whether or not to append this Parameter to the URL, since in the Manifest File of the Addin I only specify the source URL like below, and the info gets added automatically.
<SourceLocation DefaultValue="https://localhost:8443/myapp/ " />
Checking the Documentation I didn't find this behaviour in there, so i might be missing something. Querying the host info is mentioned in this blog post, but it seems it should not be part of the URL.
Is there a way I can stop the Office Add-In from appending: ?_host_Info=Word|Win32|16.01|en-US HTTP/1.1 to the request?
If not, is there a correct way to filte/ignore that part of the URL with Tomcat? Since the whole app has been running correctly with my Apache Webserver & Django Backend, where the URL was received too, but it worked.
As for question two, I've already tried to implement a Servlet filter that should remove the parameter in question. But since it relies on the same Java library to parse the URL to look at it, the same exception is thrown.
> May 23, 2016 11:04:51 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [MyUIServlet] in context with path [/word-to-moxis] threw exception [com.vaadin.server.ServiceException: java.lang.RuntimeException: Invalid location URI received from client] with root cause
java.net.URISyntaxException: Illegal character in query at index h(invalidated link because of 10 reputation / two links allowed policy)ttps://localhost:8443/myapp/?_host_Info=Word|Win32|16.01|en-US
at java.net.URI$Parser.fail(URI.java:2848)
at java.net.URI$Parser.checkChars(URI.java:3021)
at java.net.URI$Parser.parseHierarchical(URI.java:3111)
at java.net.URI$Parser.parse(URI.java:3053)
at java.net.URI.<init>(URI.java:588)
at com.vaadin.server.Page.init(Page.java:651)
at com.vaadin.ui.UI.doInit(UI.java:679)
at com.vaadin.server.communication.`UIInitHandler`.getBrowserDetailsUI(UIInitHandler.java:214)
Update:
The following Quick & Dirty Hack acts as a workaround of the problem. Still baffled as to why they chose to encode the information that way:
public class AddinServletRequestWrapper extends HttpServletRequestWrapper {
Map<String, String[]> parameterMap;
public AddinServletRequestWrapper(HttpServletRequest originalRequest) {
super(originalRequest);
parameterMap = new HashMap<String, String[]>(originalRequest.getParameterMap());
parameterMap.remove("_host_Info");
}
@Override
public String getParameter(String name) {
// TODO: Improve
String[] value = parameterMap.get(name);
if (value == null || value.length == 0)
return null;
if(name == "v-loc"){
return value[0].replace('|', '_');
}
return value[0];
}
}
Update 2/ Feb17:
With more recent Tomcat updates the workaround above no longer suffices. As noted in the comments, the versions 7.0.73, 8.0.39, 8.5.7 have a stricter URL policy. Therefore there is no solution to use the versions of tomcat for hosting office add-ins without additional tooling. I really hope this situation changes soon because such a small, probably useless string can use such problems with deployments.
UPDATE: The API is now available for use:
console.log(Office.context.host); //example: Excel
console.log(Office.context.platform); //example: PC, MAC, IOS, null (for stand alone website)
Possible values for host are: Word Excel PowerPoint Outlook OneNote Project Access
Possible values for platform are: PC OfficeOnline Mac iOS Android Universal
We recently removed the query parameters from the URL in light of the issues noted in single page applications. the _host_info_ is no longer appended for add-ins opened in the browser (Office Online).
@Matthias: For this issue, adding
office-js
tag would be more accurate. I couldn't append given the size limit for tags.If you have an apache with mod_rewrite enabled in front of your tomcat, it's possible to add this dirty apache rule to infly reencode the outlook request :
I hope this can help
This change of the URL also wreaks havoc in Angular if you are playing with the urlRouteProvider at all. It appears to create a digest loop because it is location changing event to fire inside Angular which exceeds the 10 loop limit of the digest. :(
We had a similar problem to this one.
Our solution was to downgrade our tomcat versión from 8.0.39 to 8.0.30.
Look also this: |' in query parameters?
Hope this helps.