How to Configure Jetty Server to Handle Long HTTP GET Query Strings for Solr Applications


2 views

When working with Solr via Jetty, you'll eventually hit the server's default limit for HTTP GET query string length (typically around 8KB). This becomes apparent when:

  • Complex Solr queries with multiple filters and facets
  • Large "fq" (filter query) parameters
  • Applications generating dynamic queries programmatically

The symptoms manifest as connection resets or truncated queries, particularly when using PHP libraries like Apache_Solr_Service that rely on GET requests.

Jetty enforces these limits through two key parameters:

org.eclipse.jetty.server.Request.maxFormContentSize
org.eclipse.jetty.server.Request.maxFormKeys

There are three approaches to address this:

1. Jetty XML Configuration

Edit your jetty.xml or jetty-http.xml:

<Configure id="Server" class="org.eclipse.jetty.server.Server">
  <Call name="setAttribute">
    <Arg>org.eclipse.jetty.server.Request.maxFormContentSize</Arg>
    <Arg>200000</Arg> <!-- 200KB -->
  </Call>
</Configure>

2. Java System Property Approach

Add this to your Jetty startup script:

java -Dorg.eclipse.jetty.server.Request.maxFormContentSize=200000 \
     -jar start.jar

3. Programmatic Configuration

If you're embedding Jetty:

Server server = new Server();
server.setAttribute("org.eclipse.jetty.server.Request.maxFormContentSize", 200000);

Verify the changes with a simple test:

import org.eclipse.jetty.server.Server;

public class ConfigTest {
  public static void main(String[] args) {
    Server server = new Server();
    System.out.println("Max form content size: " + 
      server.getAttribute("org.eclipse.jetty.server.Request.maxFormContentSize"));
  }
}

When increasing these limits:

  • Monitor memory usage - larger buffers require more heap
  • Consider request timeout settings (setIdleTimeout)
  • Review query optimization - very long queries may indicate inefficient filters

For PHP applications, consider using Solarium (a PHP Solr client) which properly handles POST requests:

$client = new Solarium\Client($config);
$query = $client->createSelect();
$query->setQuery('*:*');
// Add your complex filters here
$resultset = $client->select($query);

When working with Solr through Jetty, you might encounter connection resets during long GET requests. This happens because Jetty enforces a default maximum length for HTTP GET query strings (typically 8KB-16KB depending on version). For Solr applications with complex queries, this limit can become problematic.

The key configuration elements controlling this behavior are:

  • HttpConfiguration: Manages general HTTP protocol settings
  • HttpConnectionFactory: Handles the actual connection parameters
  • ServerConnector: The network interface implementation

Here's how to modify your Jetty configuration (typically in jetty.xml or your startup code):

// For Jetty 9.x/10.x
Server server = new Server();

HttpConfiguration httpConfig = new HttpConfiguration();
httpConfig.setRequestHeaderSize(65536);  // Header size
httpConfig.setResponseHeaderSize(65536); // Response headers
httpConfig.setHeaderCacheSize(32768);    // Header cache

// Set the form size (affects GET query strings)
httpConfig.setFormEncodedMethods("GET,POST");
httpConfig.setFormContentSize(262144);   // 256KB limit

ServerConnector connector = new ServerConnector(server,
    new HttpConnectionFactory(httpConfig));
connector.setPort(8080);
server.addConnector(connector);

If you're using embedded Jetty with Solr:

ContextHandlerCollection contexts = new ContextHandlerCollection();
WebAppContext webapp = new WebAppContext();
webapp.setContextPath("/solr");

HttpConfiguration httpConfig = new HttpConfiguration();
httpConfig.setFormContentSize(524288); // 512KB for large queries

ServerConnector connector = new ServerConnector(server,
    new HttpConnectionFactory(httpConfig));
connector.setHost("0.0.0.0");
connector.setPort(8983);

server.setConnectors(new Connector[] { connector });
server.setHandler(contexts);

For XML configuration (jetty.xml):

<Configure id="Server" class="org.eclipse.jetty.server.Server">
  <Call name="addConnector">
    <Arg>
      <New class="org.eclipse.jetty.server.ServerConnector">
        <Arg name="server"><Ref refid="Server" /></Arg>
        <Arg name="factories">
          <Array type="org.eclipse.jetty.server.ConnectionFactory">
            <Item>
              <New class="org.eclipse.jetty.server.HttpConnectionFactory">
                <Arg name="config">
                  <New class="org.eclipse.jetty.server.HttpConfiguration">
                    <Set name="formContentSize">1048576</Set> <!-- 1MB -->
                    <Set name="requestHeaderSize">65536</Set>
                  </New>
                </Arg>
              </New>
            </Item>
          </Array>
        </Arg>
        <Set name="port">8983</Set>
      </New>
    </Arg>
  </Call>
</Configure>
  • Verify the settings took effect by checking System.out.println(httpConfig.toString())
  • Monitor Jetty logs for any "Too large" warnings
  • Consider URI encoding efficiency - some characters expand when encoded
  • For extremely large queries, consider redesigning to use POST despite client limitations

Increasing the query string limit impacts:

  • Memory usage per connection
  • Potential denial-of-service vulnerability surface
  • Network buffer requirements

Benchmark your application after making these changes to ensure stability.