Monorepo for Tangled tangled.org
856
fork

Configure Feed

Select the types of activity you want to include in your feed.

knotserver: limit request size

Signed-off-by: oppiliappan <me@oppi.li>

+35 -3
+30 -3
knotserver/xrpc/xrpc.go
··· 1 1 package xrpc 2 2 3 3 import ( 4 + "bytes" 4 5 "encoding/json" 6 + "errors" 5 7 "log/slog" 6 8 "net/http" 7 9 "os" ··· 122 124 json.NewEncoder(w).Encode(e) 123 125 } 124 126 127 + type limitWriter struct { 128 + buf bytes.Buffer 129 + limit int 130 + written int 131 + } 132 + 133 + var errResponseTooLarge = errors.New("response too large") 134 + 135 + func (lw *limitWriter) Write(p []byte) (int, error) { 136 + if lw.written+len(p) > lw.limit { 137 + return 0, errResponseTooLarge 138 + } 139 + n, err := lw.buf.Write(p) 140 + lw.written += n 141 + return n, err 142 + } 143 + 144 + const maxResponseBytes = 5 * 1024 * 1024 145 + 125 146 func writeJson(w http.ResponseWriter, response any) { 126 - w.Header().Set("Content-Type", "application/json") 127 - if err := json.NewEncoder(w).Encode(response); err != nil { 128 - writeError(w, xrpcerr.GenericError(err), http.StatusInternalServerError) 147 + lw := &limitWriter{limit: maxResponseBytes} 148 + if err := json.NewEncoder(lw).Encode(response); err != nil { 149 + if errors.Is(err, errResponseTooLarge) { 150 + writeError(w, xrpcerr.RequestTooLargeError, http.StatusRequestEntityTooLarge) 151 + } else { 152 + writeError(w, xrpcerr.GenericError(err), http.StatusInternalServerError) 153 + } 129 154 return 130 155 } 156 + w.Header().Set("Content-Type", "application/json") 157 + w.Write(lw.buf.Bytes()) 131 158 }
+5
xrpc/errors/errors.go
··· 66 66 WithMessage("failed to access ref"), 67 67 ) 68 68 69 + var RequestTooLargeError = NewXrpcError( 70 + WithTag("RequestTooLarge"), 71 + WithMessage("request was too large"), 72 + ) 73 + 69 74 var AuthError = func(err error) XrpcError { 70 75 return NewXrpcError( 71 76 WithTag("Auth"),