MCPcopy Create free account
hub / github.com/couchbase/sync_gateway / handleGetAttachment

Method handleGetAttachment

rest/doc_api.go:243–347  ·  view source on GitHub ↗

HTTP handler for a GET of a specific doc attachment

()

Source from the content-addressed store, hash-verified

241
242// HTTP handler for a GET of a specific doc attachment
243func (h *handler) handleGetAttachment() error {
244 docid := h.PathVar("docid")
245 attachmentName := h.PathVar("attach")
246 revid := h.getQuery("rev")
247 rev, err := h.collection.GetRev(h.ctx(), docid, revid, false, nil)
248 if err != nil {
249 return err
250 }
251 if rev.BodyBytes == nil {
252 return kNotFoundError
253 }
254
255 meta, ok := rev.Attachments[attachmentName].(map[string]interface{})
256 if !ok {
257 return base.HTTPErrorf(http.StatusNotFound, "missing attachment %s", attachmentName)
258 }
259 digest := meta["digest"].(string)
260 version, ok := db.GetAttachmentVersion(meta)
261 if !ok {
262 return db.ErrAttachmentVersion
263 }
264 attachmentKey := db.MakeAttachmentKey(version, docid, digest)
265 data, err := h.collection.GetAttachment(attachmentKey)
266 if err != nil {
267 return err
268 }
269
270 metaOption := h.getBoolQuery("meta")
271 if metaOption {
272 meta["key"] = attachmentKey
273 h.writeJSONStatus(http.StatusOK, meta)
274 return nil
275 }
276
277 status, start, end := h.handleRange(uint64(len(data)))
278 if status > 299 {
279 return base.HTTPErrorf(status, "")
280 } else if status == http.StatusPartialContent {
281 data = data[start:end]
282 }
283 h.setHeader("Content-Length", strconv.FormatUint(uint64(len(data)), 10))
284
285 // #720
286 setContentDisposition := h.privs == adminPrivs
287
288 h.setEtag(digest)
289
290 // Request will be returned with the same content type as is set on the attachment. The caveat to this is if the
291 // attachment has a content type which is vulnerable to a phishing attack. If this is the case we will return with
292 // the Content Disposition header so that browsers will download the attachment rather than attempt to render it
293 // unless overridden by config option. CBG-1004
294 contentType, contentTypeSet := meta["content_type"].(string)
295 if contentTypeSet {
296 h.setHeader("Content-Type", contentType)
297 }
298
299 if !h.db.ServeInsecureAttachmentTypes {
300

Callers

nothing calls this directly

Calls 15

PathVarMethod · 0.95
getQueryMethod · 0.95
ctxMethod · 0.95
getBoolQueryMethod · 0.95
writeJSONStatusMethod · 0.95
handleRangeMethod · 0.95
setHeaderMethod · 0.95
setEtagMethod · 0.95
getOptBoolQueryMethod · 0.95
HTTPErrorfFunction · 0.92
GetAttachmentVersionFunction · 0.92
MakeAttachmentKeyFunction · 0.92

Tested by

no test coverage detected