Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
2474b26
:construction: working on allowing invalid ssl certs for https fetche…
fluffynuts Sep 17, 2026
b3bf19b
:sparkles: fix issues with appsettings parsing, add tests, fix some f…
fluffynuts Sep 18, 2026
537fc1a
:recycle: consolidate all fallbacks for app config
fluffynuts Sep 18, 2026
9393565
:sparkles: do not re-use requests with Cache-Control: no-cache headers
fluffynuts Sep 18, 2026
980e41c
:ok_hand: result of claude review
fluffynuts Sep 21, 2026
04a849e
:construction: refactoring to pull common logic into a place where I …
fluffynuts Sep 22, 2026
50a63c4
:construction: implementing settings around image posts
fluffynuts Sep 22, 2026
19ed452
:construction: adding opt-in POST support
fluffynuts Sep 22, 2026
177e070
:white_check_mark: fill out tests left with TODO
fluffynuts Sep 23, 2026
a78f6ab
:construction: refactoring from review
fluffynuts Sep 23, 2026
5831071
:recycle: improve test harnessing, only create appsettings once durin…
fluffynuts Sep 23, 2026
7516893
:white_check_mark: add integration tests, catch edge case
fluffynuts Sep 23, 2026
0cbcd85
:white_check_mark: add tests around startup middleware usage
fluffynuts Sep 23, 2026
56f39ae
:white_check_mark: add rudimentary test around CompositionRoot
fluffynuts Sep 23, 2026
2a31978
:fire: remove all release workflows
fluffynuts Sep 25, 2026
2014ff8
:bug: should allow the healthcheck endpoint in auth middleware
fluffynuts Sep 28, 2026
2485f87
:white_check_mark: fix test with a small chance of flapping onto a 20…
fluffynuts Sep 28, 2026
af20dc5
:wrench: disallow caching of /test, /size and /health
fluffynuts Sep 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 0 additions & 56 deletions .github/workflows/release-to-octopus.yml

This file was deleted.

55 changes: 0 additions & 55 deletions .github/workflows/release.yml

This file was deleted.

27 changes: 25 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,22 @@ IRAAS has a few configuration options, explained below:

Option | Default | Notes
--------------------------------|------------------------------|------
MaxInputImageSize | 41943040 (40mb) | The maximum size, in bytes, that will be accepted for resizing an image, preventing DDoS via gigantic images
MaxInputImageSize | 41943040 (40mb) | The maximum size, in bytes, that will be accepted for resizing an image, preventing DDoS via gigantic images.
MaxOutputImageSize | 41943040 (40mb) | The maximum output size, in bytes, to allow. Outputs which are larger than this are discarded
UseDeveloperExceptionPage | false | Flag: when enabled, if IRAAS encounters an error, it will show the developer exception page instead of the default short response
UseHttps | false | Flag: when enabled, requests coming in on http will be redirected to the https url you configure in `Urls`
EnableTestPage | false | Flag: when enabled, the path `/test` will serve a (very basic) web page to test resizing images
DomainWhitelist | * (all requests are honored) | Comma-delimited list of domains or domain globs which are allowed as image sources, eg `*.mydomain.com`
DomainWhitelist | * | Comma-delimited list of domains or domain globs which are allowed as image sources, eg `*.mydomain.com`. Setting this to "*" allows all domains.
MaxConcurrency | 0 | The maximum number of image resize operations to perform concurrently. When set to 0, will default to using the number of processors on the host
MaxImageFetchTimeInMilliseconds | 10000 (10s) | The maximum time to wait for a remote service to provide a requested image, in milliseconds
MaxClients | 0 | The maximum number of requests to service at one time. Image resize requests are queued in order, and results for exactly the same parameters are re-used, so requests will queue once MaxConcurrency is reached and images will be handled when resources are available. When set to 0, this instructs IRAAS not to throttle incoming requests, but to handle them as and when it can
ShareConcurrentRequests | true | Flag: when set to true, if two concurrent requests for the same image with the same parameters are received, only one resize operation is done and the result is copied to the other response
EnableConnectionKeepAlive | false | Flag: when set to true, connections to remote image servers are kept open with http keep-alive
SuppressErrorDiagnostics | false | Flag: when set to true, error responses will be secretive about what happened, so as not to leak details to an attacker
MaxUrlFetchRetries | 1 | The number of times to _retry_ a failed image fetch request. If set to zero, only the initial request is performed. Setting this to a low number like 1 or 2 may work around transient errors from remote image servers
AllowInvalidSSLCertificates | false | Flag: when set to true, invalid ssl certificates are ignored when fetching images to resize (useful for dev-testing against self-signed certificates)
AllowPostRequests | false | Flag: when set to true, clients may post raw image data and resize parameters to IRAAS and receive the resize result, if they pass other limitations
PostAuthTokens | "" | A comma-separated list of allowed tokens for Bearer authentication when POST requests are allowed. When it's empty, no POST request will be allowed. You may allow all POST requests by setting this to '*'.

## Operation notes
1. Remember: garbage in, garbage out - IRAAS can't make your images prettier and won't resize them larger
Expand All @@ -62,6 +65,26 @@ MaxUrlFetchRetries | 1 | The number of t
4. IRAAS will echo any provided request headers to the remote image service, and echo any response headers from that
remote image service back to the client. So if you have custom headers on your image responses, they will get back
to the client
5. POST requests are disabled by default, but may be enabled via AllowPostRequests - however, you will also
need to set PostAuthTokens: when this setting is empty, all POST requests are still denied. PostAuthTokens
is a comma-separated list of tokens which are allowed in a client's Authorization header (using the Bearer scheme).
Examples, with AllowPostRequests set to "true":
- config has "PostAuthTokens": "" -> all POST requests will fail, even though AllowPostRequests is set true
- config has "PostAuthTokens": "token1,token2,token3" -> a client with the header "Authorization: Bearer token2" will
be allowed to proceed. It's suggested to use something like a GUID for tokens.
- config has "PostAuthTokens": "*" -> any POST request is allowed, even if it doesn't have an Authorization header
- MaxInputImageSize still applies, but is bounded by the kestrel limits (if set), IIS, or any
reverse-proxy upstream. If this is not set in kestrel config, then it is determined from the MaxInputImageSize
when IRAAS starts up, allowing 50% headroom for base64 encoded inputs, and any resize parameters involved.
Base64-encoded binary data typically bloats by around 33%, so the extra 17% allows some headroom in which a slightly
oversized request will 400 (warning about hitting limits). Severely oversized requests will receive
a 413 response from Kestrel (or whatever response IIS or upstream reverse-proxies provide).
_NB: It is highly recommended to only allow POST requests over SSL (via your own upstream reverse-proxy) or on a
secure network, otherwise all tokens will be visible to anything between the client and IRAAS._

If you're configuring via environment variables and would like to verify that they are being set correctly,
set the environment variable DUMP_ENVIRONMENT to "1" before starting the server and the full environment
available to the server will be dumped out during startup.

## Running direct-from-code
```
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"version": "1.0.0",
"description": "",
"scripts": {
"pretest": "run-s build",
"test": "zarro test-dotnet",
"build": "zarro @",
"build-release": "cross-env BUILD_CONFIGURATION=Release run-s build",
Expand All @@ -15,8 +16,9 @@
"deploy-debug": "cross-env BUILD_CONFIGURATION=Debug zarro deploy",
"zarro": "cross-env zarro",
"prestart": "run-s build",
"start": "cd src/IRAAS/bin/Debug/net7.0 && dotnet IRAAS.dll",
"start-stress-test-server": "cd src/IRAAS.StressTest.ImageServer/bin/Debug/net7.0 && dotnet IRAAS.StressTest.ImageServer.dll",
"start": "cd src/IRAAS/bin/Debug/net8.0 && dotnet IRAAS.dll",
"start-dev": "cross-env Settings__EnableTestPage=true Settings__AllowInvalidSSLCertificates=true Settings__AllowPostRequests=true Settings__PostAuthTokens='*' run-s start",
"start-stress-test-server": "cd src/IRAAS.StressTest.ImageServer/bin/Debug/net8.0 && dotnet IRAAS.StressTest.ImageServer.dll",
"add-ip-to-security-group": "zarro @",
"remove-ip-from-security-group": "zarro @",
"build-and-push-image": "zarro @",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<IsPublishable>true</IsPublishable>
<Configurations>Debug;Release;ReleaseForDocker</Configurations>
<Configurations>Debug;Release;ReleaseForDocker;Debug.WebRequest;Release.WebRequest</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>

Expand Down
4 changes: 2 additions & 2 deletions src/IRAAS.StressTest/IRAAS.StressTest.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
<RootNamespace>IRAAS.StressTest</RootNamespace>
<LangVersion>latest</LangVersion>
<IsPublishable>false</IsPublishable>
<Configurations>Debug;Release;ReleaseForDocker</Configurations>
<Configurations>Debug;Release;ReleaseForDocker;Debug.WebRequest;Release.WebRequest</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="PeanutButter.EasyArgs" Version="3.0.339" />
<PackageReference Include="PeanutButter.EasyArgs" Version="3.0.440" />
</ItemGroup>

<ItemGroup>
Expand Down
35 changes: 35 additions & 0 deletions src/IRAAS.Tests/CompositionRootTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using DryIoc;
using IRAAS.Tests.ImageProcessing;
using Microsoft.AspNetCore.Http;
using NSubstitute;
using NUnit.Framework;

namespace IRAAS.Tests;

public class CompositionRootTests
{
[Test]
public void ShouldBootstrapOnProvidedContainer()
{
// Arrange
var container = new Container();
var appSettings = Substitute.For<IAppSettings>()
.WithDefaultSettings();
// Act
Create(container, appSettings);

// Assert
Expect(container.Resolve<IAppSettings>())
.To.Be(appSettings);
Expect(container.Resolve<IHttpContextAccessor>())
.Not.To.Be.Null();
}

private static CompositionRoot Create(
IContainer container,
IAppSettings appSettings
)
{
return new(container, appSettings);
}
}
Loading
Loading