MCPcopy
hub / github.com/jhaals/yopass / streamUpload

Method streamUpload

pkg/server/server_stream.go:24–168  ·  view source on GitHub ↗

streamUpload handles streaming file uploads. The encrypted binary data is streamed directly to the FileStore while metadata is stored in the Database.

(w http.ResponseWriter, r *http.Request)

Source from the content-addressed store, hash-verified

22// The encrypted binary data is streamed directly to the FileStore
23// while metadata is stored in the Database.
24func (y *Server) streamUpload(w http.ResponseWriter, r *http.Request) {
25 session, _ := y.getSession(r)
26 audit := y.newAuditor("file.uploaded", y.getRealClientIP(r), session)
27
28 mediaType, _, _ := mime.ParseMediaType(r.Header.Get("Content-Type"))
29 if mediaType != "application/octet-stream" {
30 audit.failure("invalid content-type")
31 jsonError(w, http.StatusBadRequest, "Content-Type must be application/octet-stream")
32 return
33 }
34
35 // Parse headers
36 expirationStr := r.Header.Get("X-Yopass-Expiration")
37 if expirationStr == "" {
38 audit.failure("missing expiration header")
39 jsonError(w, http.StatusBadRequest, "X-Yopass-Expiration header required")
40 return
41 }
42 expiration, err := strconv.ParseInt(expirationStr, 10, 32)
43 if err != nil || !validExpiration(int32(expiration)) {
44 audit.failure("invalid expiration")
45 jsonError(w, http.StatusBadRequest, "Invalid expiration specified")
46 return
47 }
48
49 if y.ForceExpiration != "" {
50 forced := expirationInSeconds(y.ForceExpiration)
51 if int32(expiration) != forced {
52 audit.failure("expiration does not match forced value")
53 jsonError(w, http.StatusBadRequest, "Expiration does not match server policy")
54 return
55 }
56 }
57
58 oneTime := r.Header.Get("X-Yopass-OneTime") == "true"
59 if !oneTime && y.ForceOneTimeSecrets {
60 audit.failure("one-time required by server policy")
61 jsonError(w, http.StatusBadRequest, "Secret must be one time download")
62 return
63 }
64
65 requireAuth := r.Header.Get("X-Yopass-RequireAuth") == "true"
66 if requireAuth && y.OIDCProvider == nil {
67 audit.failure("auth required but OIDC not configured")
68 jsonError(w, http.StatusBadRequest, "Authentication not configured on this server")
69 return
70 }
71
72 receipt := r.Header.Get("X-Yopass-Receipt") == "true"
73 if receipt && !y.readReceiptsEnabled() {
74 audit.failure("read receipts not enabled")
75 jsonError(w, http.StatusBadRequest, "Read receipts are not enabled on this server")
76 return
77 }
78
79 // Reject early if Content-Length exceeds limit
80 if y.MaxFileSize > 0 && r.ContentLength > y.MaxFileSize {
81 audit.failure("file too large")

Calls 15

getSessionMethod · 0.95
newAuditorMethod · 0.95
getRealClientIPMethod · 0.95
readReceiptsEnabledMethod · 0.95
createReceiptMethod · 0.95
webhookCreatedMethod · 0.95
GenerateIDFunction · 0.92
jsonErrorFunction · 0.85
validExpirationFunction · 0.85
expirationInSecondsFunction · 0.85
isOpenPGPBinaryFunction · 0.85
withOneTimeFunction · 0.85