Protected Scripts
One of the goals of #Script is that its defaults should be safe enough to be able to execute arbitrary scripts by untrusted 3rd parties. Given this constraint, only default scripts are pre-registered which contain a comprehensive set of filters we deem safe for use by anyone. Other methods available in #Script which are useful to have in a server-generated website environment but we don't want 3rd Parties to access are filters in ProtectedScripts.cs.
ProtectedScripts are not pre-registered when creating a new ScriptContext but they are pre-registered when registering the SharpPagesFeature ServiceStack Plugin as that's designed to use #Script within a View Engine where access to its context is limited to the server's Web Application.
To access ProtectedScripts features within your own ScriptContext it can be registered like any other filter:
var context = new ScriptContext
{
ScriptMethods = { new ProtectedScripts() }
}.Init();
includeFile
Use includeFile to embed content directly within pages:
page.html
my-file.txt
Cascading resolution
If an exact match isn't found it will look for the closest file with that name it can find, starting from the directory where the containing page that uses the filter is located and traversing up until it reaches the root folder.
includeFileWithCache
If your VirtualFiles is configured to use a combination of various sources that includes a remote file service like S3VirtualFiles, you'll likely want to cache the contents in memory to ensure fast subsequent access the next time the file is requested, which you can cache without expiration using includeFileWithCache without arguments:
{{ 'my-file.txt' |> includeFileWithCache }}
In which case it will use the 1 minute default overridable in Args[DefaultFileCacheExpiry] or if you want the content to be refreshed after 1hr you can use:
{{ 'my-file.txt' |> includeFileWithCache({ expiresInSecs: 3600 }) }}
includeUrl
You can also embed the contents of remote URLs in your page using includeUrl:
page.html
includeUrl is actually a very flexible HTTP Client which can leverage the URL Handling filters to easily construct urls and the additional filter arguments to customize the HTTP Request that's sent, here are some examples:
Accept JSON responses:
{{ url |> includeUrl({ accept: 'application/json' }) }}
{{ url |> includeUrl({ dataType: 'json' }) }}
Send data as form-urlencoded in a HTTP PUT Request with a #Script User-Agent:
{{ url |> includeUrl({ method:'PUT', data: { id: 1, name: 'foo' }, userAgent:"#Script" }) }}
Send data as JSON in a HTTP POST request and Accept JSON response:
{{ url |> includeUrl({ method: 'POST', data: { id: 1, name: 'foo' },
accept: 'application/json', contentType: 'application/json' }) }}
Shorter version of above request:
{{ url |> includeUrl({ method:'POST', data: { id: 1, name: 'foo' }, dataType: 'json' }) }}
Send data as CSV in a HTTP POST Request and Accept a CSV response:
includeUrl({ method:'POST', data: [{ id: 1, name: 'foo' }, { id: 2, name: 'bar' }], dataType:'csv' })
includeUrlWithCache
In the same way includeFileWithCache can cache file contents, includeUrlWithCache can cache URL content, either without an expiration:
{{ url |> includeUrlWithCache }}
In which case it will use the 1 minute default overridable in Args[DefaultUrlCacheExpiry] or if you want to ensure that no more than 1 url request is made per hour for this url you can specify a custom expiry with:
{{ url |> includeUrlWithCache({ expiresInSecs: 3600 }) }}
Virtual File System APIs
The Virtual File System APIs are mapped to the following methods:
All Protected Scripts Virtual File System APIs are executed against the ScriptContext.VirtualFiles
which in #Script Pages is configured
to the WebRoot FileSystem by default:
allFiles()
The VFS APIs utilizes Extension methods support to include an overloaded method that includes IVirtualPathProvider
as
its first argument:
public IEnumerable<IVirtualFile> allFiles() => allFiles(VirtualFiles);
public IEnumerable<IVirtualFile> allFiles(IVirtualPathProvider vfs) => vfs.GetAllFiles();
This allows being able to use the same method name against any VFS provider by calling it like an instance method, e.g:
vfsFileSystem(dirPath) |> to => fs
fs.allFiles()
This is supported on all VFS APIs with its C# implementation where vfs
is an instance of IVirtualPathProvider
:
Protected VFS Script Method | C# Implementation |
---|---|
allFiles() | vfs.GetAllFiles() |
allRootFiles() | vfs.GetRootFiles() |
allRootDirectories() | vfs.GetRootDirectories() |
dir(virtualPath) | vfs.GetDirectory(virtualPath) |
dirExists(virtualPath) | vfs.DirectoryExists(virtualPath) |
dirFile(dirPath, fileName) | vfs.GetDirectory(dirPath)?.GetFile(fileName) |
dirFiles(virtualPath) | vfs.GetDirectory(dirPath)?.GetFiles() |
dirDirectory(dirPath, dirName) | vfs.GetDirectory(dirPath)?.GetDirectory(dirName) |
dirDirectories(dirPath) | vfs.GetDirectory(dirPath)?.GetDirectories() |
findFilesInDirectory(dirPath, globPattern) | vfs.GetDirectory(dirPath)?.GetAllMatchingFiles(globPattern) |
findFiles(globPattern) | vfs.GetAllMatchingFiles(globPattern) |
fileExists(virtualPath) | vfs.FileExists(virtualPath) |
file(virtualPath) | vfs.GetFile(virtualPath) |
writeFile(virtualPath, contents) | vfs.WriteFile(virtualPath, contents) |
writeFiles(files) | vfs.WriteFiles(files) |
writeTextFiles(textFiles) | vfs.WriteFiles(textFiles) |
appendToFile(virtualPath, contents) | vfs.AppendFile(virtualPath, contents) |
deleteFile(virtualPath) | vfs.DeleteFile(virtualPath) |
deleteDirectory(virtualPath) | vfs.DeleteFolder(virtualPath) |
fileContents(virtualPath) | vfs.GetFile(virtualPath).GetContents() |
fileContents(IFile) | file.GetContents() |
fileTextContents(virtualPath) | vfs.GetFile(virtualPath)?.ReadAllText() |
fileBytesContent(virtualPath) | vfs.GetFile(virtualPath)?.ReadAllBytes() |
fileHash(virtualPath) | vfs.GetFileHash(virtualPath) |
All above VFS APIs work against the built-in VFS providers below:
vfsMemory() |> to => memFs
vfsFileSystem(dirPath) |> to => fs
vfsGist(gistId, accessToken) |> to => gistFs
vfsGist(gistId) |> to => gistReadOnlyFs
They can also be used against AWS S3 and Azure Blob storage providers if you configure your ScriptContext
with AwsScripts
from ServiceStack.Aws package or AzureScripts
from ServiceStack.Azure:
vfsS3(accessKey, secretAccessKey, region, bucketName) |> to => s3Fs
vfsAzureBlob(connectionString, containerName) |> to => azureBlobFs
See the Scripts API Reference for the full list of ServiceStack scripts available.