Source file
src/net/http/filetransport.go
1
2
3
4
5 package http
6
7 import (
8 "fmt"
9 "io"
10 "io/fs"
11 )
12
13
14 type fileTransport struct {
15 fh fileHandler
16 }
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 func NewFileTransport(fs FileSystem) RoundTripper {
32 return fileTransport{fileHandler{fs}}
33 }
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 func NewFileTransportFS(fsys fs.FS) RoundTripper {
50 return NewFileTransport(FS(fsys))
51 }
52
53 func (t fileTransport) RoundTrip(req *Request) (resp *Response, err error) {
54
55
56
57
58
59
60 rw, resc := newPopulateResponseWriter()
61 go func() {
62 t.fh.ServeHTTP(rw, req)
63 rw.finish()
64 }()
65 return <-resc, nil
66 }
67
68 func newPopulateResponseWriter() (*populateResponse, <-chan *Response) {
69 pr, pw := io.Pipe()
70 rw := &populateResponse{
71 ch: make(chan *Response),
72 pw: pw,
73 res: &Response{
74 Proto: "HTTP/1.0",
75 ProtoMajor: 1,
76 Header: make(Header),
77 Close: true,
78 Body: pr,
79 },
80 }
81 return rw, rw.ch
82 }
83
84
85
86
87
88 type populateResponse struct {
89 res *Response
90 ch chan *Response
91 wroteHeader bool
92 hasContent bool
93 sentResponse bool
94 pw *io.PipeWriter
95 }
96
97 func (pr *populateResponse) finish() {
98 if !pr.wroteHeader {
99 pr.WriteHeader(500)
100 }
101 if !pr.sentResponse {
102 pr.sendResponse()
103 }
104 pr.pw.Close()
105 }
106
107 func (pr *populateResponse) sendResponse() {
108 if pr.sentResponse {
109 return
110 }
111 pr.sentResponse = true
112
113 if pr.hasContent {
114 pr.res.ContentLength = -1
115 }
116 pr.ch <- pr.res
117 }
118
119 func (pr *populateResponse) Header() Header {
120 return pr.res.Header
121 }
122
123 func (pr *populateResponse) WriteHeader(code int) {
124 if pr.wroteHeader {
125 return
126 }
127 pr.wroteHeader = true
128
129 pr.res.StatusCode = code
130 pr.res.Status = fmt.Sprintf("%d %s", code, StatusText(code))
131 }
132
133 func (pr *populateResponse) Write(p []byte) (n int, err error) {
134 if !pr.wroteHeader {
135 pr.WriteHeader(StatusOK)
136 }
137 pr.hasContent = true
138 if !pr.sentResponse {
139 pr.sendResponse()
140 }
141 return pr.pw.Write(p)
142 }
143
View as plain text