Skip to content

Commit b9b9400

Browse files
committed
Optionally require a valid content type for all rest requests with content (#22691)
This change adds a strict mode for xcontent parsing on the rest layer. The strict mode will be off by default for 5.x and in a separate commit will be enabled by default for 6.0. The strict mode, which can be enabled by setting `http.content_type.required: true` in 5.x, will require that all incoming rest requests have a valid and supported content type header before the request is dispatched. In the non-strict mode, the Content-Type header will be inspected and if it is not present or not valid, we will continue with auto detection of content like we have done previously. The content type header is parsed to the matching XContentType value with the only exception being for plain text requests. This value is then passed on with the content bytes so that we can reduce the number of places where we need to auto-detect the content type. As part of this, many transport requests and builders were updated to provide methods that accepted the XContentType along with the bytes and the methods that would rely on auto-detection have been deprecated. In the non-strict mode, deprecation warnings are issued whenever a request with body doesn't provide the Content-Type header. See #19388
1 parent 1925985 commit b9b9400

File tree

255 files changed

+3844
-1053
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

255 files changed

+3844
-1053
lines changed

client/benchmark/src/main/java/org/elasticsearch/client/benchmark/transport/TransportClientBenchmark.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.elasticsearch.client.transport.TransportClient;
2929
import org.elasticsearch.common.settings.Settings;
3030
import org.elasticsearch.common.transport.InetSocketTransportAddress;
31+
import org.elasticsearch.common.xcontent.XContentType;
3132
import org.elasticsearch.index.query.QueryBuilders;
3233
import org.elasticsearch.plugin.noop.NoopPlugin;
3334
import org.elasticsearch.plugin.noop.action.bulk.NoopBulkAction;
@@ -80,7 +81,7 @@ private static final class TransportBulkRequestExecutor implements BulkRequestEx
8081
public boolean bulkIndex(List<String> bulkData) {
8182
NoopBulkRequestBuilder builder = NoopBulkAction.INSTANCE.newRequestBuilder(client);
8283
for (String bulkItem : bulkData) {
83-
builder.add(new IndexRequest(indexName, typeName).source(bulkItem.getBytes(StandardCharsets.UTF_8)));
84+
builder.add(new IndexRequest(indexName, typeName).source(bulkItem.getBytes(StandardCharsets.UTF_8), XContentType.JSON));
8485
}
8586
BulkResponse bulkResponse;
8687
try {

client/client-benchmark-noop-api-plugin/src/main/java/org/elasticsearch/plugin/noop/action/bulk/NoopBulkRequestBuilder.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.elasticsearch.client.ElasticsearchClient;
3434
import org.elasticsearch.common.Nullable;
3535
import org.elasticsearch.common.unit.TimeValue;
36+
import org.elasticsearch.common.xcontent.XContentType;
3637

3738
public class NoopBulkRequestBuilder extends ActionRequestBuilder<BulkRequest, BulkResponse, NoopBulkRequestBuilder>
3839
implements WriteRequestBuilder<NoopBulkRequestBuilder> {
@@ -95,17 +96,17 @@ public NoopBulkRequestBuilder add(UpdateRequestBuilder request) {
9596
/**
9697
* Adds a framed data in binary format
9798
*/
98-
public NoopBulkRequestBuilder add(byte[] data, int from, int length) throws Exception {
99-
request.add(data, from, length, null, null);
99+
public NoopBulkRequestBuilder add(byte[] data, int from, int length, XContentType xContentType) throws Exception {
100+
request.add(data, from, length, null, null, xContentType);
100101
return this;
101102
}
102103

103104
/**
104105
* Adds a framed data in binary format
105106
*/
106-
public NoopBulkRequestBuilder add(byte[] data, int from, int length, @Nullable String defaultIndex, @Nullable String defaultType)
107-
throws Exception {
108-
request.add(data, from, length, defaultIndex, defaultType);
107+
public NoopBulkRequestBuilder add(byte[] data, int from, int length, @Nullable String defaultIndex, @Nullable String defaultType,
108+
XContentType xContentType) throws Exception {
109+
request.add(data, from, length, defaultIndex, defaultType, xContentType);
109110
return this;
110111
}
111112

client/client-benchmark-noop-api-plugin/src/main/java/org/elasticsearch/plugin/noop/action/bulk/RestNoopBulkAction.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ public RestChannelConsumer prepareRequest(final RestRequest request, final NodeC
7373
}
7474
bulkRequest.timeout(request.paramAsTime("timeout", BulkShardRequest.DEFAULT_TIMEOUT));
7575
bulkRequest.setRefreshPolicy(request.param("refresh"));
76-
bulkRequest.add(request.content(), defaultIndex, defaultType, defaultRouting, defaultFields, null, defaultPipeline, null, true);
76+
bulkRequest.add(request.content(), defaultIndex, defaultType, defaultRouting, defaultFields, null, defaultPipeline, null, true,
77+
request.getXContentType());
7778

7879
// short circuit the call to the transport layer
7980
return channel -> {

core/src/main/java/org/elasticsearch/action/admin/cluster/repositories/put/PutRepositoryRequest.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,14 +142,28 @@ public PutRepositoryRequest settings(Settings.Builder settings) {
142142
/**
143143
* Sets the repository settings.
144144
*
145-
* @param source repository settings in json, yaml or properties format
145+
* @param source repository settings in json or yaml format
146146
* @return this request
147+
* @deprecated use {@link #settings(String, XContentType)} to avoid content type auto-detection
147148
*/
149+
@Deprecated
148150
public PutRepositoryRequest settings(String source) {
149151
this.settings = Settings.builder().loadFromSource(source).build();
150152
return this;
151153
}
152154

155+
/**
156+
* Sets the repository settings.
157+
*
158+
* @param source repository settings in json or yaml format
159+
* @param xContentType the content type of the source
160+
* @return this request
161+
*/
162+
public PutRepositoryRequest settings(String source, XContentType xContentType) {
163+
this.settings = Settings.builder().loadFromSource(source, xContentType).build();
164+
return this;
165+
}
166+
153167
/**
154168
* Sets the repository settings.
155169
*
@@ -160,7 +174,7 @@ public PutRepositoryRequest settings(Map<String, Object> source) {
160174
try {
161175
XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON);
162176
builder.map(source);
163-
settings(builder.string());
177+
settings(builder.string(), builder.contentType());
164178
} catch (IOException e) {
165179
throw new ElasticsearchGenerationException("Failed to generate [" + source + "]", e);
166180
}

core/src/main/java/org/elasticsearch/action/admin/cluster/repositories/put/PutRepositoryRequestBuilder.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.elasticsearch.action.support.master.AcknowledgedRequestBuilder;
2323
import org.elasticsearch.client.ElasticsearchClient;
2424
import org.elasticsearch.common.settings.Settings;
25+
import org.elasticsearch.common.xcontent.XContentType;
2526

2627
import java.util.Map;
2728

@@ -89,16 +90,30 @@ public PutRepositoryRequestBuilder setSettings(Settings.Builder settings) {
8990
}
9091

9192
/**
92-
* Sets the repository settings in Json, Yaml or properties format
93+
* Sets the repository settings in Json or Yaml format
9394
*
9495
* @param source repository settings
9596
* @return this builder
97+
* @deprecated use {@link #setSettings(String, XContentType)} instead to avoid content type auto detection
9698
*/
99+
@Deprecated
97100
public PutRepositoryRequestBuilder setSettings(String source) {
98101
request.settings(source);
99102
return this;
100103
}
101104

105+
/**
106+
* Sets the repository settings in Json or Yaml format
107+
*
108+
* @param source repository settings
109+
* @param xContentType the contenty type of the source
110+
* @return this builder
111+
*/
112+
public PutRepositoryRequestBuilder setSettings(String source, XContentType xContentType) {
113+
request.settings(source, xContentType);
114+
return this;
115+
}
116+
102117
/**
103118
* Sets the repository settings
104119
*

core/src/main/java/org/elasticsearch/action/admin/cluster/settings/ClusterUpdateSettingsRequest.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,22 @@ public ClusterUpdateSettingsRequest transientSettings(Settings.Builder settings)
8383

8484
/**
8585
* Sets the source containing the transient settings to be updated. They will not survive a full cluster restart
86+
* @deprecated use {@link #transientSettings(String, XContentType)} to avoid content type detection
8687
*/
88+
@Deprecated
8789
public ClusterUpdateSettingsRequest transientSettings(String source) {
8890
this.transientSettings = Settings.builder().loadFromSource(source).build();
8991
return this;
9092
}
9193

94+
/**
95+
* Sets the source containing the transient settings to be updated. They will not survive a full cluster restart
96+
*/
97+
public ClusterUpdateSettingsRequest transientSettings(String source, XContentType xContentType) {
98+
this.transientSettings = Settings.builder().loadFromSource(source, xContentType).build();
99+
return this;
100+
}
101+
92102
/**
93103
* Sets the transient settings to be updated. They will not survive a full cluster restart
94104
*/
@@ -97,7 +107,7 @@ public ClusterUpdateSettingsRequest transientSettings(Map source) {
97107
try {
98108
XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON);
99109
builder.map(source);
100-
transientSettings(builder.string());
110+
transientSettings(builder.string(), builder.contentType());
101111
} catch (IOException e) {
102112
throw new ElasticsearchGenerationException("Failed to generate [" + source + "]", e);
103113
}
@@ -122,12 +132,22 @@ public ClusterUpdateSettingsRequest persistentSettings(Settings.Builder settings
122132

123133
/**
124134
* Sets the source containing the persistent settings to be updated. They will get applied cross restarts
135+
* @deprecated use {@link #persistentSettings(String, XContentType)} to avoid content type detection
125136
*/
137+
@Deprecated
126138
public ClusterUpdateSettingsRequest persistentSettings(String source) {
127139
this.persistentSettings = Settings.builder().loadFromSource(source).build();
128140
return this;
129141
}
130142

143+
/**
144+
* Sets the source containing the persistent settings to be updated. They will get applied cross restarts
145+
*/
146+
public ClusterUpdateSettingsRequest persistentSettings(String source, XContentType xContentType) {
147+
this.persistentSettings = Settings.builder().loadFromSource(source, xContentType).build();
148+
return this;
149+
}
150+
131151
/**
132152
* Sets the persistent settings to be updated. They will get applied cross restarts
133153
*/
@@ -136,7 +156,7 @@ public ClusterUpdateSettingsRequest persistentSettings(Map source) {
136156
try {
137157
XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON);
138158
builder.map(source);
139-
persistentSettings(builder.string());
159+
persistentSettings(builder.string(), builder.contentType());
140160
} catch (IOException e) {
141161
throw new ElasticsearchGenerationException("Failed to generate [" + source + "]", e);
142162
}

core/src/main/java/org/elasticsearch/action/admin/cluster/settings/ClusterUpdateSettingsRequestBuilder.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.elasticsearch.action.support.master.AcknowledgedRequestBuilder;
2323
import org.elasticsearch.client.ElasticsearchClient;
2424
import org.elasticsearch.common.settings.Settings;
25+
import org.elasticsearch.common.xcontent.XContentType;
2526

2627
import java.util.Map;
2728

@@ -52,12 +53,22 @@ public ClusterUpdateSettingsRequestBuilder setTransientSettings(Settings.Builder
5253

5354
/**
5455
* Sets the source containing the transient settings to be updated. They will not survive a full cluster restart
56+
* @deprecated use {@link #setTransientSettings(String, XContentType)} to avoid content type detection
5557
*/
58+
@Deprecated
5659
public ClusterUpdateSettingsRequestBuilder setTransientSettings(String settings) {
5760
request.transientSettings(settings);
5861
return this;
5962
}
6063

64+
/**
65+
* Sets the source containing the transient settings to be updated. They will not survive a full cluster restart
66+
*/
67+
public ClusterUpdateSettingsRequestBuilder setTransientSettings(String settings, XContentType xContentType) {
68+
request.transientSettings(settings, xContentType);
69+
return this;
70+
}
71+
6172
/**
6273
* Sets the transient settings to be updated. They will not survive a full cluster restart
6374
*/
@@ -84,12 +95,22 @@ public ClusterUpdateSettingsRequestBuilder setPersistentSettings(Settings.Builde
8495

8596
/**
8697
* Sets the source containing the persistent settings to be updated. They will get applied cross restarts
98+
* @deprecated use {@link #setPersistentSettings(String, XContentType)} to avoid content type detection
8799
*/
100+
@Deprecated
88101
public ClusterUpdateSettingsRequestBuilder setPersistentSettings(String settings) {
89102
request.persistentSettings(settings);
90103
return this;
91104
}
92105

106+
/**
107+
* Sets the source containing the persistent settings to be updated. They will get applied cross restarts
108+
*/
109+
public ClusterUpdateSettingsRequestBuilder setPersistentSettings(String settings, XContentType xContentType) {
110+
request.persistentSettings(settings, xContentType);
111+
return this;
112+
}
113+
93114
/**
94115
* Sets the persistent settings to be updated. They will get applied cross restarts
95116
*/

core/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotRequest.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,18 +289,34 @@ public CreateSnapshotRequest settings(Settings.Builder settings) {
289289
}
290290

291291
/**
292-
* Sets repository-specific snapshot settings in JSON, YAML or properties format
292+
* Sets repository-specific snapshot settings in JSON or YAML format
293293
* <p>
294294
* See repository documentation for more information.
295295
*
296296
* @param source repository-specific snapshot settings
297297
* @return this request
298+
* @deprecated use {@link #settings(String, XContentType)} to avoid content type detection
298299
*/
300+
@Deprecated
299301
public CreateSnapshotRequest settings(String source) {
300302
this.settings = Settings.builder().loadFromSource(source).build();
301303
return this;
302304
}
303305

306+
/**
307+
* Sets repository-specific snapshot settings in JSON or YAML format
308+
* <p>
309+
* See repository documentation for more information.
310+
*
311+
* @param source repository-specific snapshot settings
312+
* @param xContentType the content type of the source
313+
* @return this request
314+
*/
315+
public CreateSnapshotRequest settings(String source, XContentType xContentType) {
316+
this.settings = Settings.builder().loadFromSource(source, xContentType).build();
317+
return this;
318+
}
319+
304320
/**
305321
* Sets repository-specific snapshot settings.
306322
* <p>
@@ -313,7 +329,7 @@ public CreateSnapshotRequest settings(Map<String, Object> source) {
313329
try {
314330
XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON);
315331
builder.map(source);
316-
settings(builder.string());
332+
settings(builder.string(), builder.contentType());
317333
} catch (IOException e) {
318334
throw new ElasticsearchGenerationException("Failed to generate [" + source + "]", e);
319335
}

core/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/create/CreateSnapshotRequestBuilder.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.elasticsearch.action.support.master.MasterNodeOperationRequestBuilder;
2424
import org.elasticsearch.client.ElasticsearchClient;
2525
import org.elasticsearch.common.settings.Settings;
26+
import org.elasticsearch.common.xcontent.XContentType;
2627

2728
import java.util.Map;
2829

@@ -147,12 +148,28 @@ public CreateSnapshotRequestBuilder setSettings(Settings.Builder settings) {
147148
*
148149
* @param source repository-specific snapshot settings
149150
* @return this builder
151+
* @deprecated use {@link #setSettings(String, XContentType)} to avoid content type detection
150152
*/
153+
@Deprecated
151154
public CreateSnapshotRequestBuilder setSettings(String source) {
152155
request.settings(source);
153156
return this;
154157
}
155158

159+
/**
160+
* Sets repository-specific snapshot settings in YAML or JSON format
161+
* <p>
162+
* See repository documentation for more information.
163+
*
164+
* @param source repository-specific snapshot settings
165+
* @param xContentType the content type of the source
166+
* @return this builder
167+
*/
168+
public CreateSnapshotRequestBuilder setSettings(String source, XContentType xContentType) {
169+
request.settings(source, xContentType);
170+
return this;
171+
}
172+
156173
/**
157174
* Sets repository-specific snapshot settings.
158175
* <p>

0 commit comments

Comments
 (0)