blob: 3b982774b02eb954d97573058c0e891036f8585e [file] [log] [blame]
Dan Willemsen0c157092016-07-08 13:57:52 -07001// Copyright 2016 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
Dan Willemsenf3f2eb62018-08-28 11:28:58 -07005// +build !js
6
Dan Willemsen0c157092016-07-08 13:57:52 -07007package net
8
9import (
Dan Willemsenf3f2eb62018-08-28 11:28:58 -070010 "bytes"
Dan Willemsen0c157092016-07-08 13:57:52 -070011 "crypto/sha256"
12 "encoding/hex"
13 "fmt"
14 "io"
15 "os"
16 "testing"
17)
18
19const (
20 twain = "testdata/Mark.Twain-Tom.Sawyer.txt"
21 twainLen = 387851
22 twainSHA256 = "461eb7cb2d57d293fc680c836464c9125e4382be3596f7d415093ae9db8fcb0e"
23)
24
25func TestSendfile(t *testing.T) {
26 ln, err := newLocalListener("tcp")
27 if err != nil {
28 t.Fatal(err)
29 }
30 defer ln.Close()
31
32 errc := make(chan error, 1)
33 go func(ln Listener) {
34 // Wait for a connection.
35 conn, err := ln.Accept()
36 if err != nil {
37 errc <- err
38 close(errc)
39 return
40 }
41
42 go func() {
43 defer close(errc)
44 defer conn.Close()
45
46 f, err := os.Open(twain)
47 if err != nil {
48 errc <- err
49 return
50 }
51 defer f.Close()
52
53 // Return file data using io.Copy, which should use
54 // sendFile if available.
55 sbytes, err := io.Copy(conn, f)
56 if err != nil {
57 errc <- err
58 return
59 }
60
61 if sbytes != twainLen {
62 errc <- fmt.Errorf("sent %d bytes; expected %d", sbytes, twainLen)
63 return
64 }
65 }()
66 }(ln)
67
68 // Connect to listener to retrieve file and verify digest matches
69 // expected.
70 c, err := Dial("tcp", ln.Addr().String())
71 if err != nil {
72 t.Fatal(err)
73 }
74 defer c.Close()
75
76 h := sha256.New()
77 rbytes, err := io.Copy(h, c)
78 if err != nil {
79 t.Error(err)
80 }
81
82 if rbytes != twainLen {
83 t.Errorf("received %d bytes; expected %d", rbytes, twainLen)
84 }
85
86 if res := hex.EncodeToString(h.Sum(nil)); res != twainSHA256 {
87 t.Error("retrieved data hash did not match")
88 }
89
90 for err := range errc {
91 t.Error(err)
92 }
93}
Dan Willemsenf3f2eb62018-08-28 11:28:58 -070094
95func TestSendfileParts(t *testing.T) {
96 ln, err := newLocalListener("tcp")
97 if err != nil {
98 t.Fatal(err)
99 }
100 defer ln.Close()
101
102 errc := make(chan error, 1)
103 go func(ln Listener) {
104 // Wait for a connection.
105 conn, err := ln.Accept()
106 if err != nil {
107 errc <- err
108 close(errc)
109 return
110 }
111
112 go func() {
113 defer close(errc)
114 defer conn.Close()
115
116 f, err := os.Open(twain)
117 if err != nil {
118 errc <- err
119 return
120 }
121 defer f.Close()
122
123 for i := 0; i < 3; i++ {
124 // Return file data using io.CopyN, which should use
125 // sendFile if available.
126 _, err = io.CopyN(conn, f, 3)
127 if err != nil {
128 errc <- err
129 return
130 }
131 }
132 }()
133 }(ln)
134
135 c, err := Dial("tcp", ln.Addr().String())
136 if err != nil {
137 t.Fatal(err)
138 }
139 defer c.Close()
140
141 buf := new(bytes.Buffer)
142 buf.ReadFrom(c)
143
144 if want, have := "Produced ", buf.String(); have != want {
145 t.Errorf("unexpected server reply %q, want %q", have, want)
146 }
147
148 for err := range errc {
149 t.Error(err)
150 }
151}
152
153func TestSendfileSeeked(t *testing.T) {
154 ln, err := newLocalListener("tcp")
155 if err != nil {
156 t.Fatal(err)
157 }
158 defer ln.Close()
159
160 const seekTo = 65 << 10
161 const sendSize = 10 << 10
162
163 errc := make(chan error, 1)
164 go func(ln Listener) {
165 // Wait for a connection.
166 conn, err := ln.Accept()
167 if err != nil {
168 errc <- err
169 close(errc)
170 return
171 }
172
173 go func() {
174 defer close(errc)
175 defer conn.Close()
176
177 f, err := os.Open(twain)
178 if err != nil {
179 errc <- err
180 return
181 }
182 defer f.Close()
183 if _, err := f.Seek(seekTo, os.SEEK_SET); err != nil {
184 errc <- err
185 return
186 }
187
188 _, err = io.CopyN(conn, f, sendSize)
189 if err != nil {
190 errc <- err
191 return
192 }
193 }()
194 }(ln)
195
196 c, err := Dial("tcp", ln.Addr().String())
197 if err != nil {
198 t.Fatal(err)
199 }
200 defer c.Close()
201
202 buf := new(bytes.Buffer)
203 buf.ReadFrom(c)
204
205 if buf.Len() != sendSize {
206 t.Errorf("Got %d bytes; want %d", buf.Len(), sendSize)
207 }
208
209 for err := range errc {
210 t.Error(err)
211 }
212}