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

Code scanning fix patches #638

Merged
merged 5 commits into from
Jan 28, 2025
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
12 changes: 10 additions & 2 deletions src/Giraffe/RequestLimitation.fs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,16 @@ let mustAcceptAny (mimeTypes: string list) (optionalErrorHandler: OptionalErrorH
)
)

let mimeTypesSet = Set.ofList mimeTypes

match Option.ofObj (headers.Accept :> _ seq) with
| Some xs when Seq.map (_.ToString()) xs |> Seq.exists (fun x -> Seq.contains x mimeTypes) -> next ctx
| Some xs when
Seq.map (_.ToString()) xs
|> Set.ofSeq
|> Set.intersect mimeTypesSet
|> (Set.isEmpty >> not)
->
next ctx
| Some xs when Seq.isEmpty xs -> headerNotFoundHandler earlyReturn ctx
| Some _ -> invalidHeaderValueHandler earlyReturn ctx
| None -> headerNotFoundHandler earlyReturn ctx
Expand Down Expand Up @@ -75,7 +83,7 @@ let hasAnyContentTypes (contentTypes: string list) (optionalErrorHandler: Option
)

match Option.ofObj ctx.Request.ContentType with
| Some header when Seq.contains header contentTypes -> next ctx
| Some header when List.contains header contentTypes -> next ctx
| Some header when String.IsNullOrEmpty header -> headerNotFoundHandler earlyReturn ctx
| Some _ -> invalidHeaderValueHandler earlyReturn ctx
| None -> headerNotFoundHandler earlyReturn ctx
Expand Down
10 changes: 6 additions & 4 deletions src/Giraffe/ResponseCaching.fs
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,16 @@ module ResponseCaching =
| Public duration -> tHeaders.CacheControl <- cacheHeader true duration
| Private duration -> tHeaders.CacheControl <- cacheHeader false duration

if vary.IsSome then
headers.[HeaderNames.Vary] <- StringValues [| vary.Value |]
vary
|> Option.iter (fun value -> headers.[HeaderNames.Vary] <- StringValues [| value |])

if varyByQueryKeys.IsSome then
varyByQueryKeys
|> Option.iter (fun value ->
let responseCachingFeature = ctx.Features.Get<IResponseCachingFeature>()

if isNotNull responseCachingFeature then
responseCachingFeature.VaryByQueryKeys <- varyByQueryKeys.Value
responseCachingFeature.VaryByQueryKeys <- value
)

next ctx

Expand Down
1 change: 1 addition & 0 deletions tests/Giraffe.Tests/Giraffe.Tests.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<Compile Include="HttpHandlerTests.fs" />
<Compile Include="RoutingTests.fs" />
<Compile Include="RequestLimitationTests.fs" />
<Compile Include="ResponseCachingTests.fs" />
<Compile Include="EndpointRoutingTests.fs" />
<Compile Include="AuthTests.fs" />
<Compile Include="ModelBindingTests.fs" />
Expand Down
51 changes: 51 additions & 0 deletions tests/Giraffe.Tests/ResponseCachingTests.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
module Giraffe.Tests.ResponseCachingTests

open System
open System.IO
open Microsoft.AspNetCore.Http
open Microsoft.Net.Http.Headers
open Microsoft.Extensions.Primitives
open Giraffe
open NSubstitute
open Xunit

// ---------------------------------
// Request caching tests
// ---------------------------------

[<Fact>]
let ``responseCaching is updating 'vary' response header`` () =
let ctx = Substitute.For<HttpContext>()

let responseCachingMiddleware: HttpHandler =
responseCaching
(Public(TimeSpan.FromSeconds(float 30)))
(Some "Accept, Accept-Encoding")
(Some [| "query1"; "query2" |])

let app =
GET
>=> route "/ok"
>=> responseCachingMiddleware
>=> setStatusCode 200
>=> text "ok"

ctx.Request.Method.ReturnsForAnyArgs "GET" |> ignore
ctx.Request.Path.ReturnsForAnyArgs("/ok") |> ignore
ctx.Response.Headers.ReturnsForAnyArgs(new HeaderDictionary()) |> ignore
ctx.Response.Body <- new MemoryStream()

task {
let! result = app next ctx

match result with
| None -> assertFail "Non expected result"
| Some ctx ->
Assert.Equal(StatusCodes.Status200OK, ctx.Response.StatusCode)

let expectedVaryHeader = StringValues [| "Accept, Accept-Encoding" |] |> string
Assert.Equal(string ctx.Response.Headers.[HeaderNames.Vary], expectedVaryHeader)

let expectedBody = "ok"
Assert.Equal(expectedBody, getBody ctx)
}
Loading