@@ -47,21 +47,6 @@ type httpSession struct {
47
47
isFullyConnected * done.Instance
48
48
}
49
49
50
- func (h * requestHandler ) maybeReapSession (isFullyConnected * done.Instance , sessionId string ) {
51
- shouldReap := done .New ()
52
- go func () {
53
- time .Sleep (30 * time .Second )
54
- shouldReap .Close ()
55
- }()
56
-
57
- select {
58
- case <- isFullyConnected .Wait ():
59
- return
60
- case <- shouldReap .Wait ():
61
- h .sessions .Delete (sessionId )
62
- }
63
- }
64
-
65
50
func (h * requestHandler ) upsertSession (sessionId string ) * httpSession {
66
51
// fast path
67
52
currentSessionAny , ok := h .sessions .Load (sessionId )
@@ -84,7 +69,21 @@ func (h *requestHandler) upsertSession(sessionId string) *httpSession {
84
69
}
85
70
86
71
h .sessions .Store (sessionId , s )
87
- go h .maybeReapSession (s .isFullyConnected , sessionId )
72
+
73
+ shouldReap := done .New ()
74
+ go func () {
75
+ time .Sleep (30 * time .Second )
76
+ shouldReap .Close ()
77
+ }()
78
+ go func () {
79
+ select {
80
+ case <- shouldReap .Wait ():
81
+ h .sessions .Delete (sessionId )
82
+ s .uploadQueue .Close ()
83
+ case <- s .isFullyConnected .Wait ():
84
+ }
85
+ }()
86
+
88
87
return s
89
88
}
90
89
@@ -183,12 +182,13 @@ func (h *requestHandler) ServeHTTP(writer http.ResponseWriter, request *http.Req
183
182
writer .WriteHeader (http .StatusBadRequest )
184
183
return
185
184
}
186
- uploadDone := done .New ()
185
+ httpSC := & httpServerConn {
186
+ Instance : done .New (),
187
+ Reader : request .Body ,
188
+ ResponseWriter : writer ,
189
+ }
187
190
err = currentSession .uploadQueue .Push (Packet {
188
- Reader : & httpRequestBodyReader {
189
- requestReader : request .Body ,
190
- uploadDone : uploadDone ,
191
- },
191
+ Reader : httpSC ,
192
192
})
193
193
if err != nil {
194
194
errors .LogInfoInner (context .Background (), err , "failed to upload (PushReader)" )
@@ -200,25 +200,21 @@ func (h *requestHandler) ServeHTTP(writer http.ResponseWriter, request *http.Req
200
200
scStreamUpServerSecs := h .config .GetNormalizedScStreamUpServerSecs ()
201
201
if referrer != "" && scStreamUpServerSecs .To > 0 {
202
202
go func () {
203
- defer func () {
204
- recover ()
205
- }()
206
203
for {
207
- _ , err := writer .Write (bytes .Repeat ([]byte {'X' }, int (h .config .GetNormalizedXPaddingBytes ().rand ())))
204
+ _ , err := httpSC .Write (bytes .Repeat ([]byte {'X' }, int (h .config .GetNormalizedXPaddingBytes ().rand ())))
208
205
if err != nil {
209
206
break
210
207
}
211
- writer .(http.Flusher ).Flush ()
212
208
time .Sleep (time .Duration (scStreamUpServerSecs .rand ()) * time .Second )
213
209
}
214
210
}()
215
211
}
216
212
select {
217
213
case <- request .Context ().Done ():
218
- case <- uploadDone .Wait ():
214
+ case <- httpSC .Wait ():
219
215
}
220
216
}
221
- uploadDone .Close ()
217
+ httpSC .Close ()
222
218
return
223
219
}
224
220
@@ -262,11 +258,6 @@ func (h *requestHandler) ServeHTTP(writer http.ResponseWriter, request *http.Req
262
258
263
259
writer .WriteHeader (http .StatusOK )
264
260
} else if request .Method == "GET" || sessionId == "" { // stream-down, stream-one
265
- responseFlusher , ok := writer .(http.Flusher )
266
- if ! ok {
267
- panic ("expected http.ResponseWriter to be an http.Flusher" )
268
- }
269
-
270
261
if sessionId != "" {
271
262
// after GET is done, the connection is finished. disable automatic
272
263
// session reaping, and handle it in defer
@@ -287,20 +278,18 @@ func (h *requestHandler) ServeHTTP(writer http.ResponseWriter, request *http.Req
287
278
}
288
279
289
280
writer .WriteHeader (http .StatusOK )
281
+ writer .(http.Flusher ).Flush ()
290
282
291
- responseFlusher .Flush ()
292
-
293
- downloadDone := done .New ()
294
-
283
+ httpSC := & httpServerConn {
284
+ Instance : done .New (),
285
+ Reader : request .Body ,
286
+ ResponseWriter : writer ,
287
+ }
295
288
conn := splitConn {
296
- writer : & httpResponseBodyWriter {
297
- responseWriter : writer ,
298
- downloadDone : downloadDone ,
299
- responseFlusher : responseFlusher ,
300
- },
301
- reader : request .Body ,
302
- localAddr : h .localAddr ,
289
+ writer : httpSC ,
290
+ reader : httpSC ,
303
291
remoteAddr : remoteAddr ,
292
+ localAddr : h .localAddr ,
304
293
}
305
294
if sessionId != "" { // if not stream-one
306
295
conn .reader = currentSession .uploadQueue
@@ -311,7 +300,7 @@ func (h *requestHandler) ServeHTTP(writer http.ResponseWriter, request *http.Req
311
300
// "A ResponseWriter may not be used after [Handler.ServeHTTP] has returned."
312
301
select {
313
302
case <- request .Context ().Done ():
314
- case <- downloadDone .Wait ():
303
+ case <- httpSC .Wait ():
315
304
}
316
305
317
306
conn .Close ()
@@ -321,45 +310,30 @@ func (h *requestHandler) ServeHTTP(writer http.ResponseWriter, request *http.Req
321
310
}
322
311
}
323
312
324
- type httpRequestBodyReader struct {
325
- requestReader io.ReadCloser
326
- uploadDone * done.Instance
327
- }
328
-
329
- func (c * httpRequestBodyReader ) Read (b []byte ) (int , error ) {
330
- return c .requestReader .Read (b )
331
- }
332
-
333
- func (c * httpRequestBodyReader ) Close () error {
334
- defer c .uploadDone .Close ()
335
- return c .requestReader .Close ()
336
- }
337
-
338
- type httpResponseBodyWriter struct {
313
+ type httpServerConn struct {
339
314
sync.Mutex
340
- responseWriter http. ResponseWriter
341
- responseFlusher http. Flusher
342
- downloadDone * done. Instance
315
+ * done. Instance
316
+ io. Reader // no need to Close request.Body
317
+ http. ResponseWriter
343
318
}
344
319
345
- func (c * httpResponseBodyWriter ) Write (b []byte ) (int , error ) {
320
+ func (c * httpServerConn ) Write (b []byte ) (int , error ) {
346
321
c .Lock ()
347
322
defer c .Unlock ()
348
- if c .downloadDone . Done () {
323
+ if c .Done () {
349
324
return 0 , io .ErrClosedPipe
350
325
}
351
- n , err := c .responseWriter .Write (b )
326
+ n , err := c .ResponseWriter .Write (b )
352
327
if err == nil {
353
- c .responseFlusher .Flush ()
328
+ c .ResponseWriter .(http. Flusher ) .Flush ()
354
329
}
355
330
return n , err
356
331
}
357
332
358
- func (c * httpResponseBodyWriter ) Close () error {
333
+ func (c * httpServerConn ) Close () error {
359
334
c .Lock ()
360
335
defer c .Unlock ()
361
- c .downloadDone .Close ()
362
- return nil
336
+ return c .Instance .Close ()
363
337
}
364
338
365
339
type Listener struct {
0 commit comments