question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Connection.request params expected RequestOptions without querystring

See original GitHub issue

🐛 Bug Report

The typing for Connection.request (defined here) states that params is of type RequestOptions.

At runtime, I observe the following object for an indices.exists call:

{ method: 'HEAD',
  path: '/_alias/idxname',
  body: null,
  querystring: '',
  headers:
   { 'User-Agent':
      'elasticsearch-js/7.3.0 (linux 4.19.57-microsoft-standard-x64; Node.js v10.14.1)' },

But RequestOptions has no attributes body and querystring. I expected to find those in TransportRequestParams instead. But TransportRequestParams also has headers missing, so it can’t be it either (defined here).

To Reproduce

I ran into this when trying to sign requests with AWS credentials.

import { Connection as UnsignedConnection } from '@elastic/elasticsearch';
import * as AWS from 'aws-sdk';
import RequestSigner from 'aws-sdk/lib/signers/v4';
import { ClientRequest, RequestOptions, IncomingMessage } from 'http';

class AwsElasticsearchError extends Error {}


class AwsSignedConnection extends UnsignedConnection {
  public request(
    params: RequestOptions,
    callback: (err: Error | null, response: IncomingMessage | null) => void,
  ): ClientRequest {
    const signedParams = this.signParams(params);
    return super.request(signedParams, callback);
  }

  private signParams(params: any): RequestOptions {
    const region = AWS.config.region || process.env.AWS_DEFAULT_REGION;
    if (!region) {
      throw new AwsElasticsearchError('missing region configuration');
    }

    const endpoint = new AWS.Endpoint(this.url.href);
    const request = new AWS.HttpRequest(endpoint, region);

    request.method = params.method;
    request.path = params.querystring
      ? `${params.path}/?${params.querystring}`
      : params.path;
    request.body = params.body;

    request.headers = params.headers;
    request.headers.Host = endpoint.host;

    const signer = new RequestSigner(request, 'es');
    signer.addAuthorization(AWS.config.credentials, new Date());
    return request;
  }
}

export { AwsSignedConnection, UnsignedConnection, AwsElasticsearchError };

...

Expected behavior

No type errors.

Your Environment

  • node version: 10.14.1
  • @elastic/elasticsearch version: =7.3.0
  • os: Windows

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:1
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
jawadmjncommented, Apr 8, 2020

@villasv You are a rock star, It worked man. Thanks a lot 👍 😃

1reaction
villasvcommented, Apr 6, 2020

Hi @jawadmjn, here’s the code I’ve been using:

import { Connection as UnsignedConnection } from '@elastic/elasticsearch';
import * as AWS from 'aws-sdk';
import RequestSigner from 'aws-sdk/lib/signers/v4';
import { ClientRequest, RequestOptions, IncomingMessage } from 'http';

class AwsElasticsearchError extends Error {}


class AwsSignedConnection extends UnsignedConnection {
  public request(
    params: RequestOptions,
    callback: (err: Error | null, response: IncomingMessage | null) => void,
  ): ClientRequest {
    const signedParams = this.signParams(params);
    return super.request(signedParams, callback);
  }

  private signParams(params: any): RequestOptions {
    const region = AWS.config.region || process.env.AWS_DEFAULT_REGION;
    if (!region) {
      throw new AwsElasticsearchError('missing region configuration');
    }

    const endpoint = new AWS.Endpoint(this.url.href);
    const request = new AWS.HttpRequest(endpoint, region);

    request.method = params.method;
    request.path = params.querystring
      ? `${params.path}/?${params.querystring}`
      : params.path;
    request.body = params.body;

    request.headers = params.headers;
    request.headers.Host = endpoint.host;

    const signer = new RequestSigner(request, 'es');
    signer.addAuthorization(AWS.config.credentials, new Date());
    return request;
  }
}

export { AwsSignedConnection, UnsignedConnection, AwsElasticsearchError };
Read more comments on GitHub >

github_iconTop Results From Across the Web

How to pass url arguments (query string) to a HTTP request on ...
I digged into the source code and found that the second parameter of http.get expects a RequestOptionsArgs interface, which URLSearchParams does not implement....
Read more >
Request Options - Guzzle Documentation
Request options control various aspects of a request including, headers, query string parameters, timeout settings, the body of a request, and much more....
Read more >
Using Request objects — Guzzle documentation
Query string parameters of a request are owned by a request's Guzzle\Http\Query object that is accessible by calling $request->getQuery(). The Query class ...
Read more >
x-amazon-apigateway-integration.requestParameters object
For REST APIs, specifies mappings from named method request parameters to integration request parameters. The method request parameters must be defined ...
Read more >
Creating a parameter - IBM® API Connect
Parameters define variable elements of a URL path, query parameters, headers, or a request body. You can create parameters for Paths and Path...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found