Reading body() before or after form() is not consistent across all servers
Maintainer antworten meist innerhalb von 1 Tag
Ein zugehöriger Pull Request wurde bereits gemerged.
- #4034 von @jknack — gemerged
Bewertung
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Anfängerfreundlichkeit
- 48/100
Rechercherichtung
The report identifies ctx.body().value() and ctx.form()/ctx.formMap() in a ServerTest that runs against Undertow and Jetty. Start by tracing how each server handles form parsing and body access, then run the supplied test against both servers. Done means the call order behaves consistently across both servers, or the server difference is documented.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
I was replacing jooby-undertow with jooby-jetty and I am getting different behaviour due to making a call to ctx.body().value() before ctx.form().toMap()
I expected this to be consistent across different servers, or at least for this difference to be documented.
/*
* Jooby https://jooby.io
* Apache License Version 2.0 https://jooby.io/LICENSE.txt
* Copyright 2014 Edgar Espina
*/
package io.jooby.test;
import io.jooby.exception.MissingValueException;
import io.jooby.junit.ServerTest;
import io.jooby.junit.ServerTestRunner;
import java.util.Map;
import okhttp3.FormBody;
import org.junit.jupiter.api.Assertions;
class IssueBodyVsForm {
@ServerTest
public void formDataAndQueryParameters(ServerTestRunner runner) {
runner
.define(
app ->
app.post(
"/",
ctx -> {
try {
Assertions.assertAll(() -> {
Assertions.assertEquals(1, ctx.form().size(), "form contains one entry");
Assertions.assertTrue(ctx.form().isPresent());
Assertions.assertFalse(ctx.form().isMissing());
Assertions.assertEquals("bar", ctx.form().get("foo").value());
Assertions.assertEquals("bar", ctx.form("foo").value());
Assertions.assertEquals("bar", ctx.form().toMap().get("foo"));
Assertions.assertEquals("bar", ctx.formMap().get("foo"));
Assertions.assertEquals("?parameter1=value1", ctx.query().queryString());
Assertions.assertEquals("parameter1=value1", ctx.query().value());
Assertions.assertEquals("value1", ctx.query("parameter1").value());
Assertions.assertEquals("value1", ctx.queryMap().get("parameter1"));
Assertions.assertEquals(1, ctx.queryMap().size());
});
return "OK";
} catch (Exception ex){
ex.printStackTrace();
ctx.setResponseCode(500);
return ex.getMessage();
}
}))
.ready(
http ->
http
.post(
"/",
new FormBody.Builder().add("foo", "bar").build(),
Map.of("parameter1", "value1"),
rsp -> {
Assertions.assertEquals("OK", rsp.body().string());
Assertions.assertEquals(200, rsp.code());
}));
}
@ServerTest
public void readFormDataBeforeBody(ServerTestRunner runner) {
runner
.define(
app ->
app.post(
"/",
ctx -> {
try {
Assertions.assertAll(() -> {
Assertions.assertEquals(1, ctx.form().size(), "form contains one entry");
Assertions.assertTrue(ctx.form().isPresent());
Assertions.assertFalse(ctx.form().isMissing());
Assertions.assertEquals("bar", ctx.form().get("foo").value());
Assertions.assertEquals("bar", ctx.form("foo").value());
Assertions.assertEquals("bar", ctx.form().toMap().get("foo"));
Assertions.assertEquals("bar", ctx.formMap().get("foo"));
// get body().value() after calling form methods
Assertions.assertThrows(MissingValueException.class, () -> ctx.body().value());
});
return "OK";
} catch (Exception ex){
ex.printStackTrace();
ctx.setResponseCode(500);
return ex.getMessage();
}
}))
.ready(
http ->
http
.post(
"/",
new FormBody.Builder().add("foo", "bar").build(),
rsp -> {
Assertions.assertEquals("OK", rsp.body().string());
Assertions.assertEquals(200, rsp.code());
}));
}
@ServerTest
public void readFormDataAfterBody(ServerTestRunner runner) {
runner
.define(
app ->
app.post(
"/",
ctx -> {
try {
Assertions.assertAll(() -> {
// get body().value() before calling form methods
Assertions.assertThrows(MissingValueException.class, () -> ctx.body().value());
Assertions.assertEquals(1, ctx.form().size(), "form contains one entry");
Assertions.assertTrue(ctx.form().isPresent());
Assertions.assertFalse(ctx.form().isMissing());
Assertions.assertEquals("bar", ctx.form().get("foo").value());
Assertions.assertEquals("bar", ctx.form("foo").value());
Assertions.assertEquals("bar", ctx.form().toMap().get("foo"));
Assertions.assertEquals("bar", ctx.formMap().get("foo"));
});
return "OK";
} catch (Exception ex){
ex.printStackTrace();
ctx.setResponseCode(500);
return ex.getMessage();
}
}))
.ready(
http ->
http
.post(
"/",
new FormBody.Builder().add("foo", "bar").build(),
rsp -> {
Assertions.assertEquals("OK", rsp.body().string());
Assertions.assertEquals(200, rsp.code());
}));
}
}
- Vorherrschende Sprache
- Java
- Sterne
- 1.8k
- Forks
- 205
- Ø Merge
- 1 T. 8 Std.
- Gemergte PRs (30 T.)
- 20
Entwicklungsumgebung
- Enthält ein Dockerfile oder eine Docker-Compose-Datei
- Keine Pull-Request-Vorlage
- Kein Beitragsleitfaden
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus jooby-project/jooby
-
Schwierigkeit 5/5 Über eine Woche Anfängerfreundlichkeit 25/100
jooby-project/jooby#4021 · 5 Kommentare ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 38/100
jooby-project/jooby#3766 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Add Jooby CLI to SDKMANOffen
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 25/100
jooby-project/jooby#3521 · 2 Kommentare ·
Maintainer antworten meist innerhalb von 1 Tag
-
jooby-1.x are brokenOffenquestion
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 35/100
jooby-project/jooby#1513 · 10 Kommentare ·
Maintainer antworten meist innerhalb von 1 Tag
Alle Issues in jooby-project/jooby
Ähnliche Issues
-
BindingServiceProperties.bindings regressed to a non-thread-safe TreeMap in GH-3158: concurrent first use of binding names corrupts itEvtl. vergeben @AkashB23 hat das heute übernommen. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 62/100
spring-cloud/spring-cloud-stream#3321 ·
Maintainer antworten meist innerhalb von 1 Tag
-
[Bug] 资源包列表 与 模组/数据包/世界 列表排列顺序不一致Evtl. vergeben @fishdry1000 hat das vor 4 Tagen übernommen. Offenbug
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 62/100
Maintainer antworten meist innerhalb von 1 Tag
-
ai-driven-fuzzing bug claude Minor
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 72/100
linagora/twake-calendar-side-service#1333 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 82/100
AtlasOfLivingAustralia/species-lists#882 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Type/Bug
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 62/100
ballerina-platform/ballerina-library#9458 ·
Maintainer antworten meist innerhalb von 1 Tag