Why do Scroll Exporters open HTTP Connections to Confluence?
Scroll Exporters and HTTP Connections
This page gives an overview about the Scroll Exporters and HTTP connections.
What are these Connections?
All Scroll Exporters use HTTP connections to:
load images
integrate with other Scroll plugins installed on your server, for example to retrieve a page list from Scroll Versions when exporting a selected version or variant.
These connections are either established with:
your local Confluence, or
any external server that your Confluence pages are including images from.
Connections to K15t Servers
Scroll Exporters do never contact K15t servers with one exception: You are manually running the resource load test. In this case the Scroll Exporter on your system tries to load a static image from our website to check whether it can establish connections to external servers or if a firewall is preventing it from doing this.
In fact, it is perfectly fine to configure your firewall in such a way that it prevents access to external servers if you do not need to load resources from there.
Why are those Connections required?
When we started to implement our exporters we loaded all images using the in-process Java-API that Confluence provides. This initially worked well and was uncomplicated to use. However while maintaining and improving compatibility with updated Confluence and third party plugin versions we found it increasingly hard to ensure that all images could be loaded correctly.
When Atlassian introduced image effects we were looking for a way to support these as well and found that the only way to do so was to load the images exactly like your browser is doing it. Furthermore there are several plugins that dynamically create images and do not store them in such a way on your Confluence server that we could load them through the Java-API.
That's why by now our first attempt to load such images is by opening a HTTP(s) request to the Confluence server (see below).
Resource Loading Explained
Whenever you export a page with an image, the following approaches are tried in sequence until one of them works:
The exporter tries several ways to open a connection with your Confluence server in order to load the image.
The exporter uses the traditional Java-API to load the image. This should always work for images simply attached to a page. Image effects are lost this way.
The default 'download-failed' image is exported.
The Connection-based Approach
Since the exporter does not know how your Confluence instance is connected to the network (think of proxies, port forwardings etc.), it tries several approaches when it occurs the first image:
The protocol (HTTP or HTTPS) and the port are guessed from the current export-request done by your browser when triggering the export.
Then the exporter tries a connection to the local address based on the guessed info.
If it works this combination is used for the current export.
If it does not work, another combination is tried.
If neither of the guessed combinations do work, the exporter tries to connect to your Confluence using the configured base url.
These guessed addresses are why you might see strange connection attempts in the Confluence log, for example HTTPS on port 80.
If neither attempt did work, the connection base attempts are disabled for the rest of the export and it falls back to the traditional way.
Firewalls
If a firewall prevents access from the server itself to its local addresses, you might run into requests timing out, leaving a warning message in the log:
2013-11-12 18:39:16,087 ERROR [pool-7-thread-3] [services.io.impl.HttpClientResourceFactory] canAccessUri Confluence Server can't access its local address:https://192.168.0.123:8090/cf/login.action
-- scrollExportCurrentPage: Example Page (ABC) | url: /cf/rest/scroll-office/1.0/export | userName: test | referer: ...
java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:152)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
...
at com.k15t.scroll.confluence.services.io.impl.HttpClientResourceFactory.canAccessUri(HttpClientResourceFactory.java:182)
at com.k15t.scroll.confluence.services.io.impl.HttpClientResourceFactory.getScheme(HttpClientResourceFactory.java:147)
at com.k15t.scroll.confluence.services.io.impl.HttpClientResourceFactory.canConnectToLocalAddress(HttpClientResourceFactory.java:122)
at com.k15t.scroll.confluence.services.io.impl.HttpClientResourceFactory.createResources(HttpClientResourceFactory.java:72)
at com.k15t.scroll.confluence.services.io.impl.ConfluenceResourceLoader.getResource(ConfluenceResourceLoader.java:41)
at com.k15t.scroll.confluence.core.builder.impl.v40.ImageBuilderV4.buildAccepted(ImageBuilderV4.java:33)
Timeouts
When establishing connections to the local Confluence instance (either using the local address or the base url) we use these connection timeouts:
while initially determining a local address to use for resource loading: 1000 milliseconds
for the actual resource loading: timeouts as configured in the General Settings
Authentication
For authenticating the image loading requests we are using a mechanism provided by Confluence: Trusted Applications. A token is generated for each request with a lifetime of one second and the permissions of the current user. This token is only added to the request when connecting against the local address or the base url.
When contacting external servers no authentication information is added to the request.
Firewall Recommendations
For resource loading to correctly work, we recommend to:
Allow requests where both the source and destination addresses are local addresses.
Allow local requests to the ports your Confluence's Tomcat connector and possible proxy (Apache, nginx) are listening to.
When using the local address, the exporter might directly try to reach the tomcat connector.
When using the base url, the exporter will usually connect with your proxy.
Block access to external servers unless your Confluence references images from those.
You can always execute the resource load test to verify if it works.