Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not working if the http interface is reverse-proxied by nginx with a suffix #164

Closed
ngugcx opened this issue Jun 4, 2023 · 9 comments
Closed
Labels
question Further information is requested

Comments

@ngugcx
Copy link

ngugcx commented Jun 4, 2023

Describe the bug

The http interface of my clickhouse server is reverse-proxied using nignx with suffix.
http://localhost:8123 is mapped to https://my.domain/clickhouse

This error is prompted when client.ping():
node:internal/process/promises:288
            triggerUncaughtException(err, true /* fromPromise */);
            ^

Error: Client network socket disconnected before secure TLS connection was established
    at connResetException (node:internal/errors:717:14)
    at TLSSocket.onConnectEnd (node:_tls_wrap:1595:19)
    at TLSSocket.emit (node:events:525:35)
    at endReadableNT (node:internal/streams/readable:1359:12)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
  code: 'ECONNRESET',
  path: null,
  host: 'my.domain',
  port: 443,
  localAddress: undefined
}

It's working when http://localhost:8123 is mapped to https://my.domain/ without a suffix.
And when accessing https://my.domain/clickhouse using curl, all works well too.

Steps to reproduce

  1. Setup reverse proxy using nignx, map http://localhost:8123 to https://my.domain/clickhouse
  2. execute ping()

Expected behaviour

ping() should return true.

Code example

const client = createClient({
  host: process.env.CLICKHOUSE_HOST ?? 'https://my.domain/clickhouse',
  username: process.env.CLICKHOUSE_USER ?? 'username',
  password: process.env.CLICKHOUSE_PASSWORD ?? 'password'
})

client.ping()

Environment

  • Client version: 0.0.16
  • Language version: node v18.16.0
  • OS: Windows 10

ClickHouse server

  • ClickHouse Server version: 23
@ngugcx ngugcx added the bug Something isn't working label Jun 4, 2023
@slvrtrn
Copy link
Contributor

slvrtrn commented Jun 13, 2023

I think it is because the HTTP connection is chosen instead of HTTPS: https://github.com/ClickHouse/clickhouse-js/blob/main/src/connection/connection.ts#L74-L81

if it was https://localhost:8123 then it should've been fine.

@slvrtrn slvrtrn added question Further information is requested and removed bug Something isn't working labels Jun 27, 2023
@martoche
Copy link

Hi, same problem here.

Unfortunately, when you call ClickHouseClient.query, you can't pass a pathname params down to the request function which is ultimately called.

See:
https://github.com/ClickHouse/clickhouse-js/blob/main/packages/client-common/src/client.ts#L188
https://github.com/ClickHouse/clickhouse-js/blob/main/packages/client-web/src/connection/web_connection.ts#L131

The only solution I've found (besides forking the repo) is to monkey patch the request function:

const clickhouseClient = createClient({})

// monkey-patch clickhouseClient.connection.request to force the "pathname" value
let request = clickhouseClient.connection.request
clickhouseClient.connection.request = function (arg0) {
  arg0.pathname = "/clickhouse"
  return request.apply(this, [arg0])
}

// call clickhouseClient.query

A solution would be to allow passing the pathname param in the ClickHouseClient.query function.

@slvrtrn
Copy link
Contributor

slvrtrn commented Oct 30, 2023

@martoche, you are referring to an issue with the web version; is it correct?
I think we could add an optional pathname (or similar) to the common client config itself.

For example:

const client = createClient({
  pathname: '/clickhouse' // defaults to '/'
})

// ### Node.js
// ping -> /clickhouse/ping
// other -> /clickhouse

// ### Web (no specific ping call, it just uses SELECT 1)
// all requests -> /clickhouse

@martoche
Copy link

@slvrtrn Correct, I'm using the web version.

The solution you suggest would be perfect! 😍

@slvrtrn
Copy link
Contributor

slvrtrn commented Oct 30, 2023

@martoche, as it turned out, there is an even easier way to do it, which will allow to just use the existing host config like this:

const client = createClient({
  host: 'http://proxy:8123/clickhouse' 
})

See #207

@slvrtrn
Copy link
Contributor

slvrtrn commented Oct 30, 2023

@martoche, 0.2.5 is out with the mentioned changes ^

@martoche
Copy link

Works great, thank you very much!
(issue can be closed)

@slvrtrn slvrtrn closed this as completed Oct 30, 2023
@slvrtrn
Copy link
Contributor

slvrtrn commented Oct 30, 2023

@ngugcx, please feel free to re-open if the issue in your scenario was not in HTTP vs HTTPS as described here.

@slvrtrn
Copy link
Contributor

slvrtrn commented Apr 2, 2024

@martoche, if you will upgrade to 1.0.0, please use separate pathname config option.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants