Skip to content

Commit

Permalink
Merge pull request #1744 from riganti/support-classic-post-forms
Browse files Browse the repository at this point in the history
Add back support for manually handling POST requests
  • Loading branch information
tomasherceg authored Dec 1, 2023
2 parents ba3e3ca + a41d4e4 commit 778f878
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 5 deletions.
7 changes: 2 additions & 5 deletions src/Framework/Framework/Hosting/DotvvmPresenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -478,11 +478,8 @@ async Task RespondWithStaticCommandValidationFailure(ActionInfo action, IDotvvmR
async Task ValidateSecFetchHeaders(IDotvvmRequestContext context)
{
var route = context.Route?.RouteName;
var isPost = context.HttpContext.Request.Method switch {
"POST" => true,
"GET" => false,
_ => throw new NotSupportedException()
};
var requestType = DotvvmRequestContext.DetermineRequestType(context.HttpContext);
var isPost = requestType is DotvvmRequestType.Command or DotvvmRequestType.StaticCommand;
var checksAllowed = (isPost ? SecurityConfiguration.VerifySecFetchForCommands : SecurityConfiguration.VerifySecFetchForPages).IsEnabledForRoute(route);
var dest = context.HttpContext.Request.Headers["Sec-Fetch-Dest"];
var site = context.HttpContext.Request.Headers["Sec-Fetch-Site"];
Expand Down
3 changes: 3 additions & 0 deletions src/Framework/Framework/Hosting/DotvvmRequestContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ public static DotvvmRequestType DetermineRequestType(IHttpContext context)
{
return DotvvmRequestType.Command;
}
// Unknown POST request is treated as a Navigate request
// it is useful for submitting classic <form method=POST> elements (as a no-JS fallback, login forms, etc.)
return DotvvmRequestType.Navigate;
}
return DotvvmRequestType.Unknown;
}
Expand Down
1 change: 1 addition & 0 deletions src/Samples/Common/DotVVM.Samples.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Web" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Views\FeatureSamples\ViewModules\LinkModuleControl.dotcontrol" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using DotVVM.Framework.ViewModel;

namespace DotVVM.Samples.BasicSamples.ViewModels.FeatureSamples.NoJsForm
{
public class NoJsFormViewModel : DotvvmViewModelBase
{
public string Form1Value { get; set; }
public string Form2Value { get; set; }

public override async Task Load()
{
var req = Context.HttpContext.Request;
if (req.Method == "POST")
{
using var body = new StreamReader(req.Body);
var data = HttpUtility.ParseQueryString(await body.ReadToEndAsync());
var submit = data["submit"];
if (submit == "form1")
{
Form1Value = data["text"];
}
else if (submit == "form2")
{
Form2Value = data["text"];
}
}
}
}
}

35 changes: 35 additions & 0 deletions src/Samples/Common/Views/FeatureSamples/NoJsForm/NoJsForm.dothtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
@viewModel DotVVM.Samples.BasicSamples.ViewModels.FeatureSamples.NoJsForm.NoJsFormViewModel, DotVVM.Samples.Common

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<div RenderSettings.Mode=Server>
<fieldset>
<legend>Form 1</legend>
<form method="POST">
<input id=input1 type="text" name="text" />
<button id=submit1 type=submit name=submit value=form1>Submit</button>

<p Visible={value: Form1Value != null}>
Last submitted value: <span id=result1>{{value: Form1Value}}</span>
</p>
</form>
</fieldset>

<fieldset>
<legend>Form 2</legend>
<form method="POST">
<input id=input2 type="text" name="text" />
<button id=submit2 type=submit name=submit value=form2>Submit</button>

<p Visible={value: Form2Value != null}>
Last submitted value: <span id=result2>{{value: Form2Value}}</span>
</p>
</form>
</fieldset>
</div>
</body>
</html>

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 35 additions & 0 deletions src/Samples/Tests/Tests/Feature/NoJsFormTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Text;
using DotVVM.Samples.Tests.Base;
using DotVVM.Testing.Abstractions;
using Riganti.Selenium.Core;
using Riganti.Selenium.DotVVM;
using Xunit;
using Xunit.Abstractions;

namespace DotVVM.Samples.Tests.Feature
{
public class NoJsFormTests : AppSeleniumTest
{
[Fact]
public void Feature_NoJsForm_NoJsForm()
{
RunInAllBrowsers(browser => {
browser.NavigateToUrl(SamplesRouteUrls.FeatureSamples_NoJsForm_NoJsForm);

browser.SendKeys("#input1", "Q");
browser.Click("#submit1");
AssertUI.InnerTextEquals(browser.First("#result1"), "Q");

browser.SendKeys("#input2", "W");
browser.Click("#submit2");
AssertUI.InnerTextEquals(browser.First("#result2"), "W");
});
}

public NoJsFormTests(ITestOutputHelper output) : base(output)
{
}
}
}

0 comments on commit 778f878

Please sign in to comment.