I just started trying to get silverstripe 2.4.5 working under Quercus after a few tweaks with url rewriting and how urls are passed to silverstripe the only problem seems to be how some of the statics are returned from Object::get_static which prevents forms and full database builds from working.
I did need to add the following code to sapphire to get things to even begin to load
sapphire/core/Core.php to correct a problem with interfaces not being loaded or found
// load interfaces manually for some reason they are being missed by the manifest builder and autoload
$_interface_list = array(
'core/i18nEntityProvider.php' ,
'core/model/CurrentPageIdentifier.php' ,
'core/control/NestedController.php',
'core/model/DataObjectInterface.php',
'core/model/HiddenClass.php',
'core/model/fieldtypes/CompositeDBField.php',
'security/PermissionProvider.php'
);
foreach($_interface_list as $_interface_class) {
require_once($_interface_class);
}
sapphire/main.php to get the stuff from my custom rewrite rules in. I added it before the IIS check
if(isset($_SERVER['SERVER_SOFTWARE']) && (strpos($_SERVER['SERVER_SOFTWARE'],'Apache PHP Quercus') !== false)) {
$_quercus_url = $_quercus_request->getAttribute('SS_URL');
$_quercus_qs = $_quercus_request->getAttribute('SS_QS');
$_SERVER['REQUEST_URI'] = $_quercus_url;
$url = $_quercus_url;
if (!empty($_quercus_qs)) {
parse_str($_quercus_qs,$_GET);
if ($_GET) $_REQUEST = array_merge((array)$_REQUEST, (array)$_GET);
}
}
I was wondering if anybody else has done any work in this area.
FYI: this is my setup
jetty-8.0.4.v20111024 from http://jetty.codehaus.org/jetty/
urlrewrite filter verson 4.0 from http://code.google.com/p/urlrewritefilter/
quercus-4.0.18 from http://www.caucho.com
Servlet Mapping for Quercus from web.xml:
<servlet>
<servlet-name>Quercus Servlet</servlet-name>
<servlet-class>com.caucho.quercus.servlet.QuercusServlet</servlet-class>
<init-param>
<param-name>script-encoding</param-name>
<param-value>ISO-8859-1</param-value>
</init-param>
<init-param>
<param-name>ini-file</param-name>
<param-value>WEB-INF/php.ini</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Quercus Servlet</servlet-name>
<url-pattern>*.php</url-pattern>
</servlet-mapping>
UrlRewriteFilter config from web.xml
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
<init-param>
<param-name>logLevel</param-name>
<param-value>DEBUG</param-value>
</init-param>
<init-param>
<param-name>modRewriteConf</param-name>
<param-value>false</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
urlrewrite.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 4.0//EN"
"http://tuckey.org/res/dtds/urlrewrite4.0.dtd">
<urlrewrite>
<rule>
<note>
The rule means that requests to /test/status/ will be redirected to /rewrite-status
the url will be rewritten.
</note>
<from>/test/status/</from>
<to type="redirect">%{context-path}/rewrite-status</to>
</rule>
<!-- invoke special rule for silverstripe -->
<class-rule class="org.silverstripe.web.filters.SSPrettyUrlRewriteRule" />
<outbound-rule>
<note>
The outbound-rule specifies that when response.encodeURL is called (if you are using JSTL c:url)
the url /rewrite-status will be rewritten to /test/status/.
The above rule and this outbound-rule means that end users should never see the
url /rewrite-status only /test/status/ both in thier location bar and in hyperlinks
in your pages.
</note>
<from>/rewrite-status</from>
<to>/test/status/</to>
</outbound-rule>
</urlrewrite>
Custom Java Rules (I couldn't get the regular ones working properly for silverstripe)
#1) SSPrettyUrlRewriteMatch.java
package org.silverstripe.web.filters;
/**
* Created by IntelliJ IDEA.
* User: smathews
* Date: 1/24/12
* Time: 10:18 PM
*/
import org.tuckey.web.filters.urlrewrite.extend.RewriteMatch;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class SSPrettyUrlRewriteMatch extends RewriteMatch {
public boolean execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String qs = request.getQueryString();
String url = request.getRequestURI();
// this these as server variables so php can see them
request.setAttribute("SS_QS",qs);
request.setAttribute("SS_URL",url);
String forwardto = "/sapphire/main.php";
RequestDispatcher rd = request.getRequestDispatcher(forwardto);
rd.forward(request, response);
return true;
}
}
#1) SSPrettyUrlRewriteRule.java
package org.silverstripe.web.filters;
/**
* Created by IntelliJ IDEA.
* User: smathews
* Date: 1/24/12
* Time: 10:01 PM
*/
import org.tuckey.web.filters.urlrewrite.extend.RewriteRule;
import org.tuckey.web.filters.urlrewrite.extend.RewriteMatch;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
public class SSPrettyUrlRewriteRule extends RewriteRule {
private boolean isFile(String filename) {
boolean exists = false;
try {
File f = new File(filename);
exists = f.isFile() && f.exists();
} catch(Exception e) {
exists = false;
}
return exists;
}
public RewriteMatch matches(HttpServletRequest request, HttpServletResponse response) {
// we don't want to match request from
if (request.getRequestURI().startsWith("/sapphire/main.php")) return null;
// ignore all image types
if (request.getRequestURI().startsWith(".ico")) return null;
if (request.getRequestURI().startsWith(".png")) return null;
if (request.getRequestURI().startsWith(".gif")) return null;
if (request.getRequestURI().startsWith(".mov")) return null;
if (request.getRequestURI().startsWith(".jpg")) return null;
String fileName = request.getServletContext().getRealPath(request.getRequestURI());
// we don't process any request if there is an actual file
if (this.isFile(fileName)) return null;
return new SSPrettyUrlRewriteMatch();
}
}