Uploaded image for project: '{RETIRED} XWiki Scheduler Application'
  1. {RETIRED} XWiki Scheduler Application
  2. XASCH-30

XWikiServletURLFactory fails to with MalformedURLException when running behind Apache reverse proxy during jobs

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • Critical
    • 1.7
    • 1.6
    • Plugin
    • None
    • scheduler, patch, reverse proxy

    Description

      I run an instance of XWiki 1.8 in virtual mode behind an Apache server with virtual hosting and reverse proxy. The WatchListMessage job fails and sends the following in the email:

      Error number 4001 in 4: Error while parsing velocity page XWiki.WatchListMessage Wrapped Exception: Failed to evaluate content with id [XWiki.WatchListMessage]
      
      Error number 4001 in 4: Error while parsing velocity page XWiki.WatchListMessage
      Wrapped Exception: Failed to evaluate content with id [XWiki.WatchListMessage]
      com.xpn.xwiki.XWikiException: Error number 4001 in 4: Error while parsing velocity page XWiki.WatchListMessage
      Wrapped Exception: Failed to evaluate content with id [XWiki.WatchListMessage]
      	at com.xpn.xwiki.render.XWikiVelocityRenderer.evaluate(XWikiVelocityRenderer.java:114)
      	at com.xpn.xwiki.plugin.mailsender.MailSenderPlugin.sendMailFromTemplate(MailSenderPlugin.java:662)
      	at com.xpn.xwiki.plugin.watchlist.WatchListJob.sendNotificationMessage(WatchListJob.java:430)
      	at com.xpn.xwiki.plugin.watchlist.WatchListJob.execute(WatchListJob.java:181)
      	at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
      	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:529)
      
      
      Wrapped Exception:
      
      org.apache.velocity.exception.MethodInvocationException: Invocation of method 'getExternalURL' in  class com.xpn.xwiki.api.Document threw exception java.lang.NullPointerException @ XWiki.WatchListMessage[33,138]
      	at org.apache.velocity.runtime.parser.node.ASTMethod.execute(ASTMethod.java:286)
      	at org.apache.velocity.runtime.parser.node.ASTReference.execute(ASTReference.java:203)
      	at org.apache.velocity.runtime.parser.node.ASTReference.render(ASTReference.java:294)
      	at org.apache.velocity.runtime.parser.node.ASTBlock.render(ASTBlock.java:74)
      	at org.apache.velocity.runtime.directive.Foreach.render(Foreach.java:448)
      	at org.apache.velocity.runtime.parser.node.ASTDirective.render(ASTDirective.java:170)
      	at org.apache.velocity.runtime.parser.node.SimpleNode.render(SimpleNode.java:318)
      	at org.xwiki.velocity.DefaultVelocityEngine.evaluate(DefaultVelocityEngine.java:178)
      	at org.xwiki.velocity.DefaultVelocityEngine.evaluate(DefaultVelocityEngine.java:143)
      	at com.xpn.xwiki.render.XWikiVelocityRenderer.evaluate(XWikiVelocityRenderer.java:108)
      	at com.xpn.xwiki.plugin.mailsender.MailSenderPlugin.sendMailFromTemplate(MailSenderPlugin.java:662)
      	at com.xpn.xwiki.plugin.watchlist.WatchListJob.sendNotificationMessage(WatchListJob.java:430)
      	at com.xpn.xwiki.plugin.watchlist.WatchListJob.execute(WatchListJob.java:181)
      	at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
      	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:529)
      Caused by: java.lang.NullPointerException
      	at com.xpn.xwiki.doc.XWikiDocument.getExternalURL(XWikiDocument.java:957)
      	at com.xpn.xwiki.api.Document.getExternalURL(Document.java:591)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      	at java.lang.reflect.Method.invoke(Method.java:585)
      	at org.apache.velocity.util.introspection.UberspectImpl$VelMethodImpl.invoke(UberspectImpl.java:295)
      	at org.apache.velocity.runtime.parser.node.ASTMethod.execute(ASTMethod.java:245)
      	... 14 more
      

      Adding some debugging statements to the code, this is actually caused by the following snippet in XWikiServletURLFactory:

      if (context.getRequest() != null) { // necessary to the tests
          final String host = context.getRequest().getHeader("x-forwarded-host"); // apache
          // modproxy host
          if (host != null) {
              int comaind = host.indexOf(',');
              final String host1 = comaind > 0 ? host.substring(0, comaind) : host;
              if (!host1.equals("")) {
                  serverURL = new URL(context.getRequest().getScheme() + "://" + host1);
              }
          }
      }
      

      The URL constructor fails with:

      java.net.MalformedURLException: unknown protocol: null
      

      This fails because the Request in the context during job execution is an instance of XWikiServletRequest wrapping a com.xpn.xwiki.plugin.scheduler.XWikiServletRequestStub. The implementation of {[XWikiServletRequestStub#getScheme}} always returns null with the current implementation. When the stub instance in initialized in SchedulerPlugin#prepareJobStubContext, the x-forwarded-host header is set as the host in the stub request (and the stub request returns the same value for the header) if present (and it will be as Apache sets this proxying the instance).

      The attached patch fixes this bug.

      Attachments

        Activity

          People

            sdumitriu Sergiu Dumitriu
            bindul Bindul Bhowmik
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: