MCPcopy Index your code
hub / github.com/OpenListTeam/OpenList / ServeHTTP

Function ServeHTTP

internal/net/serve.go:55–212  ·  view source on GitHub ↗

this file is inspired by GO_SDK net.http.ServeContent type RangeReadCloser struct { GetReaderForRange RangeReaderFunc } ServeHTTP replies to the request using the content in the provided RangeReadCloser. The main benefit of ServeHTTP over io.Copy is that it handles Range requests properly, sets the

(w http.ResponseWriter, r *http.Request, name string, modTime time.Time, size int64, RangeReadCloser model.RangeReadCloserIF)

Source from the content-addressed store, hash-verified

53// If the caller has set w's ETag header formatted per RFC 7232, section 2.3,
54// ServeHTTP uses it to handle requests using If-Match, If-None-Match, or If-Range.
55func ServeHTTP(w http.ResponseWriter, r *http.Request, name string, modTime time.Time, size int64, RangeReadCloser model.RangeReadCloserIF) error {
56 defer RangeReadCloser.Close()
57 setLastModified(w, modTime)
58 done, rangeReq := checkPreconditions(w, r, modTime)
59 if done {
60 return nil
61 }
62
63 if size < 0 {
64 // since too many functions need file size to work,
65 // will not implement the support of unknown file size here
66 http.Error(w, "negative content size not supported", http.StatusInternalServerError)
67 return nil
68 }
69
70 code := http.StatusOK
71
72 // If Content-Type isn't set, use the file's extension to find it, but
73 // if the Content-Type is unset explicitly, do not sniff the type.
74 contentTypes, haveType := w.Header()["Content-Type"]
75 var contentType string
76 if !haveType {
77 contentType = utils.GetMimeType(name)
78 w.Header().Set("Content-Type", contentType)
79 } else if len(contentTypes) > 0 {
80 contentType = contentTypes[0]
81 }
82
83 // handle Content-Range header.
84 sendSize := size
85 var sendContent io.ReadCloser
86 ranges, err := http_range.ParseRange(rangeReq, size)
87 switch {
88 case err == nil:
89 case errors.Is(err, http_range.ErrNoOverlap):
90 if size == 0 {
91 // Some clients add a Range header to all requests to
92 // limit the size of the response. If the file is empty,
93 // ignore the range header and respond with a 200 rather
94 // than a 416.
95 ranges = nil
96 break
97 }
98 w.Header().Set("Content-Range", fmt.Sprintf("bytes */%d", size))
99 fallthrough
100 default:
101 http.Error(w, err.Error(), http.StatusRequestedRangeNotSatisfiable)
102 return nil
103 }
104
105 if sumRangesSize(ranges) > size {
106 // The total number of bytes in all the ranges is larger than the size of the file
107 // or unknown file size, ignore the range request.
108 ranges = nil
109 }
110
111 // 使用请求的Context
112 // 不然从sendContent读不到数据,即使请求断开CopyBuffer也会一直堵塞

Callers 1

ProxyFunction · 0.92

Calls 15

GetMimeTypeFunction · 0.92
ParseRangeFunction · 0.92
UnwrapOrSelfFunction · 0.92
CopyWithBufferNFunction · 0.92
setLastModifiedFunction · 0.85
checkPreconditionsFunction · 0.85
sumRangesSizeFunction · 0.85
rangesMIMESizeFunction · 0.85
HeaderMethod · 0.80
ContentRangeMethod · 0.80
MimeHeaderMethod · 0.80
WriteHeaderMethod · 0.80

Tested by

no test coverage detected