aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/http.zig17
-rw-r--r--src/http/network_thread.zig2
-rw-r--r--src/http_client_async.zig24
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 {};