Skip to content

The protocol passed to the client for live reloading is not respected #763

Closed

Description

@mgol

Do you want to request a feature or report a bug?

A bug.

What is the current behavior?

Webpack Dev Server, when passed the path where the live reload server is supposed to lie, doesn't respect the protocol and instead always uses the protocol of the current page. That is, if you add 'webpack-dev-server/client?http://localhost:8888' to the entry array and run a reverse proxy that points at this server, if this proxy works on pure HTTP, it will work. But if it runs on HTTPS, the dev server will query https://localhost:8888 which is a non-existing server. You can see a lot of requests to URLs like https://localhost:8888/sockjs-node/info?t=SOMETHING which won't work.

If the current behavior is a bug, please provide the steps to reproduce.

Run:

npm install webpack@2.2.0 webpack-dev-server@2.2.0 html-webpack-plugin@2.26.0

Create the following webpack.config.js:

'use strict';

const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
	entry: [
		'webpack-dev-server/client?http://localhost:8888',
		'webpack/hot/dev-server',
		'./app.js',
	],
	output: {
		filename: '[name].bundle.js',
		publicPath: '/',
		path: '/',
	},
	plugins: [
		new HtmlWebpackPlugin(),
		new webpack.HotModuleReplacementPlugin(),
	],
};

and run:

webpack-dev-server --port 8888

Set up any reverse proxy pointing to http://localhost:8888, an example nginx config:

server {
    server_name localhost default;
    
    listen 9800;
    listen 9801 default ssl;

    ssl_certificate     ssl/server.crt;
    ssl_certificate_key ssl/server.key;
    
    charset utf-8;

    # Proxy the Websocket connection to the Webpack server.
    location /sockjs-node/ {
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_pass http://localhost:8888;
    }

    # Proxy everything to the Webpack server
    location / {
        proxy_pass http://localhost:8888;
    }
}

If you now open http://localhost:9800, everything works and you can see requests to things like http://localhost:8888/sockjs-node/info?t=SOMETHING. But open https://localhost:9801 and it suddenly queries https://localhost:8888/sockjs-node/info?t=SOMETHING which won't work.

What is the expected behavior?

It should use the provided protocol instead of using the one on the current page.

If this is a feature request, what is motivation or use case for changing the behavior?

N/A

Please mention your webpack and Operating System version.

Webpack 2.2.0, macOS 10.12.3 (16D32)

Some Angular CLI users have been hit by this issue, see e.g. angular/angular-cli#2123, in particular this comment.

Activity

  1. SpaceK33z commented on Jan 28, 2017

    @SpaceK33z
    Contributor

    Thanks for your bugreport. I think the issue is in these lines, where it will use the protocol of the current page instead of the provided one if it is https.

    After a git blame I found this was introduced in #470. As mentioned in that PR, insecure websockets don't work from https. That makes sense. I don't get why you wouldn't run the websockets also over the nginx proxy?

  2. mgol commented on Jan 28, 2017

    @mgol
    Author

    I see. It still seems weird to change the protocol in that way as it then queries a server that may not exist.

    But maybe, at the core, this can be qualified as an Angular CLI issue as that's what makes the connection use the full URL (and, hence, skip the proxy).

  3. SpaceK33z commented on Jan 28, 2017

    @SpaceK33z
    Contributor

    It still seems weird to change the protocol in that way as it then queries a server that may not exist.

    True, but since it wouldn't work anyway, we can make an assumption that the user wants to connect to a secure protocol instead. Because of this there is at least a chance that it works.

    Going to close this since we can't force a browser to connect to an insecure websocket AFAIK, thus we can never fix that in this project.

  4. Sfinx commented on Feb 7, 2017

    @Sfinx

    To SpaceK33z: The nginx is proxying the websockets here - just study these lines in nginx.conf:

    ...
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    ...

    This means that nobody use the unsecure websockets here - app (WDS at least) checks for https transport and start making calls to wss:// (nginx) and nginx successfully proxies the connection to the ws:// (webpack) in the same way as it does with http:// calls.
    This is definitely webpack bug. I think it should provide the template/rewrite option for outgoing URL generation but not blindly use the fixed local one.

    The temporary workaround is to use 443 port at the both sides - webpack and nginx.

    P.S. The simplest solution I see is to add config option something like ReverseProxyForcePort.

  5. shadowwzw commented on Mar 26, 2017

    @shadowwzw

    On the client side, you can specify an arbitrary protocol.
    https://github.com/shadowwzw/webpack-dev-server

  6. rigolepe commented on Aug 25, 2017

    @rigolepe

    I'm running against this same problemen in my development setup and I can't understand why this cannot be fixed? Just keep the protocol that is listed in:

    'webpack-dev-server/client?http://localhost:8888'

  7. jandsu commented on Oct 6, 2017

    @jandsu

    @rigolepe as explained above, keeping http rather than forcing https causes a mixed content issue

    Mixed Content: The page at 'https://foo.bar.com/' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://localhost:4200/sockjs-node/
    

    So the only option when https is involved would be to use window.location to get the host name and rely on the reverse proxy (nginx, apache, ...) to route it properly

  8. jandsu commented on Oct 10, 2017

    @jandsu

    Check out angular/angular-cli#2123 (comment) if you want a workaround for this issue.

  9. viridia commented on Oct 18, 2019

    @viridia

    I'm having the same problem - I'm working with a system that allows a local dev server, but only for javascript resources - the index.html cannot be hosted locally and must be served via https (it's part of a larger system that has a lot of infrastructure). It seems like there is no way to override the protocol for the socksjs url, which is surprising given that almost everything else can be overridden.

    I need a way to force the protocol for the socksjs connection to match the protocol of the javascript bundle, instead of picking it up from the page.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions