MCPcopy Index your code
hub / github.com/coder/coder / streamFile

Method streamFile

agent/agentfiles/files.go:88–140  ·  view source on GitHub ↗
(ctx context.Context, rw http.ResponseWriter, path string, offset, limit int64)

Source from the content-addressed store, hash-verified

86}
87
88func (api *API) streamFile(ctx context.Context, rw http.ResponseWriter, path string, offset, limit int64) (HTTPResponseCode, error) {
89 logger := api.logger.With(agentchat.Fields(ctx)...)
90
91 if !filepath.IsAbs(path) {
92 return http.StatusBadRequest, xerrors.Errorf("file path must be absolute: %q", path)
93 }
94
95 f, err := api.filesystem.Open(path)
96 if err != nil {
97 status := http.StatusInternalServerError
98 switch {
99 case errors.Is(err, os.ErrNotExist):
100 status = http.StatusNotFound
101 case errors.Is(err, os.ErrPermission):
102 status = http.StatusForbidden
103 }
104 return status, err
105 }
106 defer f.Close()
107
108 stat, err := f.Stat()
109 if err != nil {
110 return http.StatusInternalServerError, err
111 }
112
113 if stat.IsDir() {
114 return http.StatusBadRequest, xerrors.Errorf("open %s: not a file", path)
115 }
116
117 size := stat.Size()
118 if limit == 0 {
119 limit = size
120 }
121 bytesRemaining := max(size-offset, 0)
122 bytesToRead := min(bytesRemaining, limit)
123
124 // Relying on just the file name for the mime type for now.
125 mimeType := mime.TypeByExtension(filepath.Ext(path))
126 if mimeType == "" {
127 mimeType = "application/octet-stream"
128 }
129 rw.Header().Set("Content-Type", mimeType)
130 rw.Header().Set("Content-Length", strconv.FormatInt(bytesToRead, 10))
131 rw.WriteHeader(http.StatusOK)
132
133 reader := io.NewSectionReader(f, offset, bytesToRead)
134 _, err = io.Copy(rw, reader)
135 if err != nil && !errors.Is(err, io.EOF) && ctx.Err() == nil {
136 logger.Error(ctx, "workspace agent read file", slog.Error(err))
137 }
138
139 return 0, nil
140}
141
142func (api *API) HandleReadFileLines(rw http.ResponseWriter, r *http.Request) {
143 ctx := r.Context()

Callers 1

HandleReadFileMethod · 0.95

Calls 12

FieldsFunction · 0.92
SizeMethod · 0.80
ErrMethod · 0.80
CloseMethod · 0.65
SetMethod · 0.65
CopyMethod · 0.65
ErrorfMethod · 0.45
OpenMethod · 0.45
IsMethod · 0.45
HeaderMethod · 0.45
WriteHeaderMethod · 0.45
ErrorMethod · 0.45

Tested by

no test coverage detected