-
Notifications
You must be signed in to change notification settings - Fork 4
/
filebytes.go
57 lines (47 loc) · 1.29 KB
/
filebytes.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package htsserver
import (
"bufio"
"io"
"math"
"net/http"
"os"
"github.com/ga4gh/htsget-refserver/internal/htsconstants"
"github.com/ga4gh/htsget-refserver/internal/htsutils"
)
func getFileBytes(writer http.ResponseWriter, request *http.Request) {
newRequestHandler(
htsconstants.GetMethod,
htsconstants.APIEndpointFileBytes,
noAfterSetup,
getFileBytesHandler,
).handleRequest(writer, request)
}
func getFileBytesHandler(handler *requestHandler) {
start, end, err := htsutils.ParseRangeHeader(handler.HtsReq.GetHtsgetRange())
if err != nil {
return
}
file, err := os.Open(handler.HtsReq.GetHtsgetFilePath())
reader := bufio.NewReader(file)
reader.Discard(int(start))
chunkSize := 8192
nBytes := end - start + 1
nChunks := int(math.Ceil(float64(nBytes) / float64(chunkSize)))
nBytesRead := int64(0)
buffer := make([]byte, chunkSize)
for i := 0; i < nChunks; i++ {
n, err := io.ReadFull(reader, buffer)
if err != nil {
}
handler.Writer.Write(buffer)
// at the second last chunk, create a buffer that will only read bytes
// up to the exact remaining needed to fulfill the range request
nBytesRead += int64(n)
if i == nChunks-2 {
bytesRemaining := nBytes - nBytesRead
buffer = make([]byte, bytesRemaining)
} else {
buffer = make([]byte, chunkSize)
}
}
}