Skip to content

Allow request headers in HttpInputSource in native and MSQ Ingestion#16974

Merged
abhishekagarwal87 merged 12 commits intoapache:masterfrom
pranavbhole:additionalHeaders
Sep 12, 2024
Merged

Allow request headers in HttpInputSource in native and MSQ Ingestion#16974
abhishekagarwal87 merged 12 commits intoapache:masterfrom
pranavbhole:additionalHeaders

Conversation

@pranavbhole
Copy link
Copy Markdown
Contributor

@pranavbhole pranavbhole commented Aug 28, 2024

Description

PR for adding the request headers in http input source. we can now pass the additional headers as json in both native and MSQ.
Examples below.

"inputSource" : {
      "type" : "http",
      "uris" : [ "http://example.com/foo.csv", "http://example.com/bar.csv" ],
      "httpAuthenticationUsername" : "bob",
      "httpAuthenticationPassword" : {
        "type" : "default",
        "password" : "secret"
      },
      "requestHeaders" : {
        "Accept" : "application/ndjson",
        "a" : "b"
      }
    },
INSERT INTO w000
SELECT
  TIME_PARSE("timestamp") AS __time,
  isRobot
FROM TABLE(http(
  userName => 'bob',
  password => 'secret',
  uris => ARRAY['http://example.com/foo.csv', 'http://example.com/bar.csv'],
  format => 'csv',
  headers=> '{"Accept":"application/ndjson", "a": "b" }'
  )
) EXTEND ("timestamp" VARCHAR, isRobot VARCHAR)
PARTITIONED BY HOUR

Release note

This PR has:

  • been self-reviewed.
  • added documentation for new or modified features or behaviors.
  • a release note entry in the PR description.
  • added Javadocs for most classes and all non-trivial methods. Linked related entities via Javadoc links.
  • added or updated version, license, or notice information in licenses.yaml
  • added comments explaining the "why" and the intent of the code wherever would not be obvious for an unfamiliar reader.
  • added unit tests or modified existing tests to cover new code paths, ensuring the threshold for code coverage is met.
  • added integration tests.
  • been tested in a test Druid cluster.

@pranavbhole
Copy link
Copy Markdown
Contributor Author

Adding more tests and coverage.

@pranavbhole pranavbhole changed the title Additional headers in HttpInputSource in native and MSQ Additional headers in HttpInputSource in native and MSQ (Wip) Aug 28, 2024
@abhishekagarwal87
Copy link
Copy Markdown
Contributor

Please also add a corresponding runtime property to whitelist what header keys are allowed. The default can be empty and thus no header is allowed. These free-form property maps can create security holes.

@abhishekagarwal87
Copy link
Copy Markdown
Contributor

That runtime property should be added to HttpInputSourceConfig similar to allowedProtocols

@JsonProperty("httpAuthenticationUsername") @Nullable String httpAuthenticationUsername,
@JsonProperty("httpAuthenticationPassword") @Nullable PasswordProvider httpAuthenticationPasswordProvider,
@JsonProperty(SYSTEM_FIELDS_PROPERTY) @Nullable SystemFields systemFields,
@JsonProperty("additionalHeaders") @Nullable Map<String, String> headersMap,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should rename this to requestHeaders everywhere.

Copy link
Copy Markdown
Contributor

@abhishekagarwal87 abhishekagarwal87 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor comments. Looks good otherwise.

throws IOException
{
final URLConnection urlConnection = object.toURL().openConnection();
if (requestHeaders.size() > 0) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also need to check that requestHeaders is not null.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if not, then requestHeaders is not nullable.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

private final PasswordProvider httpAuthenticationPasswordProvider;
private final SystemFields systemFields;
private final HttpInputSourceConfig config;
private final Map<String, String> headersMap;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private final Map<String, String> headersMap;
private final Map<String, String> requestHeaders;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Comment on lines +103 to +113
if (!config.getAllowedHeaders().isEmpty() && headersMap.size() > 0) {
Set<String> forbiddenHeaderSet = headersMap.keySet()
.stream()
.map(StringUtils::toLowerCase)
.filter(h -> !config.getAllowedHeaders().contains(h))
.collect(Collectors.toSet());
if (!forbiddenHeaderSet.isEmpty()) {
throw new IAE("Got forbidden headers %s, allowed headers are only %s ",
forbiddenHeaderSet, config.getAllowedHeaders());
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could be simplified to

for key in headersMap
  if (!config.allowedHeaders.contains(key))
     throw new IAE(" Header [%s] is not allowed to be set. Only headers are allowed are [%s]. You can allow the headers by changing property <insert property name> ",
                      key, config.getAllowedHeaders());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also please use InvalidInput.exception.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add one test with non-empty headers map?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added test

inputStreamPartial = HttpEntity.openInputStream(url, "", null, 5);
inputStream = HttpEntity.openInputStream(url, "", null, 0, Collections.emptyMap());
inputStreamPartial = HttpEntity.openInputStream(url, "", null, 5, Collections.emptyMap());
inputStream.skip(5);

Check notice

Code scanning / CodeQL

Ignored error status of call

Method testOpenInputStream ignores exceptional return value of InputStream.skip.
{
if (config.getAllowedHeaders().size() > 0) {
for (Map.Entry<String, String> entry : requestHeaders.entrySet()) {
if (!config.getAllowedHeaders().contains(StringUtils.toLowerCase(entry.getKey()))) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are the keys in allowedHeaders always lower case?

@pranavbhole
Copy link
Copy Markdown
Contributor Author

pranavbhole commented Sep 12, 2024 via email

@abhishekagarwal87 abhishekagarwal87 changed the title Additional headers in HttpInputSource in native and MSQ (Wip) Allow request headers in HttpInputSource in native and MSQ Ingestion Sep 12, 2024
@abhishekagarwal87 abhishekagarwal87 merged commit a95397e into apache:master Sep 12, 2024
@pranavbhole pranavbhole mentioned this pull request Sep 12, 2024
10 tasks
cecemei pushed a commit to cecemei/druid that referenced this pull request Sep 12, 2024
…pache#16974)

Support for adding the request headers in http input source. we can now pass the additional headers as json in both native and MSQ.
@adarshsanjeev adarshsanjeev added this to the 32.0.0 milestone Jan 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants