3
votes

I'm trying to use an external graphic with xslt for PDF generation. Most images are working fine but every now and again one is 'not found' despite being viewable on a web browser. Here's the error that FOP spits out:

11:29:15.653 [main] ERROR org.apache.fop.apps.FOUserAgent - Image not found. URI: http://memesvault.com/wp-content/uploads/Derp-Meme-031.jpg. (No context info available)

And here's my external-graphic section:

<xsl:variable name="mediaUrl">
    <xsl:value-of select="mediaUrl" />
</xsl:variable>
<fo:external-graphic src="url('{$mediaUrl}')"
                     height="200"
                     max-width="200"
                     content-width="scale-to-fit" />

Any idea what I'm doing wrong?

Edit: it looks like this problem is related to a server not permitting access for the automated request. Is there a way to set the User Agent's URIResolver in fop 2.1? It appears that this functionality existed in prior versions but I can't seem to find a way to do it with 2.1.

1
Could it be a server-side issue? With FOP 1.1 the error message says Error with opening URL 'http://memesvault.com/wp-content/uploads/Derp-Meme-031.jpg': Server returned HTTP response code: 403 for URL: http://memesvault.com/wp-content/uploads/Derp-Meme-031.jpg. Maybe the site is configured to refuse requests having / not having specific user agents, to avoid site scraping?lfurini
@lfurini That is very possible - I guess they changed the error code for 2.1. Do you know of a way to set a user agent within fop?cscan

1 Answers

3
votes

So the reason why this happened is because, as suggested by lfurini, the server was blocking the request because of the user agent. One can work around this by using a custom URIResolver with FOP:

URIResolverAdapter uriResolverAdapter = new URIResolverAdapter(new UserAgentUriResolver());
FopFactoryBuilder builder = new FopFactoryBuilder(URI.create("/"), uriResolverAdapter);
fopFactory = builder.build();

And here's a very simple URIResolver which adds in the user agent.

import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
import javax.xml.transform.stream.StreamSource;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;

public class UserAgentUriResolver implements URIResolver {

    private static final String USER_AGENT = "whatever";

    @Override
    public Source resolve(String href, String base) throws TransformerException {
        try {
            URL url = new URL(href);
            URLConnection connection = url.openConnection();
            connection.setRequestProperty("User-Agent", USER_AGENT);
            return new StreamSource(connection.getInputStream());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}