diff options
-rw-r--r-- | src/http.zig | 17 | ||||
-rw-r--r-- | src/http/network_thread.zig | 2 | ||||
-rw-r--r-- | src/http_client_async.zig | 24 |
3 files changed, 38 insertions, 5 deletions
diff --git a/src/http.zig b/src/http.zig index 4f4bc131d..158092bd9 100644 --- a/src/http.zig +++ b/src/http.zig @@ -45,7 +45,6 @@ pub const MimeType = @import("./http/mime_type.zig"); const Bundler = bundler.Bundler; const Websocket = @import("./http/websocket.zig"); const js_printer = @import("./js_printer.zig"); -const SOCKET_FLAGS = os.SOCK_CLOEXEC; const watcher = @import("./watcher.zig"); threadlocal var req_headers_buf: [100]picohttp.Header = undefined; threadlocal var res_headers_buf: [100]picohttp.Header = undefined; @@ -62,6 +61,11 @@ const HTTPStatusCode = u10; const URLPath = @import("./http/url_path.zig"); const Method = @import("./http/method.zig").Method; +const SOCKET_FLAGS: u32 = if (Environment.isLinux) + os.SOCK_CLOEXEC | os.MSG_NOSIGNAL +else + os.SOCK_CLOEXEC; + pub const RequestContext = struct { request: Request, method: Method, @@ -2478,7 +2482,16 @@ pub const Server = struct { pub fn onTCPConnection(server: *Server, conn: tcp.Connection, comptime features: ConnectionFeatures) void { conn.client.setNoDelay(true) catch {}; conn.client.setQuickACK(true) catch {}; - conn.client.setLinger(1) catch {}; + + if (comptime Environment.isMac) { + // Don't crash if the client disconnects. + std.os.setsockopt( + conn.client.socket.fd, + std.os.IPPROTO_TCP, + std.os.SO_NOSIGPIPE, + mem.asBytes(&@as(u32, @boolToInt(true))), + ) catch {}; + } server.handleConnection(&conn, comptime features); } diff --git a/src/http/network_thread.zig b/src/http/network_thread.zig index 0ae0fce5f..3af6644d6 100644 --- a/src/http/network_thread.zig +++ b/src/http/network_thread.zig @@ -18,6 +18,7 @@ const CachedAddressList = struct { expire_after: u64, key: u64, index: ?u32 = null, + invalidated: bool = false, pub fn hash(name: []const u8, port: u16) u64 { var hasher = std.hash.Wyhash.init(0); hasher.update(name); @@ -35,6 +36,7 @@ const CachedAddressList = struct { } pub fn invalidate(this: *CachedAddressList) void { + this.invalidated = true; this.address_list.deinit(); _ = address_list_cached.remove(this.key); } diff --git a/src/http_client_async.zig b/src/http_client_async.zig index 8b8bd6082..192aebfbf 100644 --- a/src/http_client_async.zig +++ b/src/http_client_async.zig @@ -7,15 +7,18 @@ const Method = @import("./http/method.zig").Method; const Api = @import("./api/schema.zig").Api; const Lock = @import("./lock.zig").Lock; const HTTPClient = @This(); -const SOCKET_FLAGS = os.SOCK_CLOEXEC; const Zlib = @import("./zlib.zig"); const StringBuilder = @import("./string_builder.zig"); const AsyncIO = @import("io"); const ThreadPool = @import("thread_pool"); const boring = @import("boringssl"); - const NetworkThread = @import("network_thread"); +const SOCKET_FLAGS: u32 = if (Environment.isLinux) + os.SOCK_CLOEXEC | os.MSG_NOSIGNAL +else + os.SOCK_CLOEXEC; + const extremely_verbose = false; fn writeRequest( @@ -656,6 +659,8 @@ const AsyncSocket = struct { try_cached_index: { if (address_list.index) |i| { const address = list.addrs[i]; + if (address_list.invalidated) continue :outer; + this.connectToAddress(address) catch |err| { if (err == error.ConnectionRefused) { address_list.index = null; @@ -669,6 +674,7 @@ const AsyncSocket = struct { } for (list.addrs) |address, i| { + if (address_list.invalidated) continue :outer; this.connectToAddress(address) catch |err| { if (err == error.ConnectionRefused) continue; address_list.invalidate(); @@ -678,6 +684,8 @@ const AsyncSocket = struct { return; } + if (address_list.invalidated) continue :outer; + address_list.invalidate(); return error.ConnectionRefused; } @@ -1443,9 +1451,19 @@ pub fn connect( try connector.connect(this.url.hostname, port); var client = std.x.net.tcp.Client{ .socket = std.x.os.Socket.from(this.socket.socket.socket) }; - client.setNoDelay(true) catch {}; client.setReadBufferSize(BufferPool.len) catch {}; client.setQuickACK(true) catch {}; + + if (comptime Environment.isMac) { + // Don't crash if the server disconnects. + std.os.setsockopt( + client.socket.fd, + std.os.IPPROTO_TCP, + std.os.SO_NOSIGPIPE, + std.mem.asBytes(&@as(u32, @boolToInt(true))), + ) catch {}; + } + this.tcp_client = client; if (this.timeout > 0) { client.setReadTimeout(@truncate(u32, this.timeout / std.time.ns_per_ms)) catch {}; |