all: replace deprecated io/ioutil calls

The io/ioutil package's features were moved to
the io and os packages in Go 1.16.

x/net depends on Go 1.18. Drop ioutil calls,
so gopls doesn't warn about them.

Change-Id: Ibdb576d94f250808ae285aa142e2fd41e7e9afc9
Reviewed-on: https://go-review.googlesource.com/c/net/+/586244
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
diff --git a/bpf/instructions_test.go b/bpf/instructions_test.go
index 69b25c5..f5111c6 100644
--- a/bpf/instructions_test.go
+++ b/bpf/instructions_test.go
@@ -6,7 +6,7 @@
 
 import (
 	"fmt"
-	"io/ioutil"
+	"os"
 	"reflect"
 	"strconv"
 	"strings"
@@ -98,7 +98,7 @@
 	}
 	t.Logf("Assembled program is %d instructions long", len(out))
 
-	bs, err := ioutil.ReadFile(allInstructionsExpected)
+	bs, err := os.ReadFile(allInstructionsExpected)
 	if err != nil {
 		t.Fatalf("reading %s: %s", allInstructionsExpected, err)
 	}
diff --git a/context/ctxhttp/ctxhttp_test.go b/context/ctxhttp/ctxhttp_test.go
index d585f11..ace33f2 100644
--- a/context/ctxhttp/ctxhttp_test.go
+++ b/context/ctxhttp/ctxhttp_test.go
@@ -9,7 +9,6 @@
 import (
 	"context"
 	"io"
-	"io/ioutil"
 	"net/http"
 	"net/http/httptest"
 	"testing"
@@ -49,7 +48,7 @@
 		t.Fatal(err)
 	}
 	defer res.Body.Close()
-	slurp, err := ioutil.ReadAll(res.Body)
+	slurp, err := io.ReadAll(res.Body)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -102,7 +101,7 @@
 	done := make(chan struct{})
 
 	go func() {
-		b, err := ioutil.ReadAll(resp.Body)
+		b, err := io.ReadAll(resp.Body)
 		if len(b) != 0 || err == nil {
 			t.Errorf(`Read got (%q, %v); want ("", error)`, b, err)
 		}
diff --git a/dns/dnsmessage/message_test.go b/dns/dnsmessage/message_test.go
index 2555305..1fa93e6 100644
--- a/dns/dnsmessage/message_test.go
+++ b/dns/dnsmessage/message_test.go
@@ -7,7 +7,7 @@
 import (
 	"bytes"
 	"fmt"
-	"io/ioutil"
+	"os"
 	"path/filepath"
 	"reflect"
 	"strings"
@@ -1611,7 +1611,7 @@
 		// Could use something complex like go/build or x/tools/go/packages,
 		// but there's no reason for "fmt" to appear (in quotes) in the source
 		// otherwise, so just use a simple substring search.
-		data, err := ioutil.ReadFile(file)
+		data, err := os.ReadFile(file)
 		if err != nil {
 			t.Fatal(err)
 		}
diff --git a/html/atom/gen.go b/html/atom/gen.go
index 5d85c60..1e249d1 100644
--- a/html/atom/gen.go
+++ b/html/atom/gen.go
@@ -14,7 +14,6 @@
 	"flag"
 	"fmt"
 	"go/format"
-	"io/ioutil"
 	"math/rand"
 	"os"
 	"sort"
@@ -48,7 +47,7 @@
 		fmt.Fprintln(os.Stderr, err)
 		os.Exit(1)
 	}
-	if err := ioutil.WriteFile(name, b, 0644); err != nil {
+	if err := os.WriteFile(name, b, 0644); err != nil {
 		fmt.Fprintln(os.Stderr, err)
 		os.Exit(1)
 	}
diff --git a/html/charset/charset_test.go b/html/charset/charset_test.go
index b71eb43..c2f6244 100644
--- a/html/charset/charset_test.go
+++ b/html/charset/charset_test.go
@@ -7,7 +7,8 @@
 import (
 	"bytes"
 	"encoding/xml"
-	"io/ioutil"
+	"io"
+	"os"
 	"runtime"
 	"strings"
 	"testing"
@@ -17,7 +18,7 @@
 
 func transformString(t transform.Transformer, s string) (string, error) {
 	r := transform.NewReader(strings.NewReader(s), t)
-	b, err := ioutil.ReadAll(r)
+	b, err := io.ReadAll(r)
 	return string(b), err
 }
 
@@ -142,7 +143,7 @@
 	}
 
 	for _, tc := range sniffTestCases {
-		content, err := ioutil.ReadFile("testdata/" + tc.filename)
+		content, err := os.ReadFile("testdata/" + tc.filename)
 		if err != nil {
 			t.Errorf("%s: error reading file: %v", tc.filename, err)
 			continue
@@ -163,7 +164,7 @@
 	}
 
 	for _, tc := range sniffTestCases {
-		content, err := ioutil.ReadFile("testdata/" + tc.filename)
+		content, err := os.ReadFile("testdata/" + tc.filename)
 		if err != nil {
 			t.Errorf("%s: error reading file: %v", tc.filename, err)
 			continue
@@ -175,14 +176,14 @@
 			continue
 		}
 
-		got, err := ioutil.ReadAll(r)
+		got, err := io.ReadAll(r)
 		if err != nil {
 			t.Errorf("%s: error reading from charset.NewReader: %v", tc.filename, err)
 			continue
 		}
 
 		e, _ := Lookup(tc.want)
-		want, err := ioutil.ReadAll(transform.NewReader(bytes.NewReader(content), e.NewDecoder()))
+		want, err := io.ReadAll(transform.NewReader(bytes.NewReader(content), e.NewDecoder()))
 		if err != nil {
 			t.Errorf("%s: error decoding with hard-coded charset name: %v", tc.filename, err)
 			continue
diff --git a/html/parse_test.go b/html/parse_test.go
index 019333d..aa91f4c 100644
--- a/html/parse_test.go
+++ b/html/parse_test.go
@@ -10,7 +10,6 @@
 	"errors"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"os"
 	"path/filepath"
 	"runtime"
@@ -477,7 +476,7 @@
 }
 
 func BenchmarkParser(b *testing.B) {
-	buf, err := ioutil.ReadFile("testdata/go1.html")
+	buf, err := os.ReadFile("testdata/go1.html")
 	if err != nil {
 		b.Fatalf("could not read testdata/go1.html: %v", err)
 	}
diff --git a/html/token_test.go b/html/token_test.go
index 8b0d5aa..a36d112 100644
--- a/html/token_test.go
+++ b/html/token_test.go
@@ -7,7 +7,7 @@
 import (
 	"bytes"
 	"io"
-	"io/ioutil"
+	"os"
 	"reflect"
 	"runtime"
 	"strings"
@@ -680,7 +680,7 @@
 				}
 			}
 			// Anything tokenized along with untokenized input or data left in the reader.
-			assembled, err := ioutil.ReadAll(io.MultiReader(&tokenized, bytes.NewReader(z.Buffered()), r))
+			assembled, err := io.ReadAll(io.MultiReader(&tokenized, bytes.NewReader(z.Buffered()), r))
 			if err != nil {
 				t.Errorf("%s: ReadAll: %v", test.desc, err)
 				continue tests
@@ -866,7 +866,7 @@
 )
 
 func benchmarkTokenizer(b *testing.B, level int) {
-	buf, err := ioutil.ReadFile("testdata/go1.html")
+	buf, err := os.ReadFile("testdata/go1.html")
 	if err != nil {
 		b.Fatalf("could not read testdata/go1.html: %v", err)
 	}
diff --git a/http2/h2c/h2c_test.go b/http2/h2c/h2c_test.go
index 038cbc3..3e78f29 100644
--- a/http2/h2c/h2c_test.go
+++ b/http2/h2c/h2c_test.go
@@ -9,7 +9,6 @@
 	"crypto/tls"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"log"
 	"net"
 	"net/http"
@@ -68,7 +67,7 @@
 	if err != nil {
 		t.Fatal(err)
 	}
-	_, err = ioutil.ReadAll(resp.Body)
+	_, err = io.ReadAll(resp.Body)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -162,7 +161,7 @@
 		t.Fatal(err)
 	}
 	defer resp.Body.Close()
-	_, err = ioutil.ReadAll(resp.Body)
+	_, err = io.ReadAll(resp.Body)
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/http2/hpack/gen.go b/http2/hpack/gen.go
index 21a4198..0efa8e5 100644
--- a/http2/hpack/gen.go
+++ b/http2/hpack/gen.go
@@ -10,7 +10,6 @@
 	"bytes"
 	"fmt"
 	"go/format"
-	"io/ioutil"
 	"os"
 	"sort"
 
@@ -176,7 +175,7 @@
 		fmt.Fprintln(os.Stderr, err)
 		os.Exit(1)
 	}
-	if err := ioutil.WriteFile(name, b, 0644); err != nil {
+	if err := os.WriteFile(name, b, 0644); err != nil {
 		fmt.Fprintln(os.Stderr, err)
 		os.Exit(1)
 	}
diff --git a/http2/http2_test.go b/http2/http2_test.go
index a16774b..b7c946b 100644
--- a/http2/http2_test.go
+++ b/http2/http2_test.go
@@ -8,7 +8,6 @@
 	"bytes"
 	"flag"
 	"fmt"
-	"io/ioutil"
 	"net/http"
 	"os"
 	"path/filepath"
@@ -266,7 +265,7 @@
 			return nil
 		}
 
-		contents, err := ioutil.ReadFile(path)
+		contents, err := os.ReadFile(path)
 		if err != nil {
 			t.Fatal(err)
 		}
diff --git a/http2/pipe_test.go b/http2/pipe_test.go
index 67562a9..326b94d 100644
--- a/http2/pipe_test.go
+++ b/http2/pipe_test.go
@@ -8,7 +8,6 @@
 	"bytes"
 	"errors"
 	"io"
-	"io/ioutil"
 	"testing"
 )
 
@@ -85,7 +84,7 @@
 	io.WriteString(p, body)
 	a := errors.New("test error")
 	p.CloseWithError(a)
-	all, err := ioutil.ReadAll(p)
+	all, err := io.ReadAll(p)
 	if string(all) != body {
 		t.Errorf("read bytes = %q; want %q", all, body)
 	}
@@ -112,7 +111,7 @@
 	io.WriteString(p, "foo")
 	a := errors.New("test err")
 	p.BreakWithError(a)
-	all, err := ioutil.ReadAll(p)
+	all, err := io.ReadAll(p)
 	if string(all) != "" {
 		t.Errorf("read bytes = %q; want empty string", all)
 	}
diff --git a/http2/server_push_test.go b/http2/server_push_test.go
index cda8f43..e90b288 100644
--- a/http2/server_push_test.go
+++ b/http2/server_push_test.go
@@ -8,7 +8,6 @@
 	"errors"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"net/http"
 	"reflect"
 	"runtime"
@@ -40,7 +39,7 @@
 		if r.Body == nil {
 			return fmt.Errorf("nil Body")
 		}
-		if buf, err := ioutil.ReadAll(r.Body); err != nil || len(buf) != 0 {
+		if buf, err := io.ReadAll(r.Body); err != nil || len(buf) != 0 {
 			return fmt.Errorf("ReadAll(Body)=%q,%v, want '',nil", buf, err)
 		}
 		return nil
diff --git a/http2/server_test.go b/http2/server_test.go
index 9cdd482..9b7ccf7 100644
--- a/http2/server_test.go
+++ b/http2/server_test.go
@@ -14,7 +14,6 @@
 	"flag"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"log"
 	"net"
 	"net/http"
@@ -38,7 +37,7 @@
 		return os.Stderr
 	}
 
-	return ioutil.Discard
+	return io.Discard
 }
 
 type safeBuffer struct {
@@ -896,7 +895,7 @@
 		if r.ContentLength != wantContentLength {
 			t.Errorf("ContentLength = %v; want %d", r.ContentLength, wantContentLength)
 		}
-		all, err := ioutil.ReadAll(r.Body)
+		all, err := io.ReadAll(r.Body)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -917,7 +916,7 @@
 		if r.ContentLength != wantContentLength {
 			t.Errorf("ContentLength = %v; want %d", r.ContentLength, wantContentLength)
 		}
-		all, err := ioutil.ReadAll(r.Body)
+		all, err := io.ReadAll(r.Body)
 		if err == nil {
 			t.Fatalf("expected an error (%q) reading from the body. Successfully read %q instead.",
 				wantReadError, all)
@@ -2992,7 +2991,7 @@
 		if !reflect.DeepEqual(r.Trailer, wantTrailer) {
 			t.Errorf("initial Trailer = %v; want %v", r.Trailer, wantTrailer)
 		}
-		slurp, err := ioutil.ReadAll(r.Body)
+		slurp, err := io.ReadAll(r.Body)
 		if string(slurp) != testBody {
 			t.Errorf("read body %q; want %q", slurp, testBody)
 		}
@@ -3188,7 +3187,7 @@
 		// Consume the (empty) body from th peer before replying, otherwise
 		// the server will sometimes (depending on scheduling) send the peer a
 		// a RST_STREAM with the CANCEL error code.
-		if n, err := io.Copy(ioutil.Discard, r.Body); n != 0 || err != nil {
+		if n, err := io.Copy(io.Discard, r.Body); n != 0 || err != nil {
 			b.Errorf("Copy error; got %v, %v; want 0, nil", n, err)
 		}
 		io.WriteString(w, msg)
@@ -3252,7 +3251,7 @@
 		// Consume the (empty) body from th peer before replying, otherwise
 		// the server will sometimes (depending on scheduling) send the peer a
 		// a RST_STREAM with the CANCEL error code.
-		if n, err := io.Copy(ioutil.Discard, r.Body); n != 0 || err != nil {
+		if n, err := io.Copy(io.Discard, r.Body); n != 0 || err != nil {
 			b.Errorf("Copy error; got %v, %v; want 0, nil", n, err)
 		}
 		for i := 0; i < b.N; i += 1 {
@@ -3533,7 +3532,7 @@
 	b.ReportAllocs()
 	const msg = "Hello, world."
 	st := newServerTester(b, func(w http.ResponseWriter, r *http.Request) {
-		n, err := io.Copy(ioutil.Discard, r.Body)
+		n, err := io.Copy(io.Discard, r.Body)
 		if err != nil || n > 0 {
 			b.Errorf("Read %d bytes, error %v; want 0 bytes.", n, err)
 		}
@@ -3565,7 +3564,7 @@
 	b.ReportAllocs()
 	const msg = "Hello, world."
 	st := newServerTester(b, func(w http.ResponseWriter, r *http.Request) {
-		n, err := io.Copy(ioutil.Discard, r.Body)
+		n, err := io.Copy(io.Discard, r.Body)
 		if err != nil || n > 0 {
 			b.Errorf("Read %d bytes, error %v; want 0 bytes.", n, err)
 		}
@@ -3639,7 +3638,7 @@
 			EndStream:     true,
 			EndHeaders:    true,
 		})
-		go io.Copy(ioutil.Discard, c2)
+		go io.Copy(io.Discard, c2)
 		<-handlerDone
 	}()
 	const testString = "my custom ConnectionState"
@@ -4001,7 +4000,7 @@
 
 func TestServer_Rejects_TooSmall(t *testing.T) {
 	testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {
-		ioutil.ReadAll(r.Body)
+		io.ReadAll(r.Body)
 		return nil
 	}, func(st *serverTester) {
 		st.writeHeaders(HeadersFrameParam{
diff --git a/http2/transport_test.go b/http2/transport_test.go
index 7c53f7b..d875338 100644
--- a/http2/transport_test.go
+++ b/http2/transport_test.go
@@ -16,7 +16,6 @@
 	"fmt"
 	"io"
 	"io/fs"
-	"io/ioutil"
 	"log"
 	"math/rand"
 	"net"
@@ -206,7 +205,7 @@
 	if res.ProtoMajor != 2 {
 		t.Fatal("proto not h2c")
 	}
-	body, err := ioutil.ReadAll(res.Body)
+	body, err := io.ReadAll(res.Body)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -263,7 +262,7 @@
 		if res.TLS == nil {
 			t.Errorf("%d: Response.TLS = nil; want non-nil", i)
 		}
-		slurp, err := ioutil.ReadAll(res.Body)
+		slurp, err := io.ReadAll(res.Body)
 		if err != nil {
 			t.Errorf("%d: Body read: %v", i, err)
 		} else if string(slurp) != body {
@@ -304,7 +303,7 @@
 			t.Fatal(err)
 		}
 		defer res.Body.Close()
-		slurp, err := ioutil.ReadAll(res.Body)
+		slurp, err := io.ReadAll(res.Body)
 		if err != nil {
 			t.Fatalf("Body read: %v", err)
 		}
@@ -520,7 +519,7 @@
 		}
 		defer res.Body.Close()
 		ts.CloseClientConnections()
-		_, err = ioutil.ReadAll(res.Body)
+		_, err = io.ReadAll(res.Body)
 		if err == nil {
 			errCh <- errors.New("expected error from res.Body.Read")
 			return
@@ -650,7 +649,7 @@
 	gotc := make(chan reqInfo, 1)
 	ts := newTestServer(t,
 		func(w http.ResponseWriter, r *http.Request) {
-			slurp, err := ioutil.ReadAll(r.Body)
+			slurp, err := io.ReadAll(r.Body)
 			if err != nil {
 				gotc <- reqInfo{err: err}
 			} else {
@@ -774,7 +773,7 @@
 	if err != nil {
 		t.Fatal(err)
 	}
-	slurp, err := ioutil.ReadAll(res.Body)
+	slurp, err := io.ReadAll(res.Body)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -901,7 +900,7 @@
 	c := &http.Client{Transport: tr}
 
 	pr, pw := io.Pipe()
-	req, err := http.NewRequest("PUT", ts.URL, ioutil.NopCloser(pr))
+	req, err := http.NewRequest("PUT", ts.URL, io.NopCloser(pr))
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -1402,11 +1401,11 @@
 		func(w http.ResponseWriter, r *http.Request) {
 			// Consume body & force client to send
 			// trailers before writing response.
-			// ioutil.ReadAll returns non-nil err for
+			// io.ReadAll returns non-nil err for
 			// requests that attempt to send greater than
 			// maxHeaderListSize bytes of trailers, since
 			// those requests generate a stream reset.
-			ioutil.ReadAll(r.Body)
+			io.ReadAll(r.Body)
 			r.Body.Close()
 		},
 		func(ts *httptest.Server) {
@@ -1746,7 +1745,7 @@
 	if err != nil {
 		t.Fatal(err)
 	}
-	if _, err := ioutil.ReadAll(res.Body); err != nil {
+	if _, err := io.ReadAll(res.Body); err != nil {
 		t.Fatal(err)
 	}
 	defer res.Body.Close()
@@ -1808,7 +1807,7 @@
 				t.Error(err)
 				return
 			}
-			if _, err := ioutil.ReadAll(res.Body); err != nil {
+			if _, err := io.ReadAll(res.Body); err != nil {
 				t.Error(err)
 				return
 			}
@@ -2178,7 +2177,7 @@
 // the first Read call's gzip.NewReader returning an error.
 func TestGzipReader_DoubleReadCrash(t *testing.T) {
 	gz := &gzipReader{
-		body: ioutil.NopCloser(strings.NewReader("0123456789")),
+		body: io.NopCloser(strings.NewReader("0123456789")),
 	}
 	var buf [1]byte
 	n, err1 := gz.Read(buf[:])
@@ -2197,7 +2196,7 @@
 	w.Write([]byte("012345679"))
 	w.Close()
 	gz := &gzipReader{
-		body: ioutil.NopCloser(&body),
+		body: io.NopCloser(&body),
 	}
 	var buf [1]byte
 	n, err := gz.Read(buf[:])
@@ -2379,7 +2378,7 @@
 		if err != nil {
 			t.Fatal(err)
 		}
-		n, err := io.Copy(ioutil.Discard, res.Body)
+		n, err := io.Copy(io.Discard, res.Body)
 		res.Body.Close()
 		if n != bodySize || err != nil {
 			t.Fatalf("req#%d: Copy = %d, %v; want %d, nil", i, n, err, bodySize)
@@ -2892,7 +2891,7 @@
 // before we've determined that the ClientConn is usable.
 func TestRoundTripDoesntConsumeRequestBodyEarly(t *testing.T) {
 	const body = "foo"
-	req, _ := http.NewRequest("POST", "http://foo.com/", ioutil.NopCloser(strings.NewReader(body)))
+	req, _ := http.NewRequest("POST", "http://foo.com/", io.NopCloser(strings.NewReader(body)))
 	cc := &ClientConn{
 		closed:      true,
 		reqHeaderMu: make(chan struct{}, 1),
@@ -2901,7 +2900,7 @@
 	if err != errClientConnUnusable {
 		t.Fatalf("RoundTrip = %v; want errClientConnUnusable", err)
 	}
-	slurp, err := ioutil.ReadAll(req.Body)
+	slurp, err := io.ReadAll(req.Body)
 	if err != nil {
 		t.Errorf("ReadAll = %v", err)
 	}
@@ -2961,7 +2960,7 @@
 	if err != nil {
 		t.Fatal(err)
 	}
-	if _, err = io.Copy(ioutil.Discard, res.Body); err == nil {
+	if _, err = io.Copy(io.Discard, res.Body); err == nil {
 		t.Fatal("unexpected success")
 	}
 
@@ -2969,7 +2968,7 @@
 	if err != nil {
 		t.Fatal(err)
 	}
-	slurp, err := ioutil.ReadAll(res.Body)
+	slurp, err := io.ReadAll(res.Body)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -2994,7 +2993,7 @@
 	if err != nil {
 		t.Fatal(err)
 	}
-	if _, err = io.Copy(ioutil.Discard, resp.Body); err != nil {
+	if _, err = io.Copy(io.Discard, resp.Body); err != nil {
 		t.Fatalf("error reading response body: %v", err)
 	}
 	if err := resp.Body.Close(); err != nil {
@@ -3970,7 +3969,7 @@
 	case closeAtHeaders, closeAtBody:
 		if closeMode == closeAtBody {
 			go close(sendBody)
-			if _, err := io.Copy(ioutil.Discard, res.Body); err == nil {
+			if _, err := io.Copy(io.Discard, res.Body); err == nil {
 				t.Error("expected a Copy error, got nil")
 			}
 		}
@@ -4021,7 +4020,7 @@
 func TestTransportUsesGetBodyWhenPresent(t *testing.T) {
 	calls := 0
 	someBody := func() io.ReadCloser {
-		return struct{ io.ReadCloser }{ioutil.NopCloser(bytes.NewReader(nil))}
+		return struct{ io.ReadCloser }{io.NopCloser(bytes.NewReader(nil))}
 	}
 	req := &http.Request{
 		Body: someBody(),
@@ -4566,7 +4565,7 @@
 		if got, want := r.Header.Get("Big"), filler; got != want {
 			t.Errorf(`r.Header.Get("Big") = %q, want %q`, got, want)
 		}
-		b, err := ioutil.ReadAll(r.Body)
+		b, err := io.ReadAll(r.Body)
 		if err != nil {
 			t.Errorf("error reading request body: %v", err)
 		}
diff --git a/internal/iana/gen.go b/internal/iana/gen.go
index 0fe65d8..b4470ba 100644
--- a/internal/iana/gen.go
+++ b/internal/iana/gen.go
@@ -16,7 +16,6 @@
 	"fmt"
 	"go/format"
 	"io"
-	"io/ioutil"
 	"net/http"
 	"os"
 	"strconv"
@@ -69,7 +68,7 @@
 		fmt.Fprintln(os.Stderr, err)
 		os.Exit(1)
 	}
-	if err := ioutil.WriteFile("const.go", b, 0644); err != nil {
+	if err := os.WriteFile("const.go", b, 0644); err != nil {
 		fmt.Fprintln(os.Stderr, err)
 		os.Exit(1)
 	}
diff --git a/internal/socket/socket_test.go b/internal/socket/socket_test.go
index faba106..44c196b 100644
--- a/internal/socket/socket_test.go
+++ b/internal/socket/socket_test.go
@@ -9,7 +9,6 @@
 import (
 	"bytes"
 	"fmt"
-	"io/ioutil"
 	"net"
 	"os"
 	"os/exec"
@@ -446,7 +445,7 @@
 	if runtime.Compiler == "gccgo" {
 		t.Skip("skipping race test when built with gccgo")
 	}
-	dir, err := ioutil.TempDir("", "testrace")
+	dir, err := os.MkdirTemp("", "testrace")
 	if err != nil {
 		t.Fatalf("failed to create temp directory: %v", err)
 	}
@@ -463,7 +462,7 @@
 	for i, test := range tests {
 		t.Run(fmt.Sprintf("test %d", i), func(t *testing.T) {
 			src := filepath.Join(dir, fmt.Sprintf("test%d.go", i))
-			if err := ioutil.WriteFile(src, []byte(test), 0644); err != nil {
+			if err := os.WriteFile(src, []byte(test), 0644); err != nil {
 				t.Fatalf("failed to write file: %v", err)
 			}
 			t.Logf("%s run -race %s", goBinary, src)
diff --git a/ipv4/gen.go b/ipv4/gen.go
index 121c764..f0182be 100644
--- a/ipv4/gen.go
+++ b/ipv4/gen.go
@@ -17,7 +17,6 @@
 	"fmt"
 	"go/format"
 	"io"
-	"io/ioutil"
 	"net/http"
 	"os"
 	"os/exec"
@@ -61,7 +60,7 @@
 	case "freebsd", "linux":
 		zsys = "zsys_" + runtime.GOOS + "_" + runtime.GOARCH + ".go"
 	}
-	if err := ioutil.WriteFile(zsys, b, 0644); err != nil {
+	if err := os.WriteFile(zsys, b, 0644); err != nil {
 		return err
 	}
 	return nil
@@ -100,7 +99,7 @@
 	if err != nil {
 		return err
 	}
-	if err := ioutil.WriteFile("iana.go", b, 0644); err != nil {
+	if err := os.WriteFile("iana.go", b, 0644); err != nil {
 		return err
 	}
 	return nil
diff --git a/ipv6/gen.go b/ipv6/gen.go
index 2973dff..590568a 100644
--- a/ipv6/gen.go
+++ b/ipv6/gen.go
@@ -17,7 +17,6 @@
 	"fmt"
 	"go/format"
 	"io"
-	"io/ioutil"
 	"net/http"
 	"os"
 	"os/exec"
@@ -61,7 +60,7 @@
 	case "freebsd", "linux":
 		zsys = "zsys_" + runtime.GOOS + "_" + runtime.GOARCH + ".go"
 	}
-	if err := ioutil.WriteFile(zsys, b, 0644); err != nil {
+	if err := os.WriteFile(zsys, b, 0644); err != nil {
 		return err
 	}
 	return nil
@@ -100,7 +99,7 @@
 	if err != nil {
 		return err
 	}
-	if err := ioutil.WriteFile("iana.go", b, 0644); err != nil {
+	if err := os.WriteFile("iana.go", b, 0644); err != nil {
 		return err
 	}
 	return nil
diff --git a/nettest/conntest.go b/nettest/conntest.go
index 615f498..4297d40 100644
--- a/nettest/conntest.go
+++ b/nettest/conntest.go
@@ -8,7 +8,6 @@
 	"bytes"
 	"encoding/binary"
 	"io"
-	"io/ioutil"
 	"math/rand"
 	"net"
 	"runtime"
@@ -173,7 +172,7 @@
 // testRacyWrite tests that it is safe to mutate the input Write buffer
 // immediately after cancelation has occurred.
 func testRacyWrite(t *testing.T, c1, c2 net.Conn) {
-	go chunkedCopy(ioutil.Discard, c2)
+	go chunkedCopy(io.Discard, c2)
 
 	var wg sync.WaitGroup
 	defer wg.Wait()
@@ -200,7 +199,7 @@
 
 // testReadTimeout tests that Read timeouts do not affect Write.
 func testReadTimeout(t *testing.T, c1, c2 net.Conn) {
-	go chunkedCopy(ioutil.Discard, c2)
+	go chunkedCopy(io.Discard, c2)
 
 	c1.SetReadDeadline(aLongTimeAgo)
 	_, err := c1.Read(make([]byte, 1024))
diff --git a/nettest/nettest.go b/nettest/nettest.go
index 3656c3c..37e6dcb 100644
--- a/nettest/nettest.go
+++ b/nettest/nettest.go
@@ -8,7 +8,6 @@
 import (
 	"errors"
 	"fmt"
-	"io/ioutil"
 	"net"
 	"os"
 	"os/exec"
@@ -226,7 +225,7 @@
 	if runtime.GOOS == "darwin" {
 		dir = "/tmp"
 	}
-	f, err := ioutil.TempFile(dir, "go-nettest")
+	f, err := os.CreateTemp(dir, "go-nettest")
 	if err != nil {
 		return "", err
 	}
diff --git a/publicsuffix/gen.go b/publicsuffix/gen.go
index 21c1914..7f7d08d 100644
--- a/publicsuffix/gen.go
+++ b/publicsuffix/gen.go
@@ -26,7 +26,6 @@
 	"fmt"
 	"go/format"
 	"io"
-	"io/ioutil"
 	"net/http"
 	"os"
 	"regexp"
@@ -298,7 +297,7 @@
 	if err != nil {
 		return err
 	}
-	return ioutil.WriteFile(filename, b, 0644)
+	return os.WriteFile(filename, b, 0644)
 }
 
 func gitCommit() (sha, date string, retErr error) {
@@ -310,7 +309,7 @@
 		return "", "", fmt.Errorf("bad GET status for %s: %s", gitCommitURL, res.Status)
 	}
 	defer res.Body.Close()
-	b, err := ioutil.ReadAll(res.Body)
+	b, err := io.ReadAll(res.Body)
 	if err != nil {
 		return "", "", err
 	}
diff --git a/webdav/file_test.go b/webdav/file_test.go
index e875c13..3af53fd 100644
--- a/webdav/file_test.go
+++ b/webdav/file_test.go
@@ -9,7 +9,6 @@
 	"encoding/xml"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"os"
 	"path"
 	"path/filepath"
@@ -518,7 +517,7 @@
 		t.Skip("see golang.org/issue/11453")
 	}
 
-	td, err := ioutil.TempDir("", "webdav-test")
+	td, err := os.MkdirTemp("", "webdav-test")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -758,7 +757,7 @@
 			if err != nil {
 				t.Fatalf("test case #%d %q: OpenFile: %v", i, tc, err)
 			}
-			gotBytes, err := ioutil.ReadAll(g)
+			gotBytes, err := io.ReadAll(g)
 			if err != nil {
 				t.Fatalf("test case #%d %q: ReadAll: %v", i, tc, err)
 			}
diff --git a/webdav/webdav_test.go b/webdav/webdav_test.go
index 5b9133b..deb60fb 100644
--- a/webdav/webdav_test.go
+++ b/webdav/webdav_test.go
@@ -9,7 +9,6 @@
 	"errors"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"net/http"
 	"net/http/httptest"
 	"net/url"
@@ -256,7 +255,7 @@
 		}
 		defer res.Body.Close()
 
-		b, err := ioutil.ReadAll(res.Body)
+		b, err := io.ReadAll(res.Body)
 		if err != nil {
 			return "", "", err
 		}
diff --git a/websocket/hybi.go b/websocket/hybi.go
index 48a069e..dda7434 100644
--- a/websocket/hybi.go
+++ b/websocket/hybi.go
@@ -16,7 +16,6 @@
 	"encoding/binary"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"net/http"
 	"net/url"
 	"strings"
@@ -279,7 +278,7 @@
 		}
 	}
 	if header := frame.HeaderReader(); header != nil {
-		io.Copy(ioutil.Discard, header)
+		io.Copy(io.Discard, header)
 	}
 	switch frame.PayloadType() {
 	case ContinuationFrame:
@@ -294,7 +293,7 @@
 		if err != nil && err != io.EOF && err != io.ErrUnexpectedEOF {
 			return nil, err
 		}
-		io.Copy(ioutil.Discard, frame)
+		io.Copy(io.Discard, frame)
 		if frame.PayloadType() == PingFrame {
 			if _, err := handler.WritePong(b[:n]); err != nil {
 				return nil, err
diff --git a/websocket/websocket.go b/websocket/websocket.go
index 90a2257..923a578 100644
--- a/websocket/websocket.go
+++ b/websocket/websocket.go
@@ -17,7 +17,6 @@
 	"encoding/json"
 	"errors"
 	"io"
-	"io/ioutil"
 	"net"
 	"net/http"
 	"net/url"
@@ -208,7 +207,7 @@
 	n, err = ws.frameReader.Read(msg)
 	if err == io.EOF {
 		if trailer := ws.frameReader.TrailerReader(); trailer != nil {
-			io.Copy(ioutil.Discard, trailer)
+			io.Copy(io.Discard, trailer)
 		}
 		ws.frameReader = nil
 		goto again
@@ -330,7 +329,7 @@
 	ws.rio.Lock()
 	defer ws.rio.Unlock()
 	if ws.frameReader != nil {
-		_, err = io.Copy(ioutil.Discard, ws.frameReader)
+		_, err = io.Copy(io.Discard, ws.frameReader)
 		if err != nil {
 			return err
 		}
@@ -362,7 +361,7 @@
 		return ErrFrameTooLarge
 	}
 	payloadType := frame.PayloadType()
-	data, err := ioutil.ReadAll(frame)
+	data, err := io.ReadAll(frame)
 	if err != nil {
 		return err
 	}