{"action":"created","comment":{"url":"https://api.github.com/repos/SuaveIO/suave/pulls/comments/38324272","id":38324272,"diff_hunk":"@@ -148,5 +159,190 @@ let endToEnd =\n         | false, _ -> Tests.failtest \"X-Custom-After is missing\"\n \n       runWithConfig composedApp |> reqResp Types.GET \"/owin\" \"\" None None DecompressionMethods.GZip id asserts\n+\n+    testCase \"Custom status code\" <| fun _ ->\n+      let noContent (env : OwinEnvironment) =\n+        env.[OwinConstants.responseStatusCode] <- box 204\n+        //env.[OwinConstants.responseReasonPhrase] <- box \"Nothing to see here\"\n+        async.Return ()\n+\n+      let composedApp =\n+        path \"/owin\" >>= OwinApp.ofApp noContent\n+\n+      let asserts (result : HttpResponseMessage) =\n+        eq \"Http Status Code\" HttpStatusCode.NoContent result.StatusCode\n+        eq \"Reason Phrase\" \"Nothing to see here\" result.ReasonPhrase\n+\n+      runWithConfig composedApp |> reqResp Types.GET \"/owin\" \"\" None None DecompressionMethods.GZip id asserts\n+\n+    testCase \"Task signals completion with status code\" <| fun _ ->\n+      let noContent (env : OwinEnvironment) =\n+        env.[OwinConstants.responseStatusCode] <- box 204\n+        async.Return ()\n+\n+      let composedApp =\n+        path \"/owin\" >>= OwinApp.ofApp noContent\n+\n+      let asserts (result : HttpResponseMessage) =\n+        eq \"Http Status Code\" HttpStatusCode.NoContent result.StatusCode\n+        eq \"Reason Phrase set by server\" \"No Content\" result.ReasonPhrase\n+\n+      runWithConfig composedApp |> reqResp Types.GET \"/owin\" \"\" None None DecompressionMethods.GZip id asserts\n+\n+    testCase \"Task signals completion with status code and headers\" <| fun _ ->\n+      let noContent (env : OwinEnvironment) =\n+        env.[OwinConstants.responseStatusCode] <- box 204\n+        let responseHeaders : IDictionary<string, string[]> = unbox env.[OwinConstants.responseHeaders]\n+        responseHeaders.[\"Content-Type\"] <- [| \"text/plain; charset=utf-8\" |]\n+        async.Return ()\n+\n+      let composedApp =\n+        path \"/owin\" >>= OwinApp.ofApp noContent\n+\n+      let asserts (result : HttpResponseMessage) =\n+        eq \"Http Status Code\" HttpStatusCode.NoContent result.StatusCode\n+        eq \"Reason Phrase set by server\" \"No Content\" result.ReasonPhrase\n+        eq \"Content-Type\" \"text/plain; charset=utf-8\" (result.Content.Headers.ContentType.ToString())\n+\n+      runWithConfig composedApp |> reqResp Types.GET \"/owin\" \"\" None None DecompressionMethods.GZip id asserts\n+    \n+    testCase \"OWIN middleware run before OWIN app\" <| fun _ ->\n+      let noContent (env : OwinEnvironment) =\n+        env.[OwinConstants.responseStatusCode] <- box 204\n+        async.Return ()\n+      \n+      let basicAuthMidFunc = OwinMidFunc(fun next -> OwinAppFunc(fun env ->\n+          let requestHeaders : IDictionary<string, string[]> = unbox env.[OwinConstants.requestHeaders]\n+          let credentials = requestHeaders.[\"Authorization\"].[0].Split([|' '|]).[1].Split([|':'|])\n+          match credentials with\n+          | [|\"foo\";\"bar\"|] -> next.Invoke(env)\n+          | _ ->\n+            env.[OwinConstants.responseStatusCode] <- box 401\n+            Threading.Tasks.Task.FromResult() :> Threading.Tasks.Task\n+        ))\n+\n+      let composedApp =\n+        path \"/owin\"\n+          >>= OwinApp.ofMidFunc basicAuthMidFunc\n+          >>= OwinApp.ofApp noContent\n+\n+      let asserts (result : HttpResponseMessage) =\n+        eq \"Http Status Code\" HttpStatusCode.NoContent result.StatusCode\n+        eq \"Reason Phrase set by server\" \"No Content\" result.ReasonPhrase\n+\n+      let sendAuthHeader (req : HttpRequestMessage) =\n+        req.Headers.Authorization <- Net.Http.Headers.AuthenticationHeaderValue(\"Basic\", Convert.ToBase64String(\"foo:bar\"B))\n+        req\n+\n+      runWithConfig composedApp |> reqResp Types.GET \"/owin\" \"\" None None DecompressionMethods.GZip sendAuthHeader asserts\n+\n+    testCase \"OWIN middleware run after OWIN app\" <| fun _ ->\n+      let noContent (env : OwinEnvironment) =\n+        env.[OwinConstants.responseStatusCode] <- box 204\n+        async.Return ()\n+      \n+      let setCustomHeaderAfter = OwinMidFunc(fun next -> OwinAppFunc(fun env ->\n+          next.Invoke(env).ContinueWith(fun _ ->\n+            let responseHeaders : IDictionary<string, string[]> = unbox env.[OwinConstants.requestHeaders]\n+            responseHeaders.[\"X-Custom-After\"] <- [|\"After OWIN\"|]","path":"src/Suave.Tests/Owin.fs","position":114,"original_position":114,"commit_id":"6a1437e9d48adac03f184dc9cddc94358b4f311c","original_commit_id":"6a1437e9d48adac03f184dc9cddc94358b4f311c","user":{"login":"panesofglass","id":8803,"avatar_url":"https://avatars.githubusercontent.com/u/8803?v=3","gravatar_id":"","url":"https://api.github.com/users/panesofglass","html_url":"https://github.com/panesofglass","followers_url":"https://api.github.com/users/panesofglass/followers","following_url":"https://api.github.com/users/panesofglass/following{/other_user}","gists_url":"https://api.github.com/users/panesofglass/gists{/gist_id}","starred_url":"https://api.github.com/users/panesofglass/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/panesofglass/subscriptions","organizations_url":"https://api.github.com/users/panesofglass/orgs","repos_url":"https://api.github.com/users/panesofglass/repos","events_url":"https://api.github.com/users/panesofglass/events{/privacy}","received_events_url":"https://api.github.com/users/panesofglass/received_events","type":"User","site_admin":false},"body":"IIRC, this _should_ fail unless the middleware buffers the response itself. I need to double-check.","created_at":"2015-08-31T15:35:37Z","updated_at":"2015-08-31T15:35:37Z","html_url":"https://github.com/SuaveIO/suave/pull/295#discussion_r38324272","pull_request_url":"https://api.github.com/repos/SuaveIO/suave/pulls/295","_links":{"self":{"href":"https://api.github.com/repos/SuaveIO/suave/pulls/comments/38324272"},"html":{"href":"https://github.com/SuaveIO/suave/pull/295#discussion_r38324272"},"pull_request":{"href":"https://api.github.com/repos/SuaveIO/suave/pulls/295"}}},"pull_request":{"url":"https://api.github.com/repos/SuaveIO/suave/pulls/295","id":43727085,"html_url":"https://github.com/SuaveIO/suave/pull/295","diff_url":"https://github.com/SuaveIO/suave/pull/295.diff","patch_url":"https://github.com/SuaveIO/suave/pull/295.patch","issue_url":"https://api.github.com/repos/SuaveIO/suave/issues/295","number":295,"state":"open","locked":false,"title":"[owin] adding test cases","user":{"login":"panesofglass","id":8803,"avatar_url":"https://avatars.githubusercontent.com/u/8803?v=3","gravatar_id":"","url":"https://api.github.com/users/panesofglass","html_url":"https://github.com/panesofglass","followers_url":"https://api.github.com/users/panesofglass/followers","following_url":"https://api.github.com/users/panesofglass/following{/other_user}","gists_url":"https://api.github.com/users/panesofglass/gists{/gist_id}","starred_url":"https://api.github.com/users/panesofglass/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/panesofglass/subscriptions","organizations_url":"https://api.github.com/users/panesofglass/orgs","repos_url":"https://api.github.com/users/panesofglass/repos","events_url":"https://api.github.com/users/panesofglass/events{/privacy}","received_events_url":"https://api.github.com/users/panesofglass/received_events","type":"User","site_admin":false},"body":"Work in progress","created_at":"2015-08-31T02:24:47Z","updated_at":"2015-08-31T15:35:37Z","closed_at":null,"merged_at":null,"merge_commit_sha":"9043f52671c0ead4d03af3219ab2559b3cc87710","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/SuaveIO/suave/pulls/295/commits","review_comments_url":"https://api.github.com/repos/SuaveIO/suave/pulls/295/comments","review_comment_url":"https://api.github.com/repos/SuaveIO/suave/pulls/comments{/number}","comments_url":"https://api.github.com/repos/SuaveIO/suave/issues/295/comments","statuses_url":"https://api.github.com/repos/SuaveIO/suave/statuses/6a1437e9d48adac03f184dc9cddc94358b4f311c","head":{"label":"panesofglass:feature/owin-test","ref":"feature/owin-test","sha":"6a1437e9d48adac03f184dc9cddc94358b4f311c","user":{"login":"panesofglass","id":8803,"avatar_url":"https://avatars.githubusercontent.com/u/8803?v=3","gravatar_id":"","url":"https://api.github.com/users/panesofglass","html_url":"https://github.com/panesofglass","followers_url":"https://api.github.com/users/panesofglass/followers","following_url":"https://api.github.com/users/panesofglass/following{/other_user}","gists_url":"https://api.github.com/users/panesofglass/gists{/gist_id}","starred_url":"https://api.github.com/users/panesofglass/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/panesofglass/subscriptions","organizations_url":"https://api.github.com/users/panesofglass/orgs","repos_url":"https://api.github.com/users/panesofglass/repos","events_url":"https://api.github.com/users/panesofglass/events{/privacy}","received_events_url":"https://api.github.com/users/panesofglass/received_events","type":"User","site_admin":false},"repo":{"id":11205234,"name":"suave","full_name":"panesofglass/suave","owner":{"login":"panesofglass","id":8803,"avatar_url":"https://avatars.githubusercontent.com/u/8803?v=3","gravatar_id":"","url":"https://api.github.com/users/panesofglass","html_url":"https://github.com/panesofglass","followers_url":"https://api.github.com/users/panesofglass/followers","following_url":"https://api.github.com/users/panesofglass/following{/other_user}","gists_url":"https://api.github.com/users/panesofglass/gists{/gist_id}","starred_url":"https://api.github.com/users/panesofglass/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/panesofglass/subscriptions","organizations_url":"https://api.github.com/users/panesofglass/orgs","repos_url":"https://api.github.com/users/panesofglass/repos","events_url":"https://api.github.com/users/panesofglass/events{/privacy}","received_events_url":"https://api.github.com/users/panesofglass/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/panesofglass/suave","description":"Suave is a simple web development F# library providing a lightweight web server and a set of combinators to manipulate route flow and task composition.","fork":true,"url":"https://api.github.com/repos/panesofglass/suave","forks_url":"https://api.github.com/repos/panesofglass/suave/forks","keys_url":"https://api.github.com/repos/panesofglass/suave/keys{/key_id}","collaborators_url":"https://api.github.com/repos/panesofglass/suave/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/panesofglass/suave/teams","hooks_url":"https://api.github.com/repos/panesofglass/suave/hooks","issue_events_url":"https://api.github.com/repos/panesofglass/suave/issues/events{/number}","events_url":"https://api.github.com/repos/panesofglass/suave/events","assignees_url":"https://api.github.com/repos/panesofglass/suave/assignees{/user}","branches_url":"https://api.github.com/repos/panesofglass/suave/branches{/branch}","tags_url":"https://api.github.com/repos/panesofglass/suave/tags","blobs_url":"https://api.github.com/repos/panesofglass/suave/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/panesofglass/suave/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/panesofglass/suave/git/refs{/sha}","trees_url":"https://api.github.com/repos/panesofglass/suave/git/trees{/sha}","statuses_url":"https://api.github.com/repos/panesofglass/suave/statuses/{sha}","languages_url":"https://api.github.com/repos/panesofglass/suave/languages","stargazers_url":"https://api.github.com/repos/panesofglass/suave/stargazers","contributors_url":"https://api.github.com/repos/panesofglass/suave/contributors","subscribers_url":"https://api.github.com/repos/panesofglass/suave/subscribers","subscription_url":"https://api.github.com/repos/panesofglass/suave/subscription","commits_url":"https://api.github.com/repos/panesofglass/suave/commits{/sha}","git_commits_url":"https://api.github.com/repos/panesofglass/suave/git/commits{/sha}","comments_url":"https://api.github.com/repos/panesofglass/suave/comments{/number}","issue_comment_url":"https://api.github.com/repos/panesofglass/suave/issues/comments{/number}","contents_url":"https://api.github.com/repos/panesofglass/suave/contents/{+path}","compare_url":"https://api.github.com/repos/panesofglass/suave/compare/{base}...{head}","merges_url":"https://api.github.com/repos/panesofglass/suave/merges","archive_url":"https://api.github.com/repos/panesofglass/suave/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/panesofglass/suave/downloads","issues_url":"https://api.github.com/repos/panesofglass/suave/issues{/number}","pulls_url":"https://api.github.com/repos/panesofglass/suave/pulls{/number}","milestones_url":"https://api.github.com/repos/panesofglass/suave/milestones{/number}","notifications_url":"https://api.github.com/repos/panesofglass/suave/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/panesofglass/suave/labels{/name}","releases_url":"https://api.github.com/repos/panesofglass/suave/releases{/id}","created_at":"2013-07-05T17:52:47Z","updated_at":"2014-12-26T20:21:33Z","pushed_at":"2015-08-31T15:33:57Z","git_url":"git://github.com/panesofglass/suave.git","ssh_url":"git@github.com:panesofglass/suave.git","clone_url":"https://github.com/panesofglass/suave.git","svn_url":"https://github.com/panesofglass/suave","homepage":"http://ademar.name/","size":7243,"stargazers_count":0,"watchers_count":0,"language":"F#","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":0,"forks":1,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"SuaveIO:feature/owin","ref":"feature/owin","sha":"57c125b26f528645e998b150b137c0c5f45562d4","user":{"login":"SuaveIO","id":5822862,"avatar_url":"https://avatars.githubusercontent.com/u/5822862?v=3","gravatar_id":"","url":"https://api.github.com/users/SuaveIO","html_url":"https://github.com/SuaveIO","followers_url":"https://api.github.com/users/SuaveIO/followers","following_url":"https://api.github.com/users/SuaveIO/following{/other_user}","gists_url":"https://api.github.com/users/SuaveIO/gists{/gist_id}","starred_url":"https://api.github.com/users/SuaveIO/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SuaveIO/subscriptions","organizations_url":"https://api.github.com/users/SuaveIO/orgs","repos_url":"https://api.github.com/users/SuaveIO/repos","events_url":"https://api.github.com/users/SuaveIO/events{/privacy}","received_events_url":"https://api.github.com/users/SuaveIO/received_events","type":"Organization","site_admin":false},"repo":{"id":755200,"name":"suave","full_name":"SuaveIO/suave","owner":{"login":"SuaveIO","id":5822862,"avatar_url":"https://avatars.githubusercontent.com/u/5822862?v=3","gravatar_id":"","url":"https://api.github.com/users/SuaveIO","html_url":"https://github.com/SuaveIO","followers_url":"https://api.github.com/users/SuaveIO/followers","following_url":"https://api.github.com/users/SuaveIO/following{/other_user}","gists_url":"https://api.github.com/users/SuaveIO/gists{/gist_id}","starred_url":"https://api.github.com/users/SuaveIO/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SuaveIO/subscriptions","organizations_url":"https://api.github.com/users/SuaveIO/orgs","repos_url":"https://api.github.com/users/SuaveIO/repos","events_url":"https://api.github.com/users/SuaveIO/events{/privacy}","received_events_url":"https://api.github.com/users/SuaveIO/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/SuaveIO/suave","description":"Suave is a simple web development F# library providing a lightweight web server and a set of combinators to manipulate route flow and task composition.","fork":false,"url":"https://api.github.com/repos/SuaveIO/suave","forks_url":"https://api.github.com/repos/SuaveIO/suave/forks","keys_url":"https://api.github.com/repos/SuaveIO/suave/keys{/key_id}","collaborators_url":"https://api.github.com/repos/SuaveIO/suave/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/SuaveIO/suave/teams","hooks_url":"https://api.github.com/repos/SuaveIO/suave/hooks","issue_events_url":"https://api.github.com/repos/SuaveIO/suave/issues/events{/number}","events_url":"https://api.github.com/repos/SuaveIO/suave/events","assignees_url":"https://api.github.com/repos/SuaveIO/suave/assignees{/user}","branches_url":"https://api.github.com/repos/SuaveIO/suave/branches{/branch}","tags_url":"https://api.github.com/repos/SuaveIO/suave/tags","blobs_url":"https://api.github.com/repos/SuaveIO/suave/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/SuaveIO/suave/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/SuaveIO/suave/git/refs{/sha}","trees_url":"https://api.github.com/repos/SuaveIO/suave/git/trees{/sha}","statuses_url":"https://api.github.com/repos/SuaveIO/suave/statuses/{sha}","languages_url":"https://api.github.com/repos/SuaveIO/suave/languages","stargazers_url":"https://api.github.com/repos/SuaveIO/suave/stargazers","contributors_url":"https://api.github.com/repos/SuaveIO/suave/contributors","subscribers_url":"https://api.github.com/repos/SuaveIO/suave/subscribers","subscription_url":"https://api.github.com/repos/SuaveIO/suave/subscription","commits_url":"https://api.github.com/repos/SuaveIO/suave/commits{/sha}","git_commits_url":"https://api.github.com/repos/SuaveIO/suave/git/commits{/sha}","comments_url":"https://api.github.com/repos/SuaveIO/suave/comments{/number}","issue_comment_url":"https://api.github.com/repos/SuaveIO/suave/issues/comments{/number}","contents_url":"https://api.github.com/repos/SuaveIO/suave/contents/{+path}","compare_url":"https://api.github.com/repos/SuaveIO/suave/compare/{base}...{head}","merges_url":"https://api.github.com/repos/SuaveIO/suave/merges","archive_url":"https://api.github.com/repos/SuaveIO/suave/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/SuaveIO/suave/downloads","issues_url":"https://api.github.com/repos/SuaveIO/suave/issues{/number}","pulls_url":"https://api.github.com/repos/SuaveIO/suave/pulls{/number}","milestones_url":"https://api.github.com/repos/SuaveIO/suave/milestones{/number}","notifications_url":"https://api.github.com/repos/SuaveIO/suave/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/SuaveIO/suave/labels{/name}","releases_url":"https://api.github.com/repos/SuaveIO/suave/releases{/id}","created_at":"2010-07-03T15:26:06Z","updated_at":"2015-08-31T15:14:38Z","pushed_at":"2015-08-31T15:33:57Z","git_url":"git://github.com/SuaveIO/suave.git","ssh_url":"git@github.com:SuaveIO/suave.git","clone_url":"https://github.com/SuaveIO/suave.git","svn_url":"https://github.com/SuaveIO/suave","homepage":"http://suave.io","size":11381,"stargazers_count":296,"watchers_count":296,"language":"F#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":56,"mirror_url":null,"open_issues_count":46,"forks":56,"open_issues":46,"watchers":296,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/SuaveIO/suave/pulls/295"},"html":{"href":"https://github.com/SuaveIO/suave/pull/295"},"issue":{"href":"https://api.github.com/repos/SuaveIO/suave/issues/295"},"comments":{"href":"https://api.github.com/repos/SuaveIO/suave/issues/295/comments"},"review_comments":{"href":"https://api.github.com/repos/SuaveIO/suave/pulls/295/comments"},"review_comment":{"href":"https://api.github.com/repos/SuaveIO/suave/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/SuaveIO/suave/pulls/295/commits"},"statuses":{"href":"https://api.github.com/repos/SuaveIO/suave/statuses/6a1437e9d48adac03f184dc9cddc94358b4f311c"}}}}