Allow configuring header size for druid requests (#5174)

* Allow configuring header size for druid requests

* fix configuration name in doc.

* add more info to docs.

* Add info to kerberos doc.
This commit is contained in:
Nishant Bangarwa 2017-12-21 08:21:40 +05:30 committed by Slim
parent dc87e4fda1
commit 494e0b79ed
8 changed files with 32 additions and 1 deletions

View File

@ -45,6 +45,8 @@ Druid uses Jetty to serve HTTP requests.
|`druid.broker.http.compressionCodec`|Compression codec the Broker uses to communicate with historical and real-time processes. May be "gzip" or "identity".|gzip| |`druid.broker.http.compressionCodec`|Compression codec the Broker uses to communicate with historical and real-time processes. May be "gzip" or "identity".|gzip|
|`druid.broker.http.readTimeout`|The timeout for data reads from historical and real-time processes.|PT15M| |`druid.broker.http.readTimeout`|The timeout for data reads from historical and real-time processes.|PT15M|
|`druid.server.http.maxQueryTimeout`|Maximum allowed value (in milliseconds) for `timeout` parameter. See [query-context](query-context.html) to know more about `timeout`. Query is rejected if the query context `timeout` is greater than this value. |Long.MAX_VALUE| |`druid.server.http.maxQueryTimeout`|Maximum allowed value (in milliseconds) for `timeout` parameter. See [query-context](query-context.html) to know more about `timeout`. Query is rejected if the query context `timeout` is greater than this value. |Long.MAX_VALUE|
|`druid.server.http.maxRequestHeaderSize`|Maximum size of a request header in bytes. Larger headers consume more memory and can make a server more vulnerable to denial of service attacks. |8 * 1024|
#### Retry Policy #### Retry Policy

View File

@ -53,6 +53,7 @@ Druid uses Jetty to serve HTTP requests.
|`druid.server.http.enableRequestLimit`|If enabled, no requests would be queued in jetty queue and "HTTP 429 Too Many Requests" error response would be sent. |false| |`druid.server.http.enableRequestLimit`|If enabled, no requests would be queued in jetty queue and "HTTP 429 Too Many Requests" error response would be sent. |false|
|`druid.server.http.defaultQueryTimeout`|Query timeout in millis, beyond which unfinished queries will be cancelled|300000| |`druid.server.http.defaultQueryTimeout`|Query timeout in millis, beyond which unfinished queries will be cancelled|300000|
|`druid.server.http.maxQueryTimeout`|Maximum allowed value (in milliseconds) for `timeout` parameter. See [query-context](query-context.html) to know more about `timeout`. Query is rejected if the query context `timeout` is greater than this value. |Long.MAX_VALUE| |`druid.server.http.maxQueryTimeout`|Maximum allowed value (in milliseconds) for `timeout` parameter. See [query-context](query-context.html) to know more about `timeout`. Query is rejected if the query context `timeout` is greater than this value. |Long.MAX_VALUE|
|`druid.server.http.maxRequestHeaderSize`|Maximum size of a request header in bytes. Larger headers consume more memory and can make a server more vulnerable to denial of service attacks.|8 * 1024|
#### Processing #### Processing

View File

@ -49,6 +49,12 @@ The syntax for mapping rules is `RULE:\[n:string](regexp)s/pattern/replacement/g
If this string matches regexp, then the s//\[g] substitution command will be run over the string. The optional g will cause the substitution to be global over the string, instead of replacing only the first match in the string. If this string matches regexp, then the s//\[g] substitution command will be run over the string. The optional g will cause the substitution to be global over the string, instead of replacing only the first match in the string.
If required, multiple rules can be be joined by newline character and specified as a String. If required, multiple rules can be be joined by newline character and specified as a String.
### Increasing HTTP Header size for large SPNEGO negotiate header
In Active Directory environment, SPNEGO token in the Authorization header includes PAC (Privilege Access Certificate) information,
which includes all security groups for the user. In some cases when the user belongs to many security groups the header to grow beyond what druid can handle by default.
In such cases, max request header size that druid can handle can be increased by setting `druid.server.http.maxRequestHeaderSize` (default 8Kb) and `druid.router.http.maxRequestBufferSize` (default 8Kb).
## Accessing Druid HTTP end points when kerberos security is enabled ## Accessing Druid HTTP end points when kerberos security is enabled
1. To access druid HTTP endpoints via curl user will need to first login using `kinit` command as follows - 1. To access druid HTTP endpoints via curl user will need to first login using `kinit` command as follows -

View File

@ -76,6 +76,8 @@ The router module uses several of the default modules in [Configuration](../conf
|`druid.router.pollPeriod`|Any ISO8601 duration.|How often to poll for new rules.|PT1M| |`druid.router.pollPeriod`|Any ISO8601 duration.|How often to poll for new rules.|PT1M|
|`druid.router.strategies`|An ordered JSON array of objects.|All custom strategies to use for routing.|[{"type":"timeBoundary"},{"type":"priority"}]| |`druid.router.strategies`|An ordered JSON array of objects.|All custom strategies to use for routing.|[{"type":"timeBoundary"},{"type":"priority"}]|
|`druid.router.avatica.balancer.type`|String representing an AvaticaConnectionBalancer name|Class to use for balancing Avatica queries across brokers|rendezvousHash| |`druid.router.avatica.balancer.type`|String representing an AvaticaConnectionBalancer name|Class to use for balancing Avatica queries across brokers|rendezvousHash|
|`druid.router.http.maxRequestBufferSize`|Maximum size of the buffer used to write requests when forwarding them to the broker. This should be set to atleast the maxHeaderSize allowed on the broker|8 * 1024|
Router Strategies Router Strategies
----------------- -----------------

View File

@ -50,6 +50,9 @@ public class DruidHttpClientConfig
@JsonProperty @JsonProperty
private String compressionCodec = DEFAULT_COMPRESSION_CODEC; private String compressionCodec = DEFAULT_COMPRESSION_CODEC;
@JsonProperty
private int requestBuffersize = 8 * 1024;
public int getNumConnections() public int getNumConnections()
{ {
return numConnections; return numConnections;
@ -74,4 +77,9 @@ public class DruidHttpClientConfig
{ {
return numRequestsQueued; return numRequestsQueued;
} }
public int getRequestBuffersize()
{
return requestBuffersize;
}
} }

View File

@ -121,6 +121,7 @@ public class JettyHttpClientModule implements Module
httpClient.setMaxConnectionsPerDestination(config.getNumConnections()); httpClient.setMaxConnectionsPerDestination(config.getNumConnections());
httpClient.setMaxRequestsQueuedPerDestination(config.getNumRequestsQueued()); httpClient.setMaxRequestsQueuedPerDestination(config.getNumRequestsQueued());
httpClient.setConnectTimeout(CLIENT_CONNECT_TIMEOUT); httpClient.setConnectTimeout(CLIENT_CONNECT_TIMEOUT);
httpClient.setRequestBufferSize(config.getRequestBuffersize());
final QueuedThreadPool pool = new QueuedThreadPool(config.getNumMaxThreads()); final QueuedThreadPool pool = new QueuedThreadPool(config.getNumMaxThreads());
pool.setName(JettyHttpClientModule.class.getSimpleName() + "-threadPool-" + pool.hashCode()); pool.setName(JettyHttpClientModule.class.getSimpleName() + "-threadPool-" + pool.hashCode());
httpClient.setExecutor(pool); httpClient.setExecutor(pool);

View File

@ -57,6 +57,9 @@ public class ServerConfig
@Min(1) @Min(1)
private long maxQueryTimeout = Long.MAX_VALUE; private long maxQueryTimeout = Long.MAX_VALUE;
@JsonProperty
private int maxRequestHeaderSize = 8 * 1024;
public int getNumThreads() public int getNumThreads()
{ {
return numThreads; return numThreads;
@ -92,6 +95,11 @@ public class ServerConfig
return maxQueryTimeout; return maxQueryTimeout;
} }
public int getMaxRequestHeaderSize()
{
return maxRequestHeaderSize;
}
@Override @Override
public boolean equals(Object o) public boolean equals(Object o)
{ {

View File

@ -218,7 +218,9 @@ public class JettyServerModule extends JerseyServletModule
if (node.isEnablePlaintextPort()) { if (node.isEnablePlaintextPort()) {
log.info("Creating http connector with port [%d]", node.getPlaintextPort()); log.info("Creating http connector with port [%d]", node.getPlaintextPort());
final ServerConnector connector = new ServerConnector(server); HttpConfiguration httpConfiguration = new HttpConfiguration();
httpConfiguration.setRequestHeaderSize(config.getMaxRequestHeaderSize());
final ServerConnector connector = new ServerConnector(server, new HttpConnectionFactory(httpConfiguration));
connector.setPort(node.getPlaintextPort()); connector.setPort(node.getPlaintextPort());
serverConnectors.add(connector); serverConnectors.add(connector);
} }
@ -264,6 +266,7 @@ public class JettyServerModule extends JerseyServletModule
httpsConfiguration.setSecureScheme("https"); httpsConfiguration.setSecureScheme("https");
httpsConfiguration.setSecurePort(node.getTlsPort()); httpsConfiguration.setSecurePort(node.getTlsPort());
httpsConfiguration.addCustomizer(new SecureRequestCustomizer()); httpsConfiguration.addCustomizer(new SecureRequestCustomizer());
httpsConfiguration.setRequestHeaderSize(config.getMaxRequestHeaderSize());
final ServerConnector connector = new ServerConnector( final ServerConnector connector = new ServerConnector(
server, server,
new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.toString()), new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.toString()),