Skip to content

Commit

Permalink
rsc: Support dbonly small blobs on the client (#1553)
Browse files Browse the repository at this point in the history
* rsc: Support dbonly small blobs on the client

* address comments

* fix off by one

* refine size
  • Loading branch information
V-FEXrt authored May 3, 2024
1 parent 4173d52 commit 2d95726
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 18 deletions.
15 changes: 10 additions & 5 deletions share/wake/lib/system/http.wake
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ tuple HttpFormData =
# in the fullness of time it should be converted to a Path. This library is careful to not
# claim or otherwise convert it to a Path as it should be done by the caller when possible
File: String
# The optional Content-Type field of the specific form entry. The field is not set when None
ContentType: Option String

# The description of a http request to send to a web server.
tuple HttpRequest =
Expand Down Expand Up @@ -104,15 +106,15 @@ export def setBody (body: String): HttpRequest => HttpRequest =
setHttpRequestBody (Some body)

# Adds a named file to the requests form data.
export def addFormData (name: String) (value: Path): HttpRequest => HttpRequest =
unsafe_addFormData name value.getPathName
export def addFormData (name: String) (value: Path) (contentType: Option String): HttpRequest => HttpRequest =
unsafe_addFormData name value.getPathName contentType

# Adds a named file to the request's form data from an unhashed file.
#
# This is a restricted function and should be reserved for advanced use only
export def unsafe_addFormData (name: String) (value: String): HttpRequest => HttpRequest =
export def unsafe_addFormData (name: String) (value: String) (contentType: Option String): HttpRequest => HttpRequest =
def setOrAppend field =
def entry = HttpFormData name value
def entry = HttpFormData name value contentType

match field
Some formDatas -> Some (entry, formDatas)
Expand Down Expand Up @@ -192,7 +194,10 @@ def methodToString = match _
# helper function for building up the curl cmd representing a request
def makeCurlCmd ((HttpRequest url method headers body formData): HttpRequest) (extraFlags: List String): Result (List String) Error =
def headerToCurlFlag (HttpHeader name value) = "--header", "{name}:{value}", Nil
def formDataToCurlFlag (HttpFormData name file) = "--form", "{name}=@{file}", Nil

def formDataToCurlFlag (HttpFormData name file contentType) = match contentType
Some ct -> "--form", "{name}=@{file};type={ct}", Nil
None -> "--form", "{name}=@{file}", Nil

def bodyToCurlFlag body =
require True = body.strlen >= 5000
Expand Down
65 changes: 52 additions & 13 deletions share/wake/lib/system/remote_cache_api.wake
Original file line number Diff line number Diff line change
Expand Up @@ -237,13 +237,15 @@ export def makeRemoteCacheApi (config: String): Result RemoteCacheApi Error =
# (RemoteCacheApi "foo" 1 None) | rscApiPostStringBlob "foo" "my foo contents" = Fail "authorization required"
# ```
export def rscApiPostStringBlob (name: String) (value: String) (api: RemoteCacheApi): Result String Error =
# TODO: use "small blob" for this
# require False = value ==* ""
# else Pass "00000000-0000-0000-0000-000000000000"
def contentType =
if value.strlen < 95 then
Some "blob/small"
else
None

require Pass temp = writeTempFile name value

uploadBlobRequest api (addFormData name temp)
uploadBlobRequest api (addFormData name temp contentType)

# rscApiPostFileBlob: Posts a named file on disk to the remote server defined by *api*
# then returns the id associated to the blob. Requires authorization.
Expand All @@ -255,7 +257,7 @@ export def rscApiPostStringBlob (name: String) (value: String) (api: RemoteCache
export def rscApiPostFileBlob (name: String) (file: String) (api: RemoteCacheApi): Result String Error =
# We must use unsafe here since we cannot elevate *file* to a Path without either copying it
# or triggering the 'job output by multiple files' error.
uploadBlobRequest api (unsafe_addFormData name file)
uploadBlobRequest api (unsafe_addFormData name file None)

# rscApiPostJob: Posts a job defined by *req* to the remote cache server. Requires authorization.
#
Expand Down Expand Up @@ -395,16 +397,53 @@ export def rscApiCheckAuthorization (api: RemoteCacheApi): Result Unit Error =
# rscApiGetStringBlob (RemoteCacheBlob "asdf" "https://...") = Pass "foo\nbar\nbat"
# ```
export def rscApiGetStringBlob ((CacheSearchBlob _ uri): CacheSearchBlob): Result String Error =
# TODO: use "small blob" for this and also parse the schema out
# require False = id ==* "00000000-0000-0000-0000-000000000000"
# else Pass ""
require scheme, path, Nil = extract `([a-zA-Z][a-zA-Z0-9+.-]*)://(.*)` uri
else failWithError "rsc: uri has unexpected format: '{uri}'"

# maps path = "%46%6F%6F" to content = "foo"
def dbScheme _scheme path =
# If path is empty we have the empty string
require True = path.strlen > 0
else Pass ""

# If not empty then it must as least be %00
require True = path.strlen >= 3
else failWithError "rsc: Invalid db path: '{path}'"

require "", byteStrs = tokenize `%` path
else failWithError "rsc: Failed to extract bytes from db path: '{path}'"

require Some bytes =
byteStrs
| map (intbase 16)
| findNone
else failWithError "rsc: Failed to parse bytes strings into bytes from db path: '{path}'"

bytes
# TODO: this only supports ASCII, not unicode. This needs to be enforced somewhere.
| map integerToByte
| cat
| Pass

require Pass response =
buildHttpRequest uri
| setMethod HttpMethodGet
| makeRequest
def fileScheme scheme path =
require Pass response =
buildHttpRequest "{scheme}://{path}"
| setMethod HttpMethodGet
| makeRequest

Pass response.getHttpResponseBody

def unsupportedScheme scheme path =
failWithError "rsc: scheme '{scheme}' from uri '{uri}' is not supported"

def schemeFn = match scheme
"db" -> dbScheme
"file" -> fileScheme
"http" -> fileScheme
"https" -> fileScheme
_ -> unsupportedScheme

Pass response.getHttpResponseBody
schemeFn scheme path

# rscApiGetFileBlob: Downloads a blob to *path* with *mode* permisssions and return *path*
#
Expand Down

0 comments on commit 2d95726

Please sign in to comment.