Skip to content

Commit

Permalink
MB-48675 Refine fix
Browse files Browse the repository at this point in the history
Lowers the minimum result-cap size to 512 KiB.

Silently limits result-cap to available quota when quota is in effect -
this is so we see a "Response size " error ahead of a quota exceeded
error.  It also means that requests with small enough responses don't
fail up front because an over-large result-cap was specified.

Change-Id: I612331c9da15ac679d81f4ba72611c7a06c7b647
Reviewed-on: https://review.couchbase.org/c/query/+/184671
Reviewed-by: Sitaram Vemulapalli <sitaram.vemulapalli@couchbase.com>
Tested-by: Donald Haggart <donald.haggart@couchbase.com>
  • Loading branch information
dhaggart committed Jan 9, 2023
1 parent c5aeb0c commit 0154f76
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 8 deletions.
2 changes: 2 additions & 0 deletions expression/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,6 @@ type QuotaContext interface {
UseRequestQuota() bool
TrackValueSize(uint64) errors.Error
ReleaseValueSize(uint64)
MemoryQuota() uint64
CurrentQuotaUsage() float64
}
32 changes: 24 additions & 8 deletions expression/func_curl.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ var (

// Max request size from server (cant import because of cyclic dependency)
const (
_MIN_RESPONSE_SIZE = 20 * util.MiB
_MIN_RESPONSE_SIZE = 512 * util.KiB
_DEFAULT_RESPONSE_SIZE = 20 * util.MiB
_MAX_NO_QUOTA_RESPONSE_SIZE = 128 * util.MiB
)

Expand Down Expand Up @@ -244,12 +245,19 @@ func (this *Curl) handleCurl(url string, options map[string]interface{}, allowli
return nil, err
}

var availableQuota uint64
responseSize := uint64(_DEFAULT_RESPONSE_SIZE)

ctx, ok := context.(QuotaContext)
if !ok || !ctx.UseRequestQuota() {
ctx = nil
} else {
availableQuota = uint64(float64(ctx.MemoryQuota()) * (1.0 - ctx.CurrentQuotaUsage()))
if responseSize > availableQuota {
responseSize = availableQuota
}
}

responseSize := uint64(_MIN_RESPONSE_SIZE)
sizeError := false
getMethod := false
dataOp := false
Expand Down Expand Up @@ -479,23 +487,31 @@ func (this *Curl) handleCurl(url string, options map[string]interface{}, allowli
this.myCurl.Setopt(curl.OPT_SSLCERTTYPE, "PEM")
this.myCurl.Setopt(curl.OPT_CAINFO, certDir+file)
case "result-cap":
// Restricted to 20MiB - 256MiB
// Restricted to 0.5 - 256 MiB
if inputVal.Type() != value.NUMBER {
return nil, fmt.Errorf("Incorrect type for result-cap option in CURL ")
}
// negatives set to minimum
rs := value.AsNumberValue(inputVal).Int64()
if rs < _MIN_RESPONSE_SIZE {
logging.Debuga(func() string {
return fmt.Sprintf("CURL (%v) result-cap %v set to %v", url, rs, _MIN_RESPONSE_SIZE)
})
rs = _MIN_RESPONSE_SIZE
}
responseSize = uint64(rs)
// if there is a quota the remaining available memory enforces the upper limit
if ctx == nil && rs > _MAX_NO_QUOTA_RESPONSE_SIZE {
if ctx == nil && responseSize > _MAX_NO_QUOTA_RESPONSE_SIZE {
logging.Debuga(func() string {
return fmt.Sprintf("CURL (%v) result-cap %v limited to %v", url, responseSize, _MAX_NO_QUOTA_RESPONSE_SIZE)
})
responseSize = _MAX_NO_QUOTA_RESPONSE_SIZE
} else if ctx != nil && responseSize > availableQuota {
logging.Debuga(func() string {
return fmt.Sprintf("CURL (%v) result-cap %v capped to %v", url, rs, _MAX_NO_QUOTA_RESPONSE_SIZE)
return fmt.Sprintf("CURL (%v) result-cap %v limited to %v", url, responseSize, availableQuota)
})
rs = _MAX_NO_QUOTA_RESPONSE_SIZE
responseSize = availableQuota
}
responseSize = uint64(rs)
case "verbose":
// verbose only writes to STDERR so only permit it when DEBUG logging is enabled too
if inputVal.Truth() && logging.LogLevel() == logging.DEBUG {
Expand Down Expand Up @@ -574,7 +590,7 @@ func (this *Curl) handleCurl(url string, options map[string]interface{}, allowli
}

if sizeError {
return nil, fmt.Errorf("Response Size has been exceeded. The max response capacity is %v", responseSize)
return nil, fmt.Errorf("Response size limit of %v has been reached.", responseSize)
}

// The return type can either be and ARRAY or an OBJECT
Expand Down

0 comments on commit 0154f76

Please sign in to comment.