Skip to content
This repository has been archived by the owner on Dec 18, 2018. It is now read-only.

Kestrel + Proxying ( nginx/browsersync/etc ) = No response #636

Closed
amcdnl opened this issue Feb 17, 2016 · 37 comments
Closed

Kestrel + Proxying ( nginx/browsersync/etc ) = No response #636

amcdnl opened this issue Feb 17, 2016 · 37 comments
Labels
Milestone

Comments

@amcdnl
Copy link

amcdnl commented Feb 17, 2016

When using Krestel with Browser-sync my requests never respond. If I launch IISExpress and proxy the requests it works.

var gulp = require('gulp');
var browserSync = require('browser-sync');
var proxyMiddleware = require('http-proxy-middleware');
var historyApiFallback = require('connect-history-api-fallback');
var path = require('path');
var dnx = require('gulp-dnx');

gulp.task('start', ['web', 'api']);

gulp.task('web', function(done){
  var apiProxy = proxyMiddleware('/api', { 
    target: options.baseUrl,
    ws: true,
    changeOrigin: true
  });

  browserSync({
    files: ['wwwroot/index.html'],
    server: {
      baseDir: ['wwwroot'],
      middleware: [ apiProxy, historyApiFallback() ]
    }
  }, done);
});

var options = {
  cwd: path.resolve(path.join(__dirname, '..', '..', 'API')),
  baseUrl: 'http://localhost:5000/',
  restore: false,
  build: false,
  run: true
};

gulp.task('api', dnx('web', options));

Many others have had this issue too:

@amcdnl amcdnl changed the title Krestel + Browser-Sync = No response Kestrel + Browser-Sync = No response Feb 17, 2016
@amcdnl
Copy link
Author

amcdnl commented Feb 17, 2016

@CesarBS lets move the convo here.

@cesarblum
Copy link
Contributor

What version of Kestrel are you using?

@amcdnl
Copy link
Author

amcdnl commented Feb 17, 2016

RC1

@cesarblum cesarblum self-assigned this Feb 17, 2016
@replete
Copy link

replete commented Feb 24, 2016

I've been having this exact problem and been pulling my hair out trying to fix it.

IT seems like Kestrel in this context is sending as chunked but doesn't seem to send the last 0-length chunk (which would end the data).

Closing kestrel while browserSync is waiting kills the connection and the browser starts trying to use what it did download.

@amcdnl
Copy link
Author

amcdnl commented Feb 24, 2016

@replete Use WebListener, its a known bug that is fixed already in master but not published

@replete
Copy link

replete commented Feb 25, 2016

@amcdnl Thanks, I did figure this out on my own in the end.

As an aside, do you personally feel that it is anywhere near a good time for someone to start moving from an (incomplete) RC1 project to RC2?

@amcdnl
Copy link
Author

amcdnl commented Feb 25, 2016

@replete its not for the light hearted....

  • most third-party packages don't support it yet
  • obvs issues like ^^
  • I think RC2 is gonna have some major changes too so moving target.

@muratg muratg added this to the 1.0.0-rc2 milestone Mar 14, 2016
@cesarblum
Copy link
Contributor

@amcdnl Have you tried this with the latest Kestrel from the dev feed?

@amcdnl
Copy link
Author

amcdnl commented Mar 23, 2016

@CesarBS I have not, I actually dropped browsersync recently too.

If you wanna do a quick test, you can grab this gulp plugin I wrote and drop in browsersync: https://github.com/Swimlane/gulp-dotnet

@muratg muratg modified the milestones: 1.0.0, 1.0.0-rc2 Apr 1, 2016
@MarkPieszak
Copy link

@amcdnl I recently had to give up on this (for the time being as well).
Somehow getting webpack with browserSync & Kestrel to play together seems impossible... :(

I'm guessing it's because Kestrel & Node just don't play well together yet??

@amcdnl
Copy link
Author

amcdnl commented Apr 4, 2016

@MarkPieszak you can use weblistener. Its not just Node, I tried nginx too and had same issue. Its basically anything other than a browser ( proxy in these cases ) receiving the requests. This is claimed to be fixed in latest but have not personally tried.

@MarkPieszak
Copy link

How do you set up weblistener in .NET core? I see the options for IISExpress & Web (kestrel) but nothing for weblistener.

Oh I'll have to try it again today to see if it's actually fixed!

@amcdnl
Copy link
Author

amcdnl commented Apr 4, 2016

In Project.json

  "commands": {
    "web": "Microsoft.AspNet.Server.Kestrel",
    "weblistener": "Microsoft.AspNet.Server.WebListener"
  },

@MarkPieszak
Copy link

Oh excellent, so it all works with that? That's amazing I'll just use that for the time being then. :)
Thanks @amcdnl

@muratg muratg modified the milestones: Backlog, 1.0.0 May 18, 2016
@peterblazejewicz
Copy link

@CesarBS
I'm using RC2 dotnet bits on OS X and have this problem with public dotnet build. Can I somehow help with solving the problem?
Thanks!

@amcdnl
Copy link
Author

amcdnl commented May 23, 2016

@CesarBS I updated Friday to RC2 and can concur with @peterblazejewicz regarding issues proxying. I also tried the suggestion to proxy_set_header Connection keep-alive and had no luck.

I'm running a NGINX server that serves my requests from http://localhost:8080/. API requests ( /api/* ) are routed to Krestel on http://localhost:5000 of the same box. The requests waits till NGINX times out and returns successfully.

NGINX config

# Re-route api requests
location ~ ^/(api) {
  rewrite ^/api/(.*) /$1 break;
  proxy_pass http://localhost:5000;

  proxy_set_header Connection keep-alive;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Host $host;
  proxy_cache_bypass $http_upgrade;

  proxy_buffering             off;
  proxy_redirect              off;
  proxy_connect_timeout       "10s";
  proxy_send_timeout          "20m";
  proxy_read_timeout          "20m";
}

Versions

  • nginx 8.1.0
  • windows 10

I also have a rule setup to proxy http://localhost:5000 on my mac to my windows box and it is not reachable at all but if I try the same URL on windows it is.

@muratg why is this marked backlog in 1.0.0? This is HIGH priority, you can not deploy in a real world scenario with this not working! I see some other issues related saying to set the proxy_set_header Connection keep-alive but thats not really a fix given you can't always set that with other tools ( ie mac hosts redirection ).

Related Issues

@dmikov
Copy link

dmikov commented May 23, 2016

+1 Very noticable

@muratg muratg modified the milestones: 1.0.0, Backlog May 23, 2016
@amcdnl amcdnl changed the title Kestrel + Browser-Sync = No response Kestrel + Proxying ( nginx/browsersync/etc ) = No response May 23, 2016
@halter73
Copy link
Member

@amcdnl @dmikov If you change proxy_pass http://localhost:5000; to proxy_pass http://127.0.0.1:5000; does that fix the issue. We think this might be caused by #231.

@cesarblum
Copy link
Contributor

cesarblum commented May 23, 2016

I've figured out what's wrong. Right now, Kestrel will only listen on IPv4 when you bind to localhost. If you look at the network traffic when reproing this issue, you'll see nginx trying to establish an IPv6 connection with Kestrel, failing, waiting for proxy_connect_timeout, then establishing an IPv4 connection and completing the request.

The delay after the IPv6 failure is out of our control (Kestrel doesn't even see the connection attempt). @Tratcher has pointed out to me that this is a known issue with winsock - it takes a long time for it to realize a connection failure on IPv6 before trying IPv4.

I'm going to fix #231 so binding to localhost will not cause this issue because Kestrel will be listening on both IPv4 and IPv6. For now you can workaround by either listening on both 127.0.0.1 and ::1, or by proxying to 127.0.0.1 as @halter73 pointed above.

@amcdnl
Copy link
Author

amcdnl commented May 23, 2016

@halter73 Yes, that seems to work.

@CesarBS So the solution is to turn off IP6 until this is fixed officially?

@cesarblum
Copy link
Contributor

@amcdnl If you bind Kestrel to both http://127.0.0.1 and http://[::1], it should work when nginx uses proxy_pass http://localhost.

@amcdnl
Copy link
Author

amcdnl commented May 23, 2016

@CesarBS I'm trying to get Parrallels proxying to work too reason I ask.

I tried disabling IPv6 in that and no dice. It doesn't even respond when I try http://127.0.0.1:5000/ or http://localhost:5000/ either.

p

I would probably be safe to assume this would not work with docker proxying too?

@mikeharder
Copy link
Contributor

@amcdnl: You typically want to configure Kestrel to accept external requests when running inside a VM or container. URLs http://127.0.0.1 and http://localhost only accept requests from localhost. Use a URL like http://+ to listen for external requests.

@mikeharder
Copy link
Contributor

To summarize, there are two valid workarounds for nginx proxying to Kestrel in RC2:

Workaround nginx proxy_pass Kestrel UseUrls()
IPv4-only http://127.0.0.1 http://127.0.0.1
IPv4 and IPv6 http://localhost http://127.0.0.1;http://[::1]

@amcdnl
Copy link
Author

amcdnl commented May 23, 2016

@mikeharder Can you provide an example of the config to make it accept external requests?

@mikeharder
Copy link
Contributor

Accept external requests on both IPv4 and IPv6, port 5000:

var host = new WebHostBuilder()
    .UseUrls("http://+:5000")
    .UseKestrel()

@amcdnl
Copy link
Author

amcdnl commented May 23, 2016

@mikeharder Works...Thanks for your help!

@peterblazejewicz
Copy link

@mikeharder Thanks!

@amcdnl
Copy link
Author

amcdnl commented May 24, 2016

@mikeharder shouldn't that be the default?

@amcdnl amcdnl closed this as completed May 24, 2016
@halter73
Copy link
Member

@amcdnl Rejecting external requests by default and when "localhost" is specified was a design decision we made to make Kestrel more secure by default: aspnet/Announcements#80

I do think that Kestrel should bind to both the IPv4 and IPv6 loopback intervaces which is tracked by #231 and fixed by #870.

@gtarsia
Copy link

gtarsia commented May 26, 2016

I'm having the same problem with browser-sync and kestrel.
Tried using this without success:
.UseUrls("http://127.0.0.1;http://[::1]")
I'm using kestrel dev branch.

Is there another workaround to try for this?

@peterblazejewicz
Copy link

I've used this with RC2 relase + BS 2.*

@gtarsia
Copy link

gtarsia commented May 26, 2016

@peterblazejewicz that doesn't work for me either, sorry.
I'm on Windows 10 (10586.318 build). Visual Studio 2015 Update 2, dotnet 1.0.0-preview1-002702, browser-sync 2.12.8, and tried with the RC2 release this time.

@peterblazejewicz
Copy link

@erandros
The above solution definitely works for me (i've just tried at work):

$ gulp serve --reload --open
[08:40:47] Using gulpfile C:\dev\recipes\src\gulp-dotnet-browser-sync\StarterWeb\gulpfile.js
[08:40:47] Starting 'dotnet:hosting'...
[08:40:47] Finished 'dotnet:hosting' after 3.17 ms
[08:40:47] Starting 'serve'...
watching for changes ...
[BS] Proxying: http://127.0.0.1:5000
[BS] Access URLs:
 -----------------------------------
       Local: http://localhost:3000
    External: http://10.6.3.101:3000
 -----------------------------------
          UI: http://localhost:3001
 UI External: http://10.6.3.101:3001
 -----------------------------------
[DotNetWatcher] info: Running dotnet with the following arguments: run
[DotNetWatcher] info: dotnet process id: 12580
Project StarterWeb (.NETCoreApp,Version=v1.0) was previously compiled. Skipping compilation.
Hosting environment: Development
Content root path: C:\dev\recipes\src\gulp-dotnet-browser-sync\StarterWeb\
Now listening on: http://+:5000
Application started. Press Ctrl+C to shut down.

I'm using +:5000 to setup Kestrel urls in above example but 'localhost:5000' and 'localhost:3000' when configuring BS

@ghost
Copy link

ghost commented May 30, 2016

@peterblazejewicz
I don't get it ...
this is what I did:

  1. Microsoft.AspNetCore.Server.WebListene => in project.json
  2. "web": "Microsoft.AspNetCore.Hosting --server Microsoft.AspNetCore.Server.WebListener --server.urls http://+:5000" => in project.json
  3. I don't know where to put this:
    var host = new WebHostBuilder() .UseUrls("http://+:5000") .UseKestrel()
  4. this is the command line for BS:

browser-sync start --proxy "http://localhost:5000" --files "wwwroot/css/*.css"

(I'm not sure for the proxy)

@halter73
Copy link
Member

halter73 commented Jun 2, 2016

@okuz Are you trying to use RC2? We no longer support adding commands (like the "web" command) to the project.json.

"web": "Microsoft.AspNetCore.Hosting --server Microsoft.AspNetCore.Server.WebListener --server.urls http://+:5000" makes it look like your trying to use WebListener, but I assume it doesn't matter to you what server you use.

var host = new WebHostBuilder() .UseUrls("http://+:5000") .UseKestrel() belongs in your Program.Main. You should also have something like .UseContentRoot(Directory.GetCurrentDirectory()).UseStartup<Startup>().Build(); after .UseKestrel(), and add "buildOptions": { "emitEntryPoint": true ... to your project.json.

I would see if you can get this sample running first: https://github.com/aspnet/cli-samples/tree/master/HelloMvc

I would also make sure that everything is working without a proxy trying anything else like browser-sync.

@gtarsia
Copy link

gtarsia commented Sep 19, 2016

I checked again today, and browser-sync started working with Kestrel.
I'm running dotnet core 1.0 with Kestrel 1.0.0.
browser-sync is 2.10.0 (probably could update it, though).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests