Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Add a configuration to serve a local directory with a static handler#51186

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
mathias82 wants to merge10 commits intoquarkusio:main
base:main
Choose a base branch
Loading
frommathias82:feature-static-local-dir

Conversation

@mathias82
Copy link

Summary

This PR introduces support for serving static files from a local directory,
configurable viaquarkus.http.local-static-resources.*.

New configuration

quarkus.http.local-static-resources.enabled=true
quarkus.http.local-static-resources.path=/local-static/
quarkus.http.local-static-resources.directory=local-static

Tests

AddedLocalStaticResourcesTest which verifies:

  • Serving an existing file
  • Returning 404 when missing

@mathias82mathias82 changed the titleAdd support for serving static resources from a local directory in Vert.x HTTP #39968Add a configuration to serve a local directory with a static handler #39968Nov 23, 2025
@mathias82mathias82 changed the titleAdd a configuration to serve a local directory with a static handler #39968Add a configuration to serve a local directory with a static handler Fix #39968Nov 23, 2025
@mathias82mathias82force-pushed thefeature-static-local-dir branch 4 times, most recently fromdd79a29 to2bc57dcCompareNovember 24, 2025 12:08
Copy link
Contributor

@ia3andyia3andy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

LGTM, just cleaning non changed files

@ia3andy
Copy link
Contributor

ia3andy commentedNov 24, 2025
edited
Loading

I also forgot, you need to add those files as watched for livereload

@mathias82
Copy link
Author

I also forgot, you need to add those files as watched for livereload

ii have added@ia3andy

@mathias82mathias82 changed the titleAdd a configuration to serve a local directory with a static handler Fix #39968Add a configuration to serve a local directory with a static handlerNov 24, 2025
@mathias82
Copy link
Author

Improve validation and handling of local static resources directory

  • Introduce normalizedDirectory() with safety checks
  • I used validated directory in both build steps
  • Remove unnecessary endpoint trailing-slash logic
  • Simplify dev-mode directory guard

Copy link
Contributor

@ia3andyia3andy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Thanks!

@ia3andy
Copy link
Contributor

@mathias82 the code is LGTM, could you add the doc part also, I remember an old doc doing this with the StaticHandler (which was bad), but maybe it was removed.

mathias82 reacted with thumbs up emoji

@quarkus-bot

This comment has been minimized.

@quarkus-bot

This comment has been minimized.

@quarkus-bot

This comment has been minimized.

@quarkus-bot

This comment has been minimized.

@quarkus-bot

This comment has been minimized.

Comment on lines 71 to 82
To expose the contents of a `static/` directory under the `/local-static` path:

[source,properties]
----
quarkus.http.static-dir.path=/local-static
quarkus.http.static-dir.directory=static
----

With this configuration, a file located at `static/index.html` will be available at:
`http://localhost:8080/local-static/index.html`.

To disable serving local static resources explicitly:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
To expose the contents of a`static/` directory under the`/local-static`path:
[source,properties]
----
quarkus.http.static-dir.path=/local-static
quarkus.http.static-dir.directory=static
----
With this configuration, a file located at`static/index.html` will be available at:
`http://localhost:8080/local-static/index.html`.
To disable serving local static resources explicitly:
To expose the contents of a`static/` directory under the`/static`endpoint:
[source,properties]
----
quarkus.http.static-dir.endpoint=/static
quarkus.http.static-dir.path=static
----
With this configuration, a file located at`static/index.html` will be available at:
`http://localhost:8080/static/index.html`.
To disable serving local static resources explicitly:

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@mathias82 any reason not to auto enable whenendpoint orpath is not empty as@FroMage suggested?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@ia3andy@FroMage There is one reason: this feature exposes a local filesystem directory over HTTP.

If we auto-enable it as soon asendpoint orpath is set, it becomes easier
for large apps with layered configuration to accidentally expose a directory
just because some partial config was inherited or left behind.

By keepingenabled as an explicit opt-in switch, we avoid accidental exposure
and make the intent very clear: nothing is served unless the user consciously
enables it.

That said, if the project convention is to auto-enable on config, I can update
the implementation accordingly, I just wanted to highlight the security/ops
angle behind the current design.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@FroMage I let you decide on that one :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@mathias82 the change I suggested is still appllicable

mathias82 reacted with thumbs up emoji

Routerrouter =httpRouter.getValue();
router.route(basePath +"/*")
.handler(newHttpStaticDirHandler(staticFiles));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@mathias82 what is this?

Copy link
Author

@mathias82mathias82Nov 28, 2025
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@ia3andy This registers a catch-all Vert.x route for the configured static directory.

registerHttpStaticDirRoute collects all discovered static files at build time and
passes them toregisterHttpStaticDir(...), which at runtime installs:

router.route(basePath + "/*").handler(new HttpStaticDirHandler(staticFiles));

So this line effectively exposes every file under the configuredstatic-dir.path
at<basePath>/*, and delegates the resolution toHttpStaticDirHandler.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Remove it is not needed

@quarkus-bot

This comment has been minimized.

@quarkus-bot

This comment has been minimized.

@quarkus-bot

This comment has been minimized.

@quarkus-bot

This comment has been minimized.

@quarkus-bot

This comment has been minimized.

matthaios.stavrouand others added10 commitsNovember 29, 2025 01:06
@quarkus-bot
Copy link

Status for workflowQuarkus Documentation CI

This is the status report for runningQuarkus Documentation CI on commitf62e7e9.

✅ The latest workflow run for the pull request has completed successfully.

It should be safe to merge provided you have a look at the other checks in the summary.

Warning

There are other workflow runs running, you probably need to wait for their status before merging.

@quarkus-bot
Copy link

quarkus-botbot commentedNov 29, 2025
edited by github-actionsbot
Loading

Status for workflowQuarkus CI

This is the status report for runningQuarkus CI on commitf62e7e9.

Failing Jobs

StatusNameStepFailuresLogsRaw logsBuild scan
✔️JVM Integration Tests - JDK 17LogsRaw logs🚧
✔️JVM Integration Tests - JDK 17 WindowsLogsRaw logs🚧
✔️JVM Integration Tests - JDK 21LogsRaw logs🚧
JVM Integration Tests - JDK 21 SemeruBuildFailuresLogsRaw logs🚧
✔️JVM Integration Tests - JDK 25LogsRaw logs🚧

Full information is available in theBuild summary check run.
You can consult theDevelocity build scans.

Failures

⚙️ JVM Integration Tests - JDK 21 Semeru#

- Failing: integration-tests/oidc-wiremock integration-tests/virtual-threads/grpc-virtual-threads

📦 integration-tests/oidc-wiremock

io.quarkus.it.keycloak.CodeFlowAuthorizationTest. -History -More details -Source on GitHub

java.lang.RuntimeException: java.lang.RuntimeException: Failed to start quarkusat io.quarkus.test.junit.QuarkusTestExtension.throwBootFailureException(QuarkusTestExtension.java:663)at io.quarkus.test.junit.QuarkusTestExtension.interceptBeforeAllMethod(QuarkusTestExtension.java:730)at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)Caused by: java.lang.RuntimeException: Failed to start quarkusat io.quarkus.runner.ApplicationImpl.doStart(Unknown Source)at io.quarkus.runtime.Application.start(Application.java:101)at java.base/java.lang.reflect.Method.invoke(Method.java:586)

io.quarkus.it.keycloak.CodeFlowAuthorizationTest.testCodeFlowUserInfoCachedInIdToken line431 -History -More details -Source on GitHub

org.opentest4j.AssertionFailedError: expected: <true> but was: <false>at org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:151)at org.junit.jupiter.api.AssertionFailureBuilder.buildAndThrow(AssertionFailureBuilder.java:132)at org.junit.jupiter.api.AssertTrue.failNotTrue(AssertTrue.java:63)at org.junit.jupiter.api.AssertTrue.assertTrue(AssertTrue.java:36)at org.junit.jupiter.api.AssertTrue.assertTrue(AssertTrue.java:31)at org.junit.jupiter.api.Assertions.assertTrue(Assertions.java:183)at io.quarkus.it.keycloak.CodeFlowAuthorizationTest.testCodeFlowUserInfoCachedInIdToken(CodeFlowAuthorizationTest.java:431)

📦 integration-tests/virtual-threads/grpc-virtual-threads

io.quarkus.grpc.example.streaming.VertxVirtualThreadTest. -History -More details -Source on GitHub

org.junit.jupiter.engine.execution.ConditionEvaluationException: Failed to evaluate condition [io.quarkus.test.junit.QuarkusTestExtension]: Internal error: Test class was loaded with an unexpected classloader (QuarkusClassLoader:Quarkus Base Runtime ClassLoader: TEST for JUnitQuarkusTest-io.quarkus.grpc.test.utils.VertxGRPCTestProfile (QuarkusTest)@d43ac5e3) or the thread context classloader (jdk.internal.loader.ClassLoaders$AppClassLoader@b621dffa) was incorrect.at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)at java.base/java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1685)...

io.quarkus.grpc.example.streaming.VertxVirtualThreadTest.testGrpcClient -History -More details -Source on GitHub

java.lang.AssertionError: 1 expectation failed.Expected status code <200> but was <500>.at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:73)at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:108)

Flaky tests -Develocity

⚙️ JVM Tests - JDK 21

📦 extensions/smallrye-reactive-messaging/deployment

io.quarkus.smallrye.reactivemessaging.hotreload.ConnectorChangeTest.testUpdatingConnector -History

  • Expecting actual: ["-6","-8","-9","-10","-11","-12","-13","-14"] to start with: ["-6", "-7", "-8", "-9"] -java.lang.AssertionError
java.lang.AssertionError: Expecting actual:  ["-6","-8","-9","-10","-11","-12","-13","-14"]to start with:  ["-6", "-7", "-8", "-9"]at io.quarkus.smallrye.reactivemessaging.hotreload.ConnectorChangeTest.testUpdatingConnector(ConnectorChangeTest.java:41)

⚙️ Gradle Tests - JDK 17 Windows

📦 integration-tests/gradle

io.quarkus.gradle.run.AdditionalSourceSetAsDependencyTest.main -History

  • Condition with Lambda expression in io.quarkus.test.devmode.util.DevModeClient was not fulfilled within 1 minutes 30 seconds. -org.awaitility.core.ConditionTimeoutException
org.awaitility.core.ConditionTimeoutException: Condition with Lambda expression in io.quarkus.test.devmode.util.DevModeClient was not fulfilled within 1 minutes  30 seconds.at org.awaitility.core.ConditionAwaiter.await(ConditionAwaiter.java:167)at org.awaitility.core.CallableCondition.await(CallableCondition.java:78)at org.awaitility.core.CallableCondition.await(CallableCondition.java:26)at org.awaitility.core.ConditionFactory.until(ConditionFactory.java:1160)at org.awaitility.core.ConditionFactory.until(ConditionFactory.java:1129)at io.quarkus.test.devmode.util.DevModeClient.getHttpResponse(DevModeClient.java:164)at io.quarkus.gradle.devmode.QuarkusDevGradleTestBase.getHttpResponse(QuarkusDevGradleTestBase.java:165)

⚙️ MicroProfile TCKs Tests

📦 tcks/microprofile-lra

org.eclipse.microprofile.lra.tck.TckRecoveryTests.testCancelWhenParticipantIsUnavailable -History

  • Expecting the metric Compensated callback was called Expected: a value equal to or greater than <1> but: <0> was less than <1> -java.lang.AssertionError
java.lang.AssertionError: Expecting the metric Compensated callback was calledExpected: a value equal to or greater than <1>     but: <0> was less than <1>at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)at org.eclipse.microprofile.lra.tck.TckRecoveryTests.assertMetricCallbackCalled(TckRecoveryTests.java:210)at org.eclipse.microprofile.lra.tck.TckRecoveryTests.testCancelWhenParticipantIsUnavailable(TckRecoveryTests.java:195)at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

Copilot code reviewCopilotCopilot left review comments

@cescoffiercescoffierAwaiting requested review from cescoffier

@gsmetgsmetAwaiting requested review from gsmet

@sberyozkinsberyozkinAwaiting requested review from sberyozkin

@FroMageFroMageAwaiting requested review from FroMage

@ia3andyia3andyAwaiting requested review from ia3andy

Requested changes must be addressed to merge this pull request.

Assignees

No one assigned

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Add a configuration to serve a local directory with a static handler

5 participants

@mathias82@ia3andy@Sanne@sberyozkin@FroMage

[8]ページ先頭

©2009-2025 Movatter.jp