All notable changes to this project will be documented in this file.
Request.getBodyStringOptionsto allow configuration of the maximum request body size, with a default ofMultipart.DefaultMaxSize(32MB).Request.getFormOptionsto allow configuration of the maximum form size, with a default ofMultipart.DefaultMaxSize(32MB).- Guards to
RequestValue.parseto prevent oversized numerics or leading-zero numeric strings (non-decimal) from being parsed as floats. - Max size constraint to multipart form streaming, with a default of
Multipart.DefaultMaxSize(32MB).
Request.getFormnow automatically performs CSRF validation if antiforgery services are registered and the request method is POST, PUT, PATCH, or DELETE. ReturnsFormData optionwhen consumption or CSRF validation fails.- Increased multipart form streaming buffer size from 1024 to 8192 bytes to improve performance of large file uploads.
Request.ifAuthenticatedInRoleaccepts roles asseqinstead oflistfor more flexible input options.Request.getJsonOptionsexplicitly checks for application/json content type and empty body, returning default form ofT. Returns 415 Unsupported Media Type response when content type is missing.Response.signInOptionsandResponse.signOutOptionsnow conditionally set status code 301 and Location header only whenAuthenticationProperties.RedirectUriis present.Response.challengeOptionsandResponse.challengeAndRedirectnow set status code 401 and WWW-Authenticate header to properly indicate authentication challenge.
- Unnecessary URL decode in
RequestValue.parseString. - Default
JsonSerializerOptionsused for JSON deserialization, optimized by making read-only and static to prevent unnecessary allocations. Response.ofAttachmentnow properly escapes provided filename to ensure correct handling of special characters and spaces across different browsers.- Added missing Location header to
Response.signInOptionsandResponse.signOutOptionswhen redirect URI is specified.
Request.getFormSecureandRequest.mapFormSecure, which were explicit enablements of the now default CSRF validation for form requests.Request.getFormandRequest.mapFormnow include automatic CSRF validation when antiforgery services are registered and request method is POST, PUT, PATCH, or DELETE.
net10.0support.
Response.ofFragmentandResponse.ofFragmentCsrfto return HTML fragments by element ID, with optional CSRF token support.Falco.Markupversion 1.4.0, which reverted API to 1.2.0 and provided correct support for template fragments.
Falco.Markupversion 1.3.0, which enables support for template fragment responses.
- Request module error for JSON transfer encoding chunked requests.
Falco.Markupversion 1.2.0 support, which includes a unified DSL module introduces consistent prefix-based naming conventions for elements, text shortcuts, and attributes, making code cleaner and more readable.
Request.mapCookiesandRequest.mapHeadersre-added, which were accidentally removed in the 5.0.0 release.
- Declarative OpenAPI support.
RequestData(andRequestValue) to support complex form & query submissions,- Provided by an HTTP key/value pair (i.e.,
name=falco&classification=toolkit) parser. - A derivative
FormDatacontains parsedRequestValueand access toIFormFileCollection.
- Provided by an HTTP key/value pair (i.e.,
HttpContext.Plug<T>for generic injection support of dependencies withinHttpHandler's (service locator pattern).Request.getJson<T>for generic JSON request deserialization, using default settings (property name case-insensitive, trailing commas allowed).Request.getCookies, replacingRequest.getCookie.Response.signInOptionsto sign in claim principal for provided scheme and options then responds with a 301 redirect to provided URL.Response.challengeAndRedirect, replacingResponse.challengeWithRedirect.Routing.map[Get|Head|Post|Put|Patch|Delete|Options|Trace|Any]which producesHttpEndpointby associating a route pattern to anHttpHandlerafter mapping route.Routing.setDisplayNameto set the display name of the endpoint.Routing.setOrderto set the order number of the endpoint.WebApplication.run, registers the providedHttpHandleras the terminal middleware and runs the application.
Xssmodule renamed toXsrf. Functions:Xsrf.antiforgeryInput,Xsrf.getToken&Xsrf.validateToken.
- Missing cancellation token pass-through during form reading,
multipart/form-datastreaming and JSON serialization/deserialization. - Empty request body support for JSON request methods.
WebApplication.UseFalcoNotFound&IApplicationBuilder.UseFalcoNotFoundto correctly terminate by returningunitakin to the native method.
net6.0support dropped (end of life 2024-11-12).webHost [||] {}builder removed.config {}builder removed.HttpContext.GetLogger<T>()extension removed.IApplicationBuilder.IsDevelopment(),IApplicationBuilder.UseWhen()extensions removed.Services.inject<T>(and overloads) removed.Response.withContentLengthremoved (unsupported).StringCollectionReaderand derivatives removed (FormCollectionReader,QueryCollectionReader,RouteCollectionReader,HeaderCollectionReader, andCookieCollectionReader).- All replaced by homogenous
RequestDatatype.
- All replaced by homogenous
Request.streamForm,Request.streamFormSecure,Request.mapFormStreamandRequest.mapFormStreamSecureremoved.Falco.Security.CryptoandFalco.Security.Authmodules removed.- Removed
Request.getCookie, renamedRequest.getCookies. - Removed
Response.challengeWithRedirect, renamedResponse.challengeAndRedirect. - Removed
Response.debugRequest.
net7.0andnet8.0support added.- Added ability to configure
IWebHostBuilderto host builder (i.e.,webHost [||] { web_host (fun webHost -> ...) }).
- Execution order of configuration builder (i.e.,
configuration { add_env }) set to match default configuration behaviour.
Request.getFormSecureandRequest.streamFormSecure.use_corsto host builder (i.e.,webHost [||] { use_cors }).
- Unused types
HttpContextAccessorandAsyncHttpContextAccessor.
- Working tutorial sample.
- Documentation website generator
/site, and output/docs.
- Internal utility functions
httpPipeandhttpPipeTask. See issue #94, #95.
- NuGet package metadata, invalid readme.
- Hello world sample to use ASP.NET static file middleware.
- Spelling and grammar of comments. See #96.
- Unused internal function
String.parseInt.
Response.debugRequest, which pretty prints the content of the current request to the screen.- Related community projects and libraries to README.md.
- NuGet package metadata, invalid icon path.
The project no longer intends to support anything prior to net6.0, which enables the built-in task {} computation expression.
StringCollectionReader.GetChildren, safely retrieves a collection of readers. Intended to be used with the "dot notation" collection wire format (i.e., Person.First=John&Person.Last=Doe&Person.First=Jane&Person.Last=Doe).MultipartReader.StreamSectionsAsyncfor async streaming of multipart/form-data, following MSFT spec.Services.injecthelpers, for CPS-style dependency injection, supporting up to five generic input types.in_memory,required_ini,optional_ini,required_xml,optional_xmlcustom operations added to the configuration builder.
StringCollectionReaderabstract attribute removed, to support nested readers.StringCollectionReader.Get{String|StringNonEmpty|Int16|Int32|Int|Int64|Boolean|Float|Decimal|DateTime|DateTimeOffset|Guid|TimeSpan}default value made optional.- Upgraded host builder expression from
IWebHostBuildetoWebApplication.
Falco.Markup, module has been extracted into it's own project.- Additional
StringCollectionReaderconstructors, per-collection type. StringCollectionReader.TryArrayString, useStringCollectionReader.GetStringArrayStringCollectionReader.TryArrayInt16, useStringCollectionReader.GetInt16ArrayStringCollectionReader.TryArrayInt32, useStringCollectionReader.GetInt32ArrayStringCollectionReader.TryArrayInt, useStringCollectionReader.GetIntArrayStringCollectionReader.TryArrayInt64, useStringCollectionReader.GetInt64ArrayStringCollectionReader.TryArrayBoolean, useStringCollectionReader.GetBooleanArrayStringCollectionReader.TryArrayFloat, useStringCollectionReader.GetFloatArrayStringCollectionReader.TryArrayDecimal, useStringCollectionReader.GetDecimalArrayStringCollectionReader.TryArrayDateTime, useStringCollectionReader.GetDateTimeArrayStringCollectionReader.TryArrayDateTimeOffset, useStringCollectionReader.GetDateTimeOffsetArrayStringCollectionReader.TryArrayGuid, useStringCollectionReader.GetGuidArrayStringCollectionReader.TryArrayTimeSpan, useStringCollectionReader.GetTimeSpanArrayHttpRequest.IsMultipart,HttpRequest.TryStreamFormAsync, useHttpRequest.StreamFormAsync()Request.tryBindRoute, useRequest.getRoute.Request.tryBindQuery, useRequest.getQuery.Request.tryBindForm, useRequest.getForm.Request.tryBindFormStream, useRequest.tryStreamForm.Request.tryBindCookie, useRequest.getCookie.Request.getJson, useRequest.getJsonOptions Constants.defaultJsonOptions.Request.tryBindJsonOptions, useRequest.getJsonOptions.Request.tryBindJson, useRequest.getJsonOptions Constants.defaultJsonOptions.Request.bindJson, useRequest.mapJson.Request.bindRoute, useRequest.mapRoute.Request.bindQuery, useRequest.mapQuery.Request.bindCookie, useRequest.mapCookie.Request.bindForm, useRequest.mapForm.Request.bindFormStream, useRequest.mapFormStream.Request.bindFormSecure, useRequest.mapFormSecure.Request.bindFormStreamSecure, useRequest.mapFormStreamSecure.Response.withHeader, useResponse.withHeaders [ x ].Response.redirect, useResponse.redirectTemporarilyorResponse.redirectPermanently
- Embedded readme and project icon into NuGet package.
- Additional obsolete attributes to functions in preparation for v4.x.
Request.mapJsonfailing to invoke next handler, caused by a bad merge which left the valid function body commented out.
- Obsolete attributes to `Request.bind{Json|Route|Query|Cookie|Form|FormStream|FormSecure|FormStreamSecure} functions in preparation for v4.x.
- Typo in
Markup.Attr.httpEquiv.
Auth.signInOptionsto establish an authenticated context for the provide scheme, options and principalMarkup.Attr.open'.- Missing .gitignore items for JetBrains.
Auth.challengeto challenge the specified authentication scheme.Response.challengeWithRedirectto challenge the specified authentication scheme and redirect URI.
- Website to address certain accessibility issues.
- Incorporated built-in
System.Taskexpression, with compiler directives to continue supporting Ply usage.
StringCollectionReaderlookups made case-insensitive.
net6.0support.
- Embedded PDBs to faciliate sourcelink.
HttpVerb.toHttpMethodMetadatato properly capture theHttpVerb.ANYto produce an emptyHttpMethodData(notHttpMethodData [| "ANY" |]).
- Mistakenly added, experimental
Request.signOutfunction.
- Route name metadata to support ASP.NET link generator.
- Null check to internal
Response.writeString. - Explicit starting size for the internal
StringBuilderwithinXmlNodeSerializer
- Comparative view engine benchmarks.
XmlNodeSerializertype.- Source link support.
- Dependency on Ply.
Request.authenticateto authenticate the current request using the provided scheme.
- TPL helpers.
- CSRF validation switched to occur after form is streamed, which includes enabling buffering for the request body.
stringffunction.
- Dependency on Taskbuilder.fs, replaced with TPL helpers.
FalcoEndpointDataSourceto properly integrate with ASP.NET endpoint routing.- Binary response handlers
Response.ofBinary,Response.ofAttachment. IConfigurationbuilder expression with JSON input hooks.Auth.getClaimValueIServiceCollectionoperations to the HostBuilder expression:add_service,add_antiforgery,add_cookie,add_conf_cookies,add_authorization,add_data_protection,add_http_client.IApplicationBuilderoperations to the HostBuilder expression:use_middleware,use_if,use_ifnot,use_authentication,use_authorization,use_caching,use_compression,use_hsts,use_https,use_static_files.not_foundoperation added to HostBuilder expression to serve default document when no endpoints are matched.
- Internal
Response.writeBytesto useBodyWriter.
- Optional JSON config file fix, misassigned.
- MVC and REST templates
- PowerShell website build script.
- Null reference exception when consuming
IFormCollection.Files.
Response.signInAndRedirect.IEndpointRouteBuilderextension methodUserFalcoEndpoints.
Auth.hasScope,Auth.tryFindClaim,Auth.getClaim.Request.ifAuthenticatedWithScope.CookieCollectionReader, accessible getRequest.getCookie,Request.tryBindCookie,Request.bindCookie,Request.mapCookie.StringUtils.strSplit.
Markup.Elem.form,Markup.Elem.button,Markup.Elem.script
Markup.Templates.html5not using provided language code.
net5.0support.IHostbuilder expression,webHost [||] {}.IServiceCollection.AddFalco.IServiceCollection.AddFalco (routeOptions : RouteOptions -> unit).IApplicationBuilder.UseFalco (endpoints : HttpEndpoint list).IApplicationBuilder.UseFalcoExceptionHandler (exceptionHandler : HttpHandler).QueryCollectionReader.HeaderCollectionReader.RouteCollectionReader.
- Extensions,
HttpRequest.GetHeader,HttpRequest.GetRouteValues,HttpRequest.GetRouteReader. - Exceptions.
ExceptionHandler,ExceptionHandlingMiddleware. - Host module,
Host.defaultExceptionHandler,Host.defaultNotFoundHandler,Host.startWebHostDefault,Host.startWebHost. IApplicationBuilder.UseHttpEndpoints (endpoints : HttpEndpoint list)replaced byIApplicationBuilder.UseFalco (endpoints : HttpEndpoint list).Request.getHeader,Request.getRouteValuesreplaced byRequest.getRoute,Request.tryGetRouteValue.StringCollectionReader? dynamic operator
- Multimethod
HttpEndpointsupport. StringCollectionReader.TryGetStringNonEmptywhich returnsNonefor empty, whitespace and null value strings.
Request.tryBindRoute,Request.mapRouteandRequest.bindRoute.Request.bindQuery.Request.bindJsonwhich usesSystem.Text.Json.
- Dependency on Taskbuilder.fs, with internal extesion for
Task<unit> -> Taskconversion.
Request.validateCsrfTokenwhich usesMicrosoft.AspNetCore.Antiforgery.Response.ofJsonwhich usesSystem.Text.Jsonand referencesConstants.defaultJsonOptions.Response.ofEmpty.
- Parameter ordering for
Response.withCookieOptions,Response.ofJsonOptionsto ensure configuration uniformly occured first.
-
HttpResponseModifierdefined asHttpContext -> HttpContextused to make non-IO modifications to theHttpResponse. -
ResponseandRequestmodules, which provide functional access to theHttpResponseandHttpRequestrespectively.Response.redirectResponse.withHeaderResponse.withContentLengthResponse.withContentTypeResponse.withStatusCodeResponse.withCookieResponse.withCookieOptionsResponse.ofStringResponse.ofPlainTextResponse.ofHtmlResponse.ofJsonResponse.ofJsonOptionsRequest.getVerbRequest.getRouteValuesRequest.tryGetRouteValueRequest.getQueryRequest.tryBindQueryRequest.getFormRequest.tryBindFormRequest.tryStreamFormRequest.tryBindJsonRequest.tryBindJsonOptions
HttpHandlerdefinition changed toHttpContext -> Task.Falco.ViewEnginebecomesFalco.Markup- Markup functions are now fully qualified (i.e.,
Elem.h1instead ofh1). - `webApp
Still kicking myself over this brainfart. Starting version 1.1 for the win 🙄.