Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Target net 8.0 #788

Merged
merged 1 commit into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
"isRoot": true,
"tools": {
"paket": {
"version": "7.2.0",
"version": "8.0.3",
"commands": [
"paket"
]
},
"fake-cli": {
"version": "6.0.0",
"version": "6.1.1",
"commands": [
"fake"
]
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build-suave.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: 7.0.200
dotnet-version: 8.0.401
- name: Build
run: ./build.sh
997 changes: 500 additions & 497 deletions .paket/Paket.Restore.targets

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions build/build.fs
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,15 @@ let initTargets () =

Target.create "Tests" <| fun _ ->
let path = "src" </> "Suave.Tests"
let res = DotNet.exec id "run" (sprintf "-c Release --framework net7.0 --project %s -- --summary --sequenced" path)
let res = DotNet.exec id "run" (sprintf "-c Release --framework net8.0 --project %s -- --summary --sequenced" path)
if not res.OK then
res.Errors |> Seq.iter (eprintfn "%s")
failwith "Tests failed."

// Requires `httperf` installed on the server (only linux atm)
Target.create "Load" <| fun _ ->
let path = "examples" </> "Pong"
let res = DotNet.exec id "run" (sprintf "-c Release --framework net7.0 --project %s" path)
let res = DotNet.exec id "run" (sprintf "-c Release --framework net8.0 --project %s" path)
if not res.OK then
res.Errors |> Seq.iter (eprintfn "%s")
failwith "Tests failed."
Expand Down
2 changes: 1 addition & 1 deletion examples/CORS/CORS.fsproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net7.0</TargetFrameworks>
<TargetFrameworks>net8.0</TargetFrameworks>
<OutputType>Exe</OutputType>
<AssemblyName>CORS</AssemblyName>
</PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion examples/Example/Example.fsproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net7.0</TargetFrameworks>
<TargetFrameworks>net8.0</TargetFrameworks>
<OutputType>Exe</OutputType>
<AssemblyName>Example</AssemblyName>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
Expand Down
2 changes: 1 addition & 1 deletion examples/Fibonacci/Fibonacci.fsproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net7.0</TargetFrameworks>
<TargetFrameworks>net8.0</TargetFrameworks>
<OutputType>Exe</OutputType>
<AssemblyName>Fibonacci</AssemblyName>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
Expand Down
2 changes: 1 addition & 1 deletion examples/Load/Load.fsproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net7.0</TargetFrameworks>
<TargetFrameworks>net8.0</TargetFrameworks>
<OutputType>Exe</OutputType>
<AssemblyName>Load</AssemblyName>
</PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion examples/Pong/Pong.fsproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<OutputType>Exe</OutputType>
<AssemblyName>Pong</AssemblyName>
</PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion examples/Stream/Stream.fsproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<OutputType>Exe</OutputType>
<AssemblyName>Stream</AssemblyName>
</PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion examples/WebSocket/WebSocket.fsproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<OutputType>Exe</OutputType>
<AssemblyName>WebSocket</AssemblyName>
</PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{ "sdk": { "version": "7.0.200" } }
{ "sdk": { "version": "8.0.401" } }
7 changes: 4 additions & 3 deletions paket.dependencies
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
version 5.249.0

source https://api.nuget.org/v3/index.json
framework net7.0
framework net8.0
storage none

nuget FSharp.Core
nuget Microsoft.Extensions.FileProviders.Embedded
nuget System.IO.Pipelines
nuget System.Text.Json
nuget DotLiquid
nuget Websocket.Client
nuget FsCheck
Expand All @@ -16,7 +17,7 @@ nuget Expecto.BenchmarkDotNet

group Examples
source https://api.nuget.org/v3/index.json
framework net7.0
framework net8.0
nuget FSharp.Core
nuget Topshelf.FSharp
nuget Topshelf
Expand All @@ -25,7 +26,7 @@ group Examples

group Docs
source https://api.nuget.org/v3/index.json
framework net7.0
framework net8.0

nuget Argu
nuget FSharp.Core
Expand Down
9 changes: 6 additions & 3 deletions paket.lock
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
STORAGE: NONE
RESTRICTION: == net7.0
RESTRICTION: == net8.0
NUGET
remote: https://api.nuget.org/v3/index.json
BenchmarkDotNet (0.13.12)
Expand Down Expand Up @@ -80,6 +80,9 @@ NUGET
System.Runtime.CompilerServices.Unsafe (6.0)
System.Security.AccessControl (6.0.1)
System.Security.Principal.Windows (5.0)
System.Text.Encodings.Web (8.0)
System.Text.Json (8.0.4)
System.Text.Encodings.Web (>= 8.0)
System.Threading.Channels (8.0)
Websocket.Client (5.1.2)
Microsoft.Extensions.Logging.Abstractions (>= 8.0)
Expand All @@ -88,7 +91,7 @@ NUGET
System.Threading.Channels (>= 8.0)

GROUP Docs
RESTRICTION: == net7.0
RESTRICTION: == net8.0
NUGET
remote: https://api.nuget.org/v3/index.json
Argu (6.2.4)
Expand Down Expand Up @@ -152,7 +155,7 @@ NUGET
System.Text.Encodings.Web (>= 8.0)

GROUP Examples
RESTRICTION: == net7.0
RESTRICTION: == net8.0
NUGET
remote: https://api.nuget.org/v3/index.json
FSharp.Core (8.0.400)
Expand Down
2 changes: 1 addition & 1 deletion src/Suave.DotLiquid/Suave.DotLiquid.fsproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net7.0</TargetFrameworks>
<TargetFrameworks>net8.0</TargetFrameworks>
<AssemblyName>Suave.DotLiquid</AssemblyName>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/Suave.Experimental/Suave.Experimental.fsproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net7.0</TargetFrameworks>
<TargetFrameworks>net8.0</TargetFrameworks>
<AssemblyName>Suave.Experimental</AssemblyName>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/Suave.IO/Suave.IO.fsproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<AssemblyName>Suave.IO</AssemblyName>
<OutputType>Exe</OutputType>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
Expand Down
19 changes: 12 additions & 7 deletions src/Suave.Tests/Auth.fs
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,9 @@ let interact methd resource container ctx =
| true, values -> values |> Seq.iter (fun cookie -> container.SetCookies(endpointUri ctx.suaveConfig, cookie))
response

let sessionState f =
context( fun r ->
match HttpContext.state r with
| None -> RequestErrors.BAD_REQUEST "damn it"
| Some store -> f store )

[<Tests>]
let authTests cfg =
let runWithConfig = runWith cfg //{ cfg with logger = Targets.create Warn [||] }
let runWithConfig = runWith cfg
testList "auth tests" [
testCase "baseline, no auth cookie" <| fun _ ->
let ctx = runWithConfig (OK "ACK")
Expand Down Expand Up @@ -154,7 +148,18 @@ let authTests cfg =

use res''''' = interact HttpMethod.GET "/protected"
Expect.equal (contentString res''''') "please authenticate" "should not have access to protected after logout"
]

let sessionState f =
context(fun r ->
match HttpContext.state r with
| None -> RequestErrors.BAD_REQUEST "damn it"
| Some store -> f store )

[<Tests>]
let sessionTests cfg =
let runWithConfig = runWith cfg
testList "session tests" [
testCase "test session is maintained across requests" <| fun _ ->
// given
let ctx =
Expand Down
2 changes: 1 addition & 1 deletion src/Suave.Tests/Suave.Tests.fsproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net7.0</TargetFrameworks>
<TargetFrameworks>net8.0</TargetFrameworks>
<AssemblyName>Suave.Tests</AssemblyName>
<OutputType>Exe</OutputType>
<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
Expand Down
15 changes: 4 additions & 11 deletions src/Suave/CookieSerialiser.fs
Original file line number Diff line number Diff line change
@@ -1,22 +1,15 @@
namespace Suave

open System.IO
namespace Suave

type CookieSerialiser =
abstract serialise : Map<string, obj> -> byte []
abstract deserialise : byte [] -> Map<string, obj>

open System.Runtime.Serialization.Formatters.Binary
open System.Text.Json

type BinaryFormatterSerialiser() =
interface CookieSerialiser with
member x.serialise m =
use ms = new MemoryStream()
let f = new BinaryFormatter()
f.Serialize(ms, m)
ms.ToArray()
JsonSerializer.SerializeToUtf8Bytes<_>(m)

member x.deserialise data =
use ms = new MemoryStream(data)
let f = new BinaryFormatter()
f.Deserialize ms :?> _
JsonSerializer.Deserialize<_>(data)
74 changes: 4 additions & 70 deletions src/Suave/State.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ module Suave.State

open Suave.Cookie

open System.Text.Json

/// A session store is a reader and a writer function pair keyed on strings.
type StateStore =
/// Get an item from the state store
Expand Down Expand Up @@ -69,7 +71,6 @@ module CookieStateStore =
let m =
try
ctx.runtime.cookieSerialiser.deserialise data

with _ ->
Map.empty

Expand Down Expand Up @@ -123,9 +124,10 @@ module CookieStateStore =
serialiser.deserialise (ss :?> byte [])
with ex ->
Map.empty

map
|> Map.tryFind key
|> Option.map unbox
|> Option.map (fun z -> JsonSerializer.Deserialize(z :?> JsonElement))
member x.set key value =
let expiry = userState.[(StateStoreType + "-expiry")] :?> CookieLife
write expiry key value
Expand All @@ -139,71 +141,3 @@ module CookieStateStore =
match ctx.userState.TryGetValue StateStoreType with
| true, x -> Some (createStateStore ctx.runtime.cookieSerialiser ctx.userState x)
| _, _ -> None

#if SYSTEM_RUNTIME_CACHING
/// This module contains the implementation for the memory-cache backed session
/// state store, when the memory cache is global for the server.
module MemoryCacheStateStore =
open System
open System.Runtime.Caching
open System.Collections.Concurrent

/// This key will be present in HttpContext.userState and will contain the
/// MemoryCache instance.
[<Literal>]
let StateStoreType = "Suave.State.MemoryCacheStateStore"

[<Literal>]
let UserStateIdKey = "Suave.State.MemoryCacheStateStore-id"

[<Literal>]
let StateCookie = "mc-st"

module HttpContext =

/// Try to find the state id of the HttpContext.
let stateId ctx =
ctx.userState
|> Map.tryFind UserStateIdKey
|> Option.map (fun x -> x :?> string)
|> Option.get

/// Read the session store from the HttpContext.
let state (ctx : HttpContext) =
ctx.userState
|> Map.tryFind StateStoreType
|> Option.map (fun ss -> ss :?> StateStore)
|> Option.get

let private wrap (sessionMap : MemoryCache) relativeExpiry sessionId =
let exp = function
| Session -> CacheItemPolicy()
| MaxAge ts -> CacheItemPolicy(SlidingExpiration = ts)

let stateBag =
lock sessionMap (fun _->
if sessionMap.Contains sessionId then
sessionMap.Get sessionId
:?> ConcurrentDictionary<string, obj>
else
let cd = new ConcurrentDictionary<string, obj>()
sessionMap.Set(CacheItem(sessionId, cd), exp relativeExpiry)
cd)

{ new StateStore with
member x.get key =
if stateBag.ContainsKey key then
Some (stateBag.[key] :?> 'T)
else None
member x.set key value =
stateBag.[key] <- value
succeed }

let stateful relativeExpiry : WebPart =
let stateStore = wrap (MemoryCache.Default) relativeExpiry
context (fun ctx ->
let stateId = ctx |> HttpContext.stateId
Writers.setUserData StateStoreType (stateStore stateId))

let DefaultExpiry = TimeSpan.FromMinutes 30. |> MaxAge
#endif
2 changes: 1 addition & 1 deletion src/Suave/Suave.fsproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net7.0</TargetFrameworks>
<TargetFrameworks>net8.0</TargetFrameworks>
<AssemblyName>Suave</AssemblyName>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
Expand Down
1 change: 1 addition & 0 deletions src/Suave/paket.references
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
FSharp.Core
System.IO.Pipelines
System.Text.Json
Loading