├── javalin-ssl
└── src
│ ├── test
│ ├── resources
│ │ ├── server
│ │ │ ├── wrong.pem
│ │ │ ├── norway.jks
│ │ │ ├── norway.p12
│ │ │ ├── keystore.jks
│ │ │ ├── keystore.p12
│ │ │ ├── malformed.p12
│ │ │ ├── cert.crt
│ │ │ ├── malformed.jks
│ │ │ ├── passwordless.key
│ │ │ └── encrypted.key
│ │ ├── client
│ │ │ ├── cert.der
│ │ │ ├── cert.jks
│ │ │ ├── cert.p12
│ │ │ ├── cert.pem
│ │ │ ├── cert.p7b
│ │ │ └── key.pem
│ │ └── ca
│ │ │ ├── keystores
│ │ │ ├── client.p12
│ │ │ ├── server.p12
│ │ │ ├── issuer-ca.p12
│ │ │ └── root-ca.p12
│ │ │ ├── client-nochain.cer
│ │ │ ├── root-ca.cer
│ │ │ ├── client.key
│ │ │ └── server.key
│ └── kotlin
│ │ └── io
│ │ └── javalin
│ │ └── community
│ │ └── ssl
│ │ └── SslConfigExceptionTest.kt
│ └── main
│ ├── module-info.java
│ └── kotlin
│ └── io
│ └── javalin
│ └── community
│ └── ssl
│ └── SslConfigException.kt
├── javalin
├── src
│ ├── test
│ │ ├── resources
│ │ │ ├── public
│ │ │ │ ├── file
│ │ │ │ ├── subpage
│ │ │ │ │ └── index.html
│ │ │ │ ├── file.javalin
│ │ │ │ ├── subdir
│ │ │ │ │ └── index.html
│ │ │ │ ├── protected
│ │ │ │ │ └── secret.html
│ │ │ │ ├── script.js
│ │ │ │ ├── immutable
│ │ │ │ │ └── library-1.0.0.min.js
│ │ │ │ ├── styles.css
│ │ │ │ ├── module.mjs
│ │ │ │ ├── assets
│ │ │ │ │ └── filtered-styles.css
│ │ │ │ ├── readme.md.br
│ │ │ │ ├── html.html
│ │ │ │ └── sse
│ │ │ │ │ └── sse-example.html
│ │ │ ├── markdown
│ │ │ │ └── test.md
│ │ │ ├── vue
│ │ │ │ ├── scripts-dev.js
│ │ │ │ ├── scripts-not-dev.js
│ │ │ │ ├── scripts.js
│ │ │ │ ├── dependency-1.vue
│ │ │ │ ├── view-one.vue
│ │ │ │ ├── view-two.vue
│ │ │ │ ├── dependency-123.vue
│ │ │ │ ├── dependency-one.vue
│ │ │ │ ├── test-component.vue
│ │ │ │ ├── view-one-3.vue
│ │ │ │ ├── view-three.vue
│ │ │ │ ├── dependency-two.vue
│ │ │ │ ├── dependency-1-foo.vue
│ │ │ │ ├── dependency-one-3.vue
│ │ │ │ ├── test-component-3.vue
│ │ │ │ ├── dependency-two-3.vue
│ │ │ │ ├── view-nested-dependency.vue
│ │ │ │ ├── nested-dependency.vue
│ │ │ │ ├── view-number-dependency.vue
│ │ │ │ ├── multi-dependency.vue
│ │ │ │ ├── view-multiline-dependency.vue
│ │ │ │ └── layout.html
│ │ │ ├── upload-test
│ │ │ │ ├── text.txt
│ │ │ │ ├── image.png
│ │ │ │ └── sound.mp3
│ │ │ └── keystore.jks
│ │ ├── external
│ │ │ ├── txt.txt
│ │ │ └── html.html
│ │ ├── java
│ │ │ └── io
│ │ │ │ └── javalin
│ │ │ │ ├── testing
│ │ │ │ ├── TestDependency.kt
│ │ │ │ ├── NonSerializableObject.java
│ │ │ │ ├── FasterJacksonMapper.kt
│ │ │ │ ├── SerializableObject.java
│ │ │ │ ├── RunResult.java
│ │ │ │ ├── UploadInfo.kt
│ │ │ │ ├── TypedException.java
│ │ │ │ ├── ThrowingBiConsumer.java
│ │ │ │ ├── TestEnvironment.kt
│ │ │ │ ├── TestServlet.java
│ │ │ │ ├── WebDriverUtil.kt
│ │ │ │ └── HttpUtil.kt
│ │ │ │ ├── examples
│ │ │ │ ├── HelloWorld.java
│ │ │ │ ├── HelloWorldStaticFiles.java
│ │ │ │ ├── HelloWorldStaticFiles_external.java
│ │ │ │ ├── HelloWorldFuture.java
│ │ │ │ ├── HelloWorldAsync.java
│ │ │ │ ├── FileUploadExample.java
│ │ │ │ ├── HelloWorldBasicAuth.java
│ │ │ │ ├── HelloWorldApi.java
│ │ │ │ ├── HelloWorldSse.java
│ │ │ │ ├── HelloWorldCors.java
│ │ │ │ ├── HelloWorldServlet.java
│ │ │ │ ├── HelloWorldStaticFiles_linked.java
│ │ │ │ ├── HelloWorldCustomJsonMapper.java
│ │ │ │ ├── HelloWorldSecure.java
│ │ │ │ ├── HelloWorldWebSockets.java
│ │ │ │ └── HelloWorldPlugin.java
│ │ │ │ ├── TestServerHeader.kt
│ │ │ │ ├── javalinvue
│ │ │ │ └── VueTestUtil.kt
│ │ │ │ ├── TestRequest_Java.java
│ │ │ │ ├── LargeSeekableInput.kt
│ │ │ │ ├── TestDependencyUtil.kt
│ │ │ │ ├── http
│ │ │ │ ├── HttpResponseExceptionTest.kt
│ │ │ │ └── ContentTypeTest.kt
│ │ │ │ ├── TestContextHandlerType.java
│ │ │ │ ├── TestConcurrencyUtil.kt
│ │ │ │ ├── TestMethodNotAllowed.kt
│ │ │ │ ├── routeoverview
│ │ │ │ └── TestRouteOverviewInJava.java
│ │ │ │ ├── TestCustomRequestLifecycle.kt
│ │ │ │ ├── TestClose.kt
│ │ │ │ ├── TestSslRedirectPlugin.kt
│ │ │ │ ├── TestMaxRequestSize.kt
│ │ │ │ ├── TestJsonMapper.kt
│ │ │ │ └── TestHttpAllowedMethodsPlugin.kt
│ │ └── kotlin
│ │ │ └── io
│ │ │ └── javalin
│ │ │ └── examples
│ │ │ ├── HelloWorld.kt
│ │ │ ├── HelloWorldStaticFiles.kt
│ │ │ ├── HelloWorldStaticFiles_external.kt
│ │ │ ├── FileUploadExample.kt
│ │ │ ├── HelloWorldApi.kt
│ │ │ ├── HelloWorldSse.kt
│ │ │ ├── HelloWorldCustomJsonMapper.kt
│ │ │ ├── HelloWorldCors.kt
│ │ │ ├── KotlinExample.kt
│ │ │ ├── HelloWorldPlugin.kt
│ │ │ ├── HelloWorldAsync.kt
│ │ │ ├── HelloWorldSecure.kt
│ │ │ ├── HelloWorldImages.kt
│ │ │ ├── HelloWorldWebSockets.kt
│ │ │ ├── HelloWorldAuth.kt
│ │ │ └── AdvancedServerSentEvent.kt
│ └── main
│ │ └── java
│ │ └── io
│ │ └── javalin
│ │ ├── compression
│ │ ├── CompressionType.kt
│ │ ├── Gzip.kt
│ │ ├── Brotli.kt
│ │ ├── Compressor.kt
│ │ ├── GzipCompressor.kt
│ │ └── Brotli4jCompressor.kt
│ │ ├── router
│ │ ├── exception
│ │ │ └── JavaLangErrorHandler.kt
│ │ ├── RoutingApi.kt
│ │ ├── matcher
│ │ │ ├── ParserExceptions.kt
│ │ │ ├── RoutingRegexes.kt
│ │ │ └── PathMatcher.kt
│ │ ├── ParsedEndpoint.kt
│ │ └── error
│ │ │ └── ErrorMapper.kt
│ │ ├── util
│ │ ├── function
│ │ │ └── ThrowingRunnable.java
│ │ ├── JavalinExceptions.kt
│ │ ├── FileUtil.kt
│ │ ├── JavalinLogger.kt
│ │ └── ReflectionUtil.kt
│ │ ├── http
│ │ ├── servlet
│ │ │ ├── ServletEntry.kt
│ │ │ ├── JavalinServletRequest.kt
│ │ │ └── Task.kt
│ │ ├── staticfiles
│ │ │ └── ResourceHandler.java
│ │ ├── util
│ │ │ ├── JsonEscapeUtil.kt
│ │ │ ├── MethodNotAllowedUtil.kt
│ │ │ └── ETagGenerator.kt
│ │ ├── RequestLogger.java
│ │ ├── ExceptionHandler.java
│ │ ├── Handler.java
│ │ ├── sse
│ │ │ ├── SseHandler.kt
│ │ │ └── Emitter.kt
│ │ └── UploadedFile.kt
│ │ ├── vue
│ │ ├── VueRenderer.kt
│ │ ├── VueComponent.kt
│ │ ├── VueStateRenderer.kt
│ │ └── VueFileInliner.kt
│ │ ├── apibuilder
│ │ ├── EndpointGroup.java
│ │ └── CrudHandler.kt
│ │ ├── security
│ │ ├── BasicAuthCredentials.kt
│ │ └── RouteRole.kt
│ │ ├── plugin
│ │ ├── PluginExceptions.kt
│ │ ├── bundled
│ │ │ ├── BasicAuthPlugin.kt
│ │ │ ├── RouteOverviewPlugin.kt
│ │ │ └── HttpAllowedMethodsPlugin.kt
│ │ └── PluginManager.kt
│ │ ├── event
│ │ └── LifecycleEventListener.kt
│ │ ├── websocket
│ │ ├── WsExceptionHandler.java
│ │ ├── WsRouter.kt
│ │ ├── WsHandlers.kt
│ │ ├── WsAutomaticPing.kt
│ │ └── WsExceptionMapper.kt
│ │ ├── jetty
│ │ └── JettyUtil.kt
│ │ ├── validation
│ │ ├── NullableValidator.kt
│ │ ├── BodyValidator.kt
│ │ └── Validator.kt
│ │ ├── config
│ │ ├── RequestLoggerConfig.kt
│ │ ├── ValidationConfig.kt
│ │ ├── AppDataManager.kt
│ │ ├── JettyInternalConfig.kt
│ │ ├── SpaRootConfig.kt
│ │ └── ContextResolverConfig.kt
│ │ ├── rendering
│ │ └── FileRenderer.kt
│ │ └── json
│ │ └── PipedStreamUtil.kt
└── module-info.java
├── javalin-utils
├── pom.properties
├── javalin-context-mock
│ └── src
│ │ └── main
│ │ └── java
│ │ └── io
│ │ └── javalin
│ │ └── mock
│ │ ├── ContextMockConfigurer.kt
│ │ ├── ContextMockConfig.kt
│ │ └── servlet
│ │ └── InMemoryPart.kt
├── pom.xml
└── coverage
│ └── README.md
├── javalin-rendering
├── src
│ ├── test
│ │ ├── resources
│ │ │ ├── markdown
│ │ │ │ └── test.md
│ │ │ └── templates
│ │ │ │ ├── st
│ │ │ │ ├── withImport.st
│ │ │ │ └── test.st
│ │ │ │ ├── jtwig
│ │ │ │ ├── test.jtwig
│ │ │ │ ├── test.html.twig
│ │ │ │ ├── multiple.dots.twig
│ │ │ │ └── custom.jtwig
│ │ │ │ ├── velocity
│ │ │ │ ├── test.vm
│ │ │ │ └── test-set.vm
│ │ │ │ ├── freemarker
│ │ │ │ ├── test.ftl
│ │ │ │ └── test-with-base.ftl
│ │ │ │ ├── pebble
│ │ │ │ ├── test.peb
│ │ │ │ └── test-empty-context-map.peb
│ │ │ │ ├── mustache
│ │ │ │ └── test.mustache
│ │ │ │ ├── thymeleaf
│ │ │ │ ├── test.html
│ │ │ │ └── testUrls.html
│ │ │ │ └── jte
│ │ │ │ ├── multiple-params.jte
│ │ │ │ ├── kte
│ │ │ │ ├── multiple-params.kte
│ │ │ │ └── test.kte
│ │ │ │ └── test.jte
│ │ └── java
│ │ │ └── io
│ │ │ └── javalin
│ │ │ ├── jte
│ │ │ └── JteTestPage.java
│ │ │ └── TestTemplateUtil.kt
│ └── main
│ │ ├── resources
│ │ └── META-INF
│ │ │ └── services
│ │ │ └── io.javalin.rendering.JavalinRenderer$FileRendererLoader
│ │ └── java
│ │ └── io
│ │ └── javalin
│ │ └── rendering
│ │ ├── template
│ │ ├── TemplateUtil.kt
│ │ ├── JavalinMustache.kt
│ │ ├── JavalinFreemarker.kt
│ │ ├── JavalinPebble.kt
│ │ ├── JavalinVelocity.kt
│ │ ├── JavalinJte.kt
│ │ └── JavalinThymeleaf.kt
│ │ ├── markdown
│ │ └── Commonmark.kt
│ │ └── util
│ │ └── RenderingDependency.kt
└── meta
│ └── module-info.java
├── .github
├── img
│ └── javalin.png
├── dependabot.yml
└── workflows
│ └── publish-snapshots.yml
├── .mvn
└── wrapper
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── pom.properties
├── javalin-osgi
└── README.md
├── javalin-testtools
└── src
│ ├── main
│ └── java
│ │ └── io
│ │ └── javalin
│ │ └── testtools
│ │ ├── TestCase.java
│ │ └── JavalinTest.kt
│ └── test
│ ├── kotlin
│ └── io
│ │ └── javalin
│ │ └── testtools
│ │ └── KotlinApp.kt
│ └── java
│ └── io
│ └── javalin
│ └── testtools
│ └── JavaApp.java
├── .gitignore
├── javalin-bundle
└── src
│ └── main
│ └── resources
│ └── logback.xml
├── javalin-micrometer
└── src
│ └── test
│ └── kotlin
│ └── io
│ └── javalin
│ └── micrometer
│ └── MicrometerPluginTest_Java.java
├── .editorconfig
└── README.md
/javalin-ssl/src/test/resources/server/wrong.pem:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/public/file:
--------------------------------------------------------------------------------
1 | TESTFILE
--------------------------------------------------------------------------------
/javalin/src/test/external/txt.txt:
--------------------------------------------------------------------------------
1 | Sample text
2 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/public/subpage/index.html:
--------------------------------------------------------------------------------
1 | TEST
--------------------------------------------------------------------------------
/javalin/src/test/resources/markdown/test.md:
--------------------------------------------------------------------------------
1 | # Hello Markdown!
2 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/public/file.javalin:
--------------------------------------------------------------------------------
1 | TESTFILE.javalin
2 |
--------------------------------------------------------------------------------
/javalin-utils/pom.properties:
--------------------------------------------------------------------------------
1 | # Dummy file to satisfy javalin-parent
2 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/public/subdir/index.html:
--------------------------------------------------------------------------------
1 |
Welcome file
--------------------------------------------------------------------------------
/javalin/src/test/resources/vue/scripts-dev.js:
--------------------------------------------------------------------------------
1 | let b = "Included if dev"
--------------------------------------------------------------------------------
/javalin-rendering/src/test/resources/markdown/test.md:
--------------------------------------------------------------------------------
1 | # Hello Markdown!
2 |
--------------------------------------------------------------------------------
/javalin-rendering/src/test/resources/templates/st/withImport.st:
--------------------------------------------------------------------------------
1 | $test()$
2 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/public/protected/secret.html:
--------------------------------------------------------------------------------
1 | Secret file
--------------------------------------------------------------------------------
/javalin/src/test/resources/vue/scripts-not-dev.js:
--------------------------------------------------------------------------------
1 | let b = "Included if not dev"
--------------------------------------------------------------------------------
/javalin-rendering/src/test/resources/templates/jtwig/test.jtwig:
--------------------------------------------------------------------------------
1 | {{message}}
--------------------------------------------------------------------------------
/javalin-rendering/src/test/resources/templates/velocity/test.vm:
--------------------------------------------------------------------------------
1 | $message
--------------------------------------------------------------------------------
/javalin-rendering/src/test/resources/templates/freemarker/test.ftl:
--------------------------------------------------------------------------------
1 | ${message}
--------------------------------------------------------------------------------
/javalin-rendering/src/test/resources/templates/jtwig/test.html.twig:
--------------------------------------------------------------------------------
1 | {{message}}
--------------------------------------------------------------------------------
/javalin-rendering/src/test/resources/templates/pebble/test.peb:
--------------------------------------------------------------------------------
1 | {{ message }}
--------------------------------------------------------------------------------
/javalin-rendering/src/test/resources/templates/st/test.st:
--------------------------------------------------------------------------------
1 | Hello $message$
2 |
--------------------------------------------------------------------------------
/javalin-rendering/src/test/resources/templates/jtwig/multiple.dots.twig:
--------------------------------------------------------------------------------
1 | {{message}}
--------------------------------------------------------------------------------
/javalin-rendering/src/test/resources/templates/mustache/test.mustache:
--------------------------------------------------------------------------------
1 | {{message}}
--------------------------------------------------------------------------------
/javalin/src/test/resources/public/script.js:
--------------------------------------------------------------------------------
1 | document.write("JavaScript works ");
2 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/upload-test/text.txt:
--------------------------------------------------------------------------------
1 | This is my content.
2 | It's two lines.
3 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/vue/scripts.js:
--------------------------------------------------------------------------------
1 | let a = "Always included";let $a = "Dollar works"
--------------------------------------------------------------------------------
/javalin-rendering/src/test/resources/templates/freemarker/test-with-base.ftl:
--------------------------------------------------------------------------------
1 | ${foo}
2 |
--------------------------------------------------------------------------------
/.github/img/javalin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Petersoj/javalin/master/.github/img/javalin.png
--------------------------------------------------------------------------------
/javalin/src/test/resources/public/immutable/library-1.0.0.min.js:
--------------------------------------------------------------------------------
1 | console.log("Cached for a year")
2 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/public/styles.css:
--------------------------------------------------------------------------------
1 | .css-test:before {
2 | content: "CSS works"
3 | }
4 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/public/module.mjs:
--------------------------------------------------------------------------------
1 | export function test() {
2 | return 'mjs works'
3 | }
4 |
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Petersoj/javalin/master/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/javalin-rendering/src/test/resources/templates/thymeleaf/test.html:
--------------------------------------------------------------------------------
1 | Some default value
--------------------------------------------------------------------------------
/javalin-rendering/src/test/resources/templates/velocity/test-set.vm:
--------------------------------------------------------------------------------
1 | #set($message = "Set works")
2 | $message
--------------------------------------------------------------------------------
/javalin/src/test/resources/public/assets/filtered-styles.css:
--------------------------------------------------------------------------------
1 | .css-test:before {
2 | content: "CSS works"
3 | }
4 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/keystore.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Petersoj/javalin/master/javalin/src/test/resources/keystore.jks
--------------------------------------------------------------------------------
/javalin-rendering/src/test/resources/templates/jtwig/custom.jtwig:
--------------------------------------------------------------------------------
1 | {{javalin("Javalin is the best framework you will ever get")}}
--------------------------------------------------------------------------------
/javalin-rendering/src/test/resources/templates/jte/multiple-params.jte:
--------------------------------------------------------------------------------
1 | @param String one
2 | @param String two
3 | ${one} ${two}!
4 |
--------------------------------------------------------------------------------
/javalin-rendering/src/test/resources/templates/jte/kte/multiple-params.kte:
--------------------------------------------------------------------------------
1 | @param one:String
2 | @param two:String
3 | ${one} ${two}!
4 |
--------------------------------------------------------------------------------
/javalin-rendering/src/test/resources/templates/thymeleaf/testUrls.html:
--------------------------------------------------------------------------------
1 | Link text
--------------------------------------------------------------------------------
/javalin-ssl/src/test/resources/client/cert.der:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Petersoj/javalin/master/javalin-ssl/src/test/resources/client/cert.der
--------------------------------------------------------------------------------
/javalin-ssl/src/test/resources/client/cert.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Petersoj/javalin/master/javalin-ssl/src/test/resources/client/cert.jks
--------------------------------------------------------------------------------
/javalin-ssl/src/test/resources/client/cert.p12:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Petersoj/javalin/master/javalin-ssl/src/test/resources/client/cert.p12
--------------------------------------------------------------------------------
/javalin/src/test/resources/public/readme.md.br:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Petersoj/javalin/master/javalin/src/test/resources/public/readme.md.br
--------------------------------------------------------------------------------
/pom.properties:
--------------------------------------------------------------------------------
1 | artifactId=${project.artifactId}
2 | groupId=${project.groupId}
3 | version=${project.version}
4 | buildTime=${maven.build.timestamp}
--------------------------------------------------------------------------------
/javalin-ssl/src/test/resources/server/norway.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Petersoj/javalin/master/javalin-ssl/src/test/resources/server/norway.jks
--------------------------------------------------------------------------------
/javalin-ssl/src/test/resources/server/norway.p12:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Petersoj/javalin/master/javalin-ssl/src/test/resources/server/norway.p12
--------------------------------------------------------------------------------
/javalin/src/test/resources/upload-test/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Petersoj/javalin/master/javalin/src/test/resources/upload-test/image.png
--------------------------------------------------------------------------------
/javalin/src/test/resources/upload-test/sound.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Petersoj/javalin/master/javalin/src/test/resources/upload-test/sound.mp3
--------------------------------------------------------------------------------
/javalin-ssl/src/test/resources/server/keystore.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Petersoj/javalin/master/javalin-ssl/src/test/resources/server/keystore.jks
--------------------------------------------------------------------------------
/javalin-ssl/src/test/resources/server/keystore.p12:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Petersoj/javalin/master/javalin-ssl/src/test/resources/server/keystore.p12
--------------------------------------------------------------------------------
/javalin-ssl/src/test/resources/ca/keystores/client.p12:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Petersoj/javalin/master/javalin-ssl/src/test/resources/ca/keystores/client.p12
--------------------------------------------------------------------------------
/javalin-ssl/src/test/resources/ca/keystores/server.p12:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Petersoj/javalin/master/javalin-ssl/src/test/resources/ca/keystores/server.p12
--------------------------------------------------------------------------------
/javalin-ssl/src/test/resources/ca/keystores/issuer-ca.p12:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Petersoj/javalin/master/javalin-ssl/src/test/resources/ca/keystores/issuer-ca.p12
--------------------------------------------------------------------------------
/javalin-ssl/src/test/resources/ca/keystores/root-ca.p12:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Petersoj/javalin/master/javalin-ssl/src/test/resources/ca/keystores/root-ca.p12
--------------------------------------------------------------------------------
/javalin/src/test/java/io/javalin/testing/TestDependency.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.testing
2 |
3 | object TestDependency {
4 | val swaggerVersion = "4.10.3";
5 | }
6 |
--------------------------------------------------------------------------------
/javalin-rendering/src/test/resources/templates/jte/kte/test.kte:
--------------------------------------------------------------------------------
1 | @import io.javalin.jte.JteTestPage
2 | @param page:JteTestPage
3 | ${page.hello} ${page.world}!
4 |
--------------------------------------------------------------------------------
/javalin-rendering/src/test/resources/templates/jte/test.jte:
--------------------------------------------------------------------------------
1 | @import io.javalin.jte.JteTestPage
2 | @param JteTestPage page
3 | ${page.getHello()} ${page.getWorld()}!
4 |
--------------------------------------------------------------------------------
/javalin-rendering/src/test/resources/templates/pebble/test-empty-context-map.peb:
--------------------------------------------------------------------------------
1 | {% set message = 'Hello world' %}
2 |
3 | {% block content %}
4 | {{ message }}
5 | {% endblock %}
6 |
--------------------------------------------------------------------------------
/javalin-osgi/README.md:
--------------------------------------------------------------------------------
1 | Produced OSGi bundle of Javalin, currently exporting all the packages.
2 | This is done by re-packaging Javalin JAR into OSGi bundle and generating a suitable OSGi manifest file.
3 |
--------------------------------------------------------------------------------
/javalin/src/test/external/html.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | HTML works
7 |
8 |
9 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/vue/dependency-1.vue:
--------------------------------------------------------------------------------
1 |
2 | Dependency 1
3 |
4 |
7 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/vue/view-one.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/vue/view-two.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/vue/dependency-123.vue:
--------------------------------------------------------------------------------
1 |
2 | Dependency 123
3 |
4 |
7 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/vue/dependency-one.vue:
--------------------------------------------------------------------------------
1 |
2 | Dependency One
3 |
4 |
7 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/vue/test-component.vue:
--------------------------------------------------------------------------------
1 |
2 | Test ÆØÅ
3 |
4 |
7 |
8 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/vue/view-one-3.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/vue/view-three.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/vue/dependency-two.vue:
--------------------------------------------------------------------------------
1 |
2 | Dependency Two
3 |
4 |
7 |
8 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/vue/dependency-1-foo.vue:
--------------------------------------------------------------------------------
1 |
2 | Dependency 1 foo
3 |
4 |
7 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/vue/dependency-one-3.vue:
--------------------------------------------------------------------------------
1 |
2 | Dependency One
3 |
4 |
7 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/vue/test-component-3.vue:
--------------------------------------------------------------------------------
1 |
2 | Test ÆØÅ
3 |
4 |
7 |
8 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/vue/dependency-two-3.vue:
--------------------------------------------------------------------------------
1 |
2 | Dependency Two
3 |
4 |
7 |
8 |
--------------------------------------------------------------------------------
/javalin/src/test/java/io/javalin/testing/NonSerializableObject.java:
--------------------------------------------------------------------------------
1 | package io.javalin.testing;
2 |
3 | public class NonSerializableObject {
4 | private final String value1 = "First value";
5 | private final String value2 = "Second value";
6 | }
7 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/compression/CompressionType.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.compression
2 |
3 | enum class CompressionType(val typeName: String, val extension: String) {
4 | GZIP("gzip", ".gz"),
5 | BR("br", ".br"),
6 | NONE("", "");
7 | }
8 |
--------------------------------------------------------------------------------
/javalin/src/test/java/io/javalin/testing/FasterJacksonMapper.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.testing
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper
4 | import io.javalin.json.JavalinJackson
5 |
6 | val fasterJacksonMapper = JavalinJackson(ObjectMapper())
7 |
--------------------------------------------------------------------------------
/javalin-testtools/src/main/java/io/javalin/testtools/TestCase.java:
--------------------------------------------------------------------------------
1 | package io.javalin.testtools;
2 |
3 | import io.javalin.Javalin;
4 |
5 | @FunctionalInterface
6 | public interface TestCase {
7 | void accept(Javalin server, HttpClient client) throws Exception;
8 | }
9 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/vue/view-nested-dependency.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/router/exception/JavaLangErrorHandler.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.router.exception
2 |
3 | import jakarta.servlet.http.HttpServletResponse
4 |
5 | fun interface JavaLangErrorHandler {
6 | fun handle(res: HttpServletResponse, err: Error)
7 | }
8 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/util/function/ThrowingRunnable.java:
--------------------------------------------------------------------------------
1 | package io.javalin.util.function;
2 |
3 | /** Throwing version of {@link java.lang.Runnable} */
4 | @FunctionalInterface
5 | public interface ThrowingRunnable {
6 | void run() throws E;
7 | }
8 |
--------------------------------------------------------------------------------
/javalin/src/test/java/io/javalin/testing/SerializableObject.java:
--------------------------------------------------------------------------------
1 | package io.javalin.testing;
2 |
3 | import java.io.Serializable;
4 |
5 | public class SerializableObject implements Serializable {
6 | public String value1 = "FirstValue";
7 | public String value2 = "SecondValue";
8 | }
9 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/vue/nested-dependency.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/vue/view-number-dependency.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/http/servlet/ServletEntry.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.http.servlet
2 |
3 | import jakarta.servlet.Servlet
4 | import jakarta.servlet.ServletContainerInitializer
5 |
6 | data class ServletEntry(
7 | val initializer: ServletContainerInitializer? = null,
8 | val servlet: Servlet
9 | )
10 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/vue/VueRenderer.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.vue
2 |
3 | import io.javalin.http.Context
4 |
5 | open class VueRenderer {
6 | open fun preRender(layout: String, ctx: Context) = layout // no changes by default
7 | open fun postRender(layout: String, ctx: Context) = layout // no changes by default
8 | }
9 |
--------------------------------------------------------------------------------
/javalin/src/test/java/io/javalin/testing/RunResult.java:
--------------------------------------------------------------------------------
1 | package io.javalin.testing;
2 |
3 | public class RunResult {
4 | public String logs;
5 | public Exception exception;
6 |
7 | public RunResult(String logs, Exception exception) {
8 | this.logs = logs;
9 | this.exception = exception;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | pom.xml.tag
3 | pom.xml.releaseBackup
4 | pom.xml.versionsBackup
5 | pom.xml.next
6 | release.properties
7 | dependency-reduced-pom.xml
8 | buildNumber.properties
9 | .mvn/timing.properties
10 |
11 | .idea
12 | *.iml
13 |
14 | # ignore Eclipse specifics
15 | .classpath
16 | .settings
17 | .project
18 | .factorypath
19 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/public/html.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | HTML works
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/apibuilder/EndpointGroup.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.apibuilder;
8 |
9 | @FunctionalInterface
10 | public interface EndpointGroup {
11 | void addEndpoints();
12 | }
13 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/security/BasicAuthCredentials.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.security
2 |
3 | /**
4 | * Auth credentials for basic HTTP authorization.
5 | * Contains the Base64 decoded [username] and [password] from the Authorization header.
6 | * @see io.javalin.http.Context.basicAuthCredentials
7 | */
8 | data class BasicAuthCredentials(val username: String, val password: String)
9 |
--------------------------------------------------------------------------------
/javalin/src/test/java/io/javalin/testing/UploadInfo.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.testing
8 |
9 | class UploadInfo(val filename: String = "", val size: Long = 0L, val contentType: String? = "", val extension: String = "")
10 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/compression/Gzip.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.compression
2 |
3 | /** Configuration for Gzip compression
4 | * @param level Compression level. Higher yields better (but slower) compression. Range 0..9, default = 6 */
5 | class Gzip(val level: Int = 6) {
6 | init {
7 | require(level in 0..9) { "Valid range for parameter level is 0 to 9" }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/javalin-bundle/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/compression/Brotli.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.compression
2 |
3 | /** Configuration for Brotli compression
4 | * @param level Compression level. Higher yields better (but slower) compression. Range 0..11, default = 4 */
5 | class Brotli(val level: Int = 4) {
6 | init {
7 | require(level in 0..11) { "Valid range for parameter level is 0 to 11" }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/vue/multi-dependency.vue:
--------------------------------------------------------------------------------
1 |
2 | Dependency Three
3 |
4 |
5 | Dependency Four
6 |
7 |
11 |
12 |
--------------------------------------------------------------------------------
/javalin/src/test/java/io/javalin/testing/TypedException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | *
6 | */
7 |
8 | package io.javalin.testing;
9 |
10 | public class TypedException extends Exception {
11 | public String proofOfType() {
12 | return "I'm so typed";
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/javalin-micrometer/src/test/kotlin/io/javalin/micrometer/MicrometerPluginTest_Java.java:
--------------------------------------------------------------------------------
1 | package io.javalin.micrometer;
2 |
3 | import org.junit.jupiter.api.Test;
4 |
5 | public class MicrometerPluginTest_Java {
6 |
7 | @Test
8 | public void api_looks_ok_from_java() {
9 | var plugin = new MicrometerPlugin(config -> {});
10 | var handler = MicrometerPlugin.exceptionHandler;
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/javalin-utils/javalin-context-mock/src/main/java/io/javalin/mock/ContextMockConfigurer.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.mock
2 |
3 | fun interface ContextMockConfigurer {
4 | /** Apply changes to the [ContextMockConfig] instance. */
5 | fun ContextMockConfig.configure()
6 | }
7 |
8 | internal fun invokeConfigWithConfigurerScope(configurer: ContextMockConfigurer, config: ContextMockConfig) {
9 | with(configurer) { config.configure() }
10 | }
11 |
--------------------------------------------------------------------------------
/javalin/src/test/kotlin/io/javalin/examples/HelloWorld.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.examples
8 |
9 | import io.javalin.Javalin
10 |
11 | fun main() {
12 | val app = Javalin.create(/*config*/)
13 | .get("/") { it.result("Hello World") }
14 | .start(7070)
15 | }
16 |
--------------------------------------------------------------------------------
/javalin-rendering/meta/module-info.java:
--------------------------------------------------------------------------------
1 | module io.javalin.rendering {
2 | requires io.javalin;
3 | requires transitive kotlin.stdlib;
4 |
5 | requires static thymeleaf;
6 | requires static com.github.mustachejava;
7 | requires static freemarker;
8 | requires static gg.jte;
9 | requires static gg.jte.runtime;
10 | requires static io.pebbletemplates;
11 |
12 | exports io.javalin.rendering.template;
13 | exports io.javalin.rendering.markdown;
14 | }
15 |
--------------------------------------------------------------------------------
/javalin/src/test/kotlin/io/javalin/examples/HelloWorldStaticFiles.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.examples
8 |
9 | import io.javalin.Javalin
10 | import io.javalin.http.staticfiles.Location
11 |
12 | fun main() {
13 | Javalin.create { it.staticFiles.add("/public", Location.CLASSPATH) }.start(7070)
14 | }
15 |
16 |
--------------------------------------------------------------------------------
/javalin-ssl/src/main/module-info.java:
--------------------------------------------------------------------------------
1 | module io.javalin.community.ssl {
2 | exports io.javalin.community.ssl;
3 | exports io.javalin.community.ssl.util;
4 |
5 | requires transitive io.javalin;
6 | requires org.eclipse.jetty.server;
7 | requires org.eclipse.jetty.alpn.server;
8 | requires org.eclipse.jetty.http2.server;
9 | requires nl.altindag.ssl;
10 | requires nl.altindag.ssl.jetty;
11 | requires nl.altindag.ssl.pem;
12 |
13 | requires kotlin.stdlib;
14 | }
15 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/http/staticfiles/ResourceHandler.java:
--------------------------------------------------------------------------------
1 | package io.javalin.http.staticfiles;
2 |
3 | import io.javalin.http.Context;
4 | import io.javalin.security.RouteRole;
5 | import java.util.Set;
6 |
7 | public interface ResourceHandler {
8 | boolean canHandle(Context context);
9 |
10 | boolean handle(Context context);
11 |
12 | boolean addStaticFileConfig(StaticFileConfig config);
13 |
14 | Set getResourceRouteRoles(Context ctx);
15 | }
16 |
--------------------------------------------------------------------------------
/javalin-rendering/src/test/java/io/javalin/jte/JteTestPage.java:
--------------------------------------------------------------------------------
1 | package io.javalin.jte;
2 |
3 | public class JteTestPage {
4 | private final String hello;
5 | private final String world;
6 |
7 | public JteTestPage(String hello, String world) {
8 | this.hello = hello;
9 | this.world = world;
10 | }
11 |
12 | public String getHello() {
13 | return hello;
14 | }
15 |
16 | public String getWorld() {
17 | return world;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/vue/view-multiline-dependency.vue:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
10 |
13 | foo
14 |
15 |
16 |
19 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/vue/layout.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | @componentRegistration
4 |
5 |
6 |
7 |
8 |
9 |
10 | @routeComponent
11 |
12 |
--------------------------------------------------------------------------------
/javalin/src/test/kotlin/io/javalin/examples/HelloWorldStaticFiles_external.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.examples
8 |
9 | import io.javalin.Javalin
10 | import io.javalin.http.staticfiles.Location
11 |
12 | fun main() {
13 | Javalin.create {
14 | it.staticFiles.add("src/test/external/", Location.EXTERNAL)
15 | }.start(7070)
16 | }
17 |
--------------------------------------------------------------------------------
/javalin/src/test/java/io/javalin/examples/HelloWorld.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | *
6 | */
7 |
8 | package io.javalin.examples;
9 |
10 | import io.javalin.Javalin;
11 |
12 | public class HelloWorld {
13 | public static void main(String[] args) {
14 | var app = Javalin.create(/*config*/)
15 | .get("/", ctx -> ctx.result("Hello World"))
16 | .start(7070);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/javalin-rendering/src/main/resources/META-INF/services/io.javalin.rendering.JavalinRenderer$FileRendererLoader:
--------------------------------------------------------------------------------
1 | io.javalin.rendering.markdown.JavalinCommonmark$Loader
2 | io.javalin.rendering.template.JavalinFreemarker$Loader
3 | io.javalin.rendering.template.JavalinJte$Loader
4 | io.javalin.rendering.template.JavalinMustache$Loader
5 | io.javalin.rendering.template.JavalinPebble$Loader
6 | io.javalin.rendering.template.JavalinStringTemplate4$Loader
7 | io.javalin.rendering.template.JavalinThymeleaf$Loader
8 | io.javalin.rendering.template.JavalinVelocity$Loader
9 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/router/RoutingApi.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.router
2 |
3 | import io.javalin.config.JavalinConfig
4 |
5 | interface RoutingApi
6 |
7 | fun interface RoutingApiInitializer {
8 | fun initialize(cfg: JavalinConfig, internalRouter: InternalRouter, setup: RoutingSetupScope)
9 | }
10 |
11 | fun interface RoutingSetupScope {
12 | fun SETUP.setup()
13 | }
14 |
15 | internal fun RoutingSetupScope.invokeAsSamWithReceiver(receiver: SETUP) {
16 | with(this) { receiver.setup() }
17 | }
18 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/util/JavalinExceptions.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.util
2 |
3 | open class JavalinException : RuntimeException {
4 | constructor(message: String) : super(message)
5 | constructor(message: String, cause: Throwable) : super(message, cause)
6 | constructor(cause: Throwable) : super(cause)
7 | }
8 |
9 | class JavalinBindException(message: String, cause: Throwable) : JavalinException(message, cause)
10 |
11 | class BodyAlreadyReadException(msg: String = "Request body has already been read") : JavalinException(msg)
12 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/http/servlet/JavalinServletRequest.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.http.servlet
2 |
3 | import jakarta.servlet.ServletInputStream
4 | import jakarta.servlet.http.HttpServletRequest
5 | import jakarta.servlet.http.HttpServletRequestWrapper
6 |
7 | class JavalinServletRequest(request: HttpServletRequest) : HttpServletRequestWrapper(request) {
8 | internal var inputStreamRead: Boolean = false
9 | private set
10 |
11 | override fun getInputStream(): ServletInputStream =
12 | super.getInputStream().also { inputStreamRead = true }
13 | }
14 |
--------------------------------------------------------------------------------
/javalin-testtools/src/main/java/io/javalin/testtools/JavalinTest.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.testtools
2 |
3 | import io.javalin.Javalin
4 |
5 | object JavalinTest {
6 |
7 | private val testConfig = TestConfig()
8 | private val testTool = TestTool(testConfig)
9 |
10 | @JvmStatic
11 | @JvmOverloads
12 | fun test(app: Javalin = Javalin.create(), config: TestConfig = this.testConfig, testCase: TestCase) =
13 | testTool.test(app, config, testCase)
14 |
15 | @JvmStatic
16 | fun captureStdOut(runnable: Runnable) = testTool.captureStdOut(runnable)
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/security/RouteRole.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.security;
8 |
9 | import io.javalin.router.EndpointMetadata
10 |
11 | /**
12 | * Marker interface for roles used in route declarations.
13 | * See {@link Context#routeRoles()}.
14 | */
15 | interface RouteRole
16 |
17 | /**
18 | * List of roles used in route declaration
19 | */
20 | data class Roles(val roles: Set) : EndpointMetadata
21 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/plugin/PluginExceptions.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.plugin
2 |
3 | abstract class PluginException(pluginClass: Class>, override val message: String) :
4 | RuntimeException("Error in ${pluginClass.canonicalName}: $message")
5 |
6 | data class PluginAlreadyRegisteredException(val plugin: Plugin<*>) :
7 | PluginException(plugin::class.java, "${plugin.name()} is already registered")
8 |
9 | class PluginNotRegisteredException(pluginClass: Class>) :
10 | PluginException(pluginClass, "${pluginClass.canonicalName} was not registered as a plugin at startup")
11 |
--------------------------------------------------------------------------------
/javalin/src/test/java/io/javalin/examples/HelloWorldStaticFiles.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | *
6 | */
7 |
8 | package io.javalin.examples;
9 |
10 | import io.javalin.Javalin;
11 | import io.javalin.http.staticfiles.Location;
12 |
13 | public class HelloWorldStaticFiles {
14 |
15 | public static void main(String[] args) {
16 | Javalin.create(config -> {
17 | config.staticFiles.add("/public", Location.CLASSPATH);
18 | }).start(7070);
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/http/servlet/Task.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.http.servlet
2 |
3 | import io.javalin.http.Context
4 |
5 | enum class SubmitOrder {
6 | FIRST,
7 | LAST
8 | }
9 |
10 | fun interface TaskInitializer {
11 | fun createTasks(submitTask: (SubmitOrder, Task) -> Unit, servlet: JavalinServlet, ctx: CTX, requestUri: String)
12 | }
13 |
14 | data class Task(
15 | val skipIfExceptionOccurred: Boolean = true, // tasks in this stage can be aborted by throwing an exception
16 | val handler: TaskHandler
17 | )
18 |
19 | fun interface TaskHandler {
20 | fun handle(): R
21 | }
22 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 4
6 | end_of_line = lf
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 | max_line_length = 200
11 |
12 | [*.java]
13 | ij_java_names_count_to_use_import_on_demand = 999
14 | ij_java_use_single_class_imports = true
15 |
16 | [*.kt]
17 | ij_kotlin_name_count_to_use_star_import = 999
18 | ij_kotlin_name_count_to_use_star_import_for_members = 999
19 |
20 | [*.md]
21 | trim_trailing_whitespace = false
22 |
23 | [*.{js,css,html}]
24 | insert_final_newline = false
25 |
26 | [*.{yml,yaml,json}]
27 | indent_size = 2
28 |
29 |
--------------------------------------------------------------------------------
/javalin-ssl/src/test/kotlin/io/javalin/community/ssl/SslConfigExceptionTest.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.community.ssl
2 |
3 | import org.junit.jupiter.api.Assertions.*
4 | import org.junit.jupiter.api.Test
5 |
6 | class SslConfigExceptionTest {
7 | @Test
8 | fun `test all exception types`(){
9 | assertEquals("There is no certificate or key file provided",SslConfigException(SslConfigException.Types.MISSING_CERT_AND_KEY_FILE).message)
10 | assertEquals("Both the certificate and key must be provided using the same method",SslConfigException(SslConfigException.Types.MULTIPLE_IDENTITY_LOADING_OPTIONS).message)
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/javalin/src/test/java/io/javalin/TestServerHeader.kt:
--------------------------------------------------------------------------------
1 | package io.javalin
2 |
3 | import io.javalin.http.HttpStatus.OK
4 | import io.javalin.testing.TestUtil
5 | import kong.unirest.HttpMethod
6 | import org.assertj.core.api.Assertions.assertThat
7 | import org.junit.jupiter.api.Test
8 |
9 | class TestServerHeader {
10 |
11 | @Test
12 | fun `server header is not set by default`() = TestUtil.test { app, http ->
13 | app.get("/hello") { it.status(OK).result("Hello world") }
14 | val response = http.call(HttpMethod.GET, "/hello")
15 | assertThat(response.headers.getFirst("Server")).isEqualTo("")
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/javalin-ssl/src/main/kotlin/io/javalin/community/ssl/SslConfigException.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.community.ssl
2 |
3 | /**
4 | * Exception thrown when the SslConfig is invalid.
5 | */
6 | class SslConfigException : RuntimeException {
7 | constructor(type: Types) : super(type.message)
8 |
9 | /**
10 | * Types of errors that can occur when configuring SSL.
11 | */
12 | enum class Types(val message: String) {
13 | MISSING_CERT_AND_KEY_FILE("There is no certificate or key file provided"),
14 | MULTIPLE_IDENTITY_LOADING_OPTIONS("Both the certificate and key must be provided using the same method")
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/event/LifecycleEventListener.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.event
8 |
9 | /**
10 | * Main interface for Lifecycle Event Handlers.
11 | * A Runnable does not suffice because the event handler may throw a checked exception.
12 | *
13 | * @see Lifecycle Events in documentation
14 | */
15 | fun interface LifecycleEventListener {
16 | @Throws(Exception::class) fun handleEvent()
17 | }
18 |
--------------------------------------------------------------------------------
/javalin/src/test/java/io/javalin/examples/HelloWorldStaticFiles_external.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.examples;
8 |
9 | import io.javalin.Javalin;
10 | import io.javalin.http.staticfiles.Location;
11 |
12 | public class HelloWorldStaticFiles_external {
13 |
14 | public static void main(String[] args) {
15 | Javalin.create(config -> {
16 | config.staticFiles.add("src/test/external/", Location.EXTERNAL);
17 | }).start(7070);
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/javalin-rendering/src/main/java/io/javalin/rendering/template/TemplateUtil.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.rendering.template
8 |
9 | object TemplateUtil {
10 | @JvmStatic
11 | fun model(vararg args: Any?): Map {
12 | if (args.size % 2 != 0) {
13 | throw IllegalArgumentException("Number of arguments must be even (key value pairs).")
14 | }
15 | return args.asSequence().chunked(2).associate { it[0] as String to it[1] }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/javalin/src/test/resources/public/sse/sse-example.html:
--------------------------------------------------------------------------------
1 | Stats
2 | onmessage:
3 | addEventListener("counter"):
4 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/router/matcher/ParserExceptions.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.router.matcher
2 |
3 | class MissingBracketsException(segment: String, val path: String) : IllegalArgumentException(
4 | "This segment '$segment' is missing some brackets! Found in path '$path'"
5 | )
6 |
7 | class WildcardBracketAdjacentException(segment: String, val path: String) : IllegalArgumentException(
8 | "Wildcard and a path parameter bracket are adjacent in segment '$segment' of path '$path'. This is forbidden"
9 | )
10 |
11 | class ParameterNamesNotUniqueException(val path: String) : IllegalArgumentException(
12 | "Duplicate path param names detected! This is forbidden. Found in path '$path'"
13 | )
14 |
--------------------------------------------------------------------------------
/javalin/src/test/java/io/javalin/testing/ThrowingBiConsumer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.testing;
8 |
9 | import java.util.function.BiConsumer;
10 |
11 | @FunctionalInterface
12 | public interface ThrowingBiConsumer extends BiConsumer {
13 | @Override
14 | default void accept(T t, U u) {
15 | try {
16 | acceptThrows(t, u);
17 | } catch (Exception e) {
18 | throw new RuntimeException(e);
19 | }
20 | }
21 |
22 | void acceptThrows(T t, U u) throws Exception;
23 | }
24 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/websocket/WsExceptionHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.websocket;
8 |
9 | import org.jetbrains.annotations.NotNull;
10 |
11 | /**
12 | * A handler for use with {@link io.javalin.Javalin#wsException(Class, WsExceptionHandler)}.
13 | * Is triggered when an exception is thrown by a handler in a {@link WsConfig}.
14 | *
15 | * @see WsContext
16 | */
17 | @FunctionalInterface
18 | public interface WsExceptionHandler {
19 | void handle(@NotNull T exception, @NotNull WsContext ctx);
20 | }
21 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/jetty/JettyUtil.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.jetty
2 |
3 | import io.javalin.config.JavalinConfig
4 | import io.javalin.http.servlet.ServletEntry
5 | import io.javalin.util.Util
6 | import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer
7 |
8 | internal object JettyUtil {
9 |
10 | fun createJettyServletWithWebsocketsIfAvailable(cfg: JavalinConfig): ServletEntry? =
11 | when {
12 | Util.classExists("org.eclipse.jetty.websocket.server.JettyWebSocketServlet") ->
13 | ServletEntry(JettyWebSocketServletContainerInitializer(null), JavalinJettyServlet(cfg))
14 | else ->
15 | null
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/vue/VueComponent.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.vue
2 |
3 | import io.javalin.http.Context
4 |
5 | class VueComponent @JvmOverloads constructor(
6 | val component: String, val state: Any? = null,
7 | private val renderer: VueRenderer = VueRenderer()
8 | ) : VueHandler(component) {
9 | override fun state(ctx: Context) = this.state // we are extending VueHandler and just returning the state passed by the user
10 | override fun preRender(layout: String, ctx: Context) = renderer.preRender(layout, ctx) // default implementation does no pre rendering
11 | override fun postRender(layout: String, ctx: Context) = renderer.postRender(layout, ctx) // default implementation does no post rendering
12 | }
13 |
--------------------------------------------------------------------------------
/javalin/src/test/java/io/javalin/testing/TestEnvironment.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.testing
2 |
3 | object TestEnvironment {
4 |
5 | // CI server
6 | val isCiServer = System.getProperty("RunningOnCi")?.toBoolean() == true
7 | val isNotCiServer = !isCiServer
8 |
9 | // Operating systems
10 | val os: String = System.getProperty("os.name").lowercase()
11 | val isMac = os.contains("mac", "darwin")
12 | val isNotMac = !isMac
13 | val isWindows = os.contains("win")
14 | val isNotWindows = !isWindows
15 | val isLinux = os.contains("nix", "nux", "aix")
16 | val isNotLinux = !isLinux
17 |
18 | private fun String.contains(vararg strings: String) = strings.any { this.contains(it, ignoreCase = true) }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/javalin-testtools/src/test/kotlin/io/javalin/testtools/KotlinApp.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.testtools
2 |
3 | import io.javalin.Javalin
4 | import io.javalin.apibuilder.ApiBuilder.get
5 | import io.javalin.http.Context
6 |
7 | // We're using objects for simplicity's sake, but you could
8 | // make it classes and do dependency injection or whatever
9 | object KotlinApp {
10 | var app = Javalin.create { javalin ->
11 | javalin.router.ignoreTrailingSlashes = false
12 | javalin.router.apiBuilder {
13 | get("/hello", HelloController::hello)
14 | }
15 | }
16 |
17 | internal object HelloController {
18 | fun hello(ctx: Context) {
19 | ctx.result("Hello, app!")
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/apibuilder/CrudHandler.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.apibuilder
8 |
9 | import io.javalin.http.Context
10 |
11 | /**
12 | * The CrudHandler is an interface for handling the five most
13 | * common CRUD operations. It's only available through the ApiBuilder.
14 | *
15 | * @see ApiBuilder
16 | */
17 | interface CrudHandler {
18 | fun getAll(ctx: Context)
19 | fun getOne(ctx: Context, resourceId: String)
20 | fun create(ctx: Context)
21 | fun update(ctx: Context, resourceId: String)
22 | fun delete(ctx: Context, resourceId: String)
23 | }
24 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/validation/NullableValidator.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.validation
8 |
9 | /**
10 | * The NullableValidator is a [Validator] that allows null values, created by calling [Validator.allowNullable].
11 | */
12 | open class NullableValidator internal constructor(params: Params) : BaseValidator(params) {
13 | fun check(check: Check, error: String) = addRule(params.fieldName, check, error) as NullableValidator
14 | fun check(check: Check, error: ValidationError) = addRule(params.fieldName, check, error) as NullableValidator
15 | }
16 |
--------------------------------------------------------------------------------
/javalin/src/test/java/io/javalin/javalinvue/VueTestUtil.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.javalinvue
2 |
3 | import io.javalin.Javalin
4 | import io.javalin.config.JavalinConfig
5 | import io.javalin.http.staticfiles.Location
6 | import io.javalin.testing.HttpUtil
7 | import io.javalin.testing.TestUtil
8 | import io.javalin.testing.ThrowingBiConsumer
9 | import java.util.function.Consumer
10 |
11 | object VueTestUtil {
12 | @JvmOverloads
13 | @JvmStatic
14 | fun test(config: Consumer? = null, test: ThrowingBiConsumer) =
15 | TestUtil.test(Javalin.create { baseConfig ->
16 | baseConfig.vue.rootDirectory("src/test/resources/vue", Location.EXTERNAL)
17 | config?.accept(baseConfig)
18 | }, test)
19 | }
20 |
--------------------------------------------------------------------------------
/javalin/src/test/java/io/javalin/testing/TestServlet.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.testing;
8 |
9 | import jakarta.servlet.http.HttpServlet;
10 | import jakarta.servlet.http.HttpServletRequest;
11 | import jakarta.servlet.http.HttpServletResponse;
12 | import java.io.IOException;
13 | import java.io.PrintWriter;
14 |
15 | public class TestServlet extends HttpServlet {
16 | public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
17 | PrintWriter out = res.getWriter();
18 | out.println("Hello Servlet World!");
19 | out.close();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/compression/Compressor.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.compression
2 |
3 | import java.io.OutputStream
4 |
5 | /** A compressor is used to compress an output stream */
6 | interface Compressor {
7 |
8 | /** The content encoding for this compressor (e.g. "gzip")
9 | * [MDN Content-Encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding)
10 | * @return the content encoding (case-insensitive) */
11 | fun encoding(): String
12 |
13 | /** @return the file extension for this compressor (empty string if none) */
14 | fun extension(): String = ""
15 |
16 | /** @param out the output stream to compress
17 | * @return the compressed output stream */
18 | fun compress(out: OutputStream): OutputStream
19 | }
20 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/router/ParsedEndpoint.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.router
2 |
3 | import io.javalin.config.RouterConfig
4 | import io.javalin.http.servlet.JavalinServletContext
5 | import io.javalin.router.matcher.PathParser
6 |
7 | class ParsedEndpoint(
8 | val endpoint: Endpoint,
9 | routerConfig: RouterConfig,
10 | ) {
11 |
12 | private val pathParser = PathParser(endpoint.path, routerConfig)
13 |
14 | fun handle(ctx: JavalinServletContext, requestUri: String) {
15 | endpoint.handle(ctx.update(this, requestUri))
16 | }
17 |
18 | fun matches(requestUri: String): Boolean =
19 | pathParser.matches(requestUri)
20 |
21 | fun extractPathParams(requestUri: String): Map =
22 | pathParser.extractPathParams(requestUri)
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/javalin-testtools/src/test/java/io/javalin/testtools/JavaApp.java:
--------------------------------------------------------------------------------
1 | package io.javalin.testtools;
2 |
3 | import io.javalin.Javalin;
4 | import io.javalin.http.Context;
5 |
6 | import static io.javalin.apibuilder.ApiBuilder.get;
7 |
8 | // We're using statics for simplicity's sake, but you could
9 | // make it non static and do dependency injection or whatever
10 | public class JavaApp {
11 |
12 | public Javalin app = Javalin.create(javalin -> {
13 | javalin.router.ignoreTrailingSlashes = false;
14 | javalin.router.apiBuilder(() -> {
15 | get("/hello", HelloController::hello);
16 | });
17 | });
18 |
19 | static class HelloController {
20 | public static void hello(Context ctx) {
21 | ctx.result("Hello, app!");
22 | }
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "maven"
4 | directory: "/"
5 | schedule:
6 | interval: "monthly"
7 | time: "04:30" # this is in UTC time
8 | open-pull-requests-limit: 10
9 | commit-message:
10 | prefix: "[deps]"
11 | labels:
12 | - "dependencies"
13 | target-branch: "master"
14 | groups:
15 | dependencies:
16 | patterns:
17 | - "*"
18 |
19 |
20 | - package-ecosystem: "github-actions"
21 | directory: "/"
22 | schedule:
23 | interval: "weekly"
24 | open-pull-requests-limit: 5
25 | commit-message:
26 | prefix: "[workflow]"
27 | labels:
28 | - "dependencies"
29 | target-branch: "master"
30 | groups:
31 | dependencies:
32 | patterns:
33 | - "*"
34 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/compression/GzipCompressor.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.compression
2 |
3 | import java.io.OutputStream
4 | import java.util.zip.GZIPOutputStream
5 |
6 | /** @param level Compression level. Higher yields better (but slower) compression. Range 0..9, default = 6 */
7 | class GzipCompressor(val level: Int) : Compressor {
8 | init {
9 | require(level in 0..9) { "Valid range for parameter level is 0 to 9" }
10 | }
11 |
12 | override fun encoding() = CompressionType.GZIP.typeName
13 | override fun extension() = CompressionType.GZIP.extension
14 | override fun compress(out: OutputStream) = LeveledGzipStream(out, level)
15 | }
16 |
17 | class LeveledGzipStream(out: OutputStream, level: Int) : GZIPOutputStream(out) {
18 | init {
19 | this.def.setLevel(level)
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/javalin-utils/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | javalin-parent
5 | io.javalin
6 | 6.7.1-SNAPSHOT
7 |
8 | 4.0.0
9 |
10 | javalin-utils
11 | pom
12 |
13 |
14 | javalin-context-mock
15 | coverage
16 |
17 |
18 |
19 | true
20 |
21 |
22 |
--------------------------------------------------------------------------------
/javalin/src/test/java/io/javalin/TestRequest_Java.java:
--------------------------------------------------------------------------------
1 | package io.javalin;
2 |
3 | import io.javalin.testing.TestUtil;
4 | import org.junit.jupiter.api.Test;
5 | import static org.assertj.core.api.Assertions.assertThat;
6 |
7 | public class TestRequest_Java {
8 |
9 | @Test
10 | public void session_attribute_can_be_consumed_easily() {
11 | TestUtil.test((app, http) -> {
12 | app.get("/store-attr", ctx -> ctx.sessionAttribute("attr", "Rowin"));
13 | app.get("/read-attr", ctx -> ctx.result("" + ctx.consumeSessionAttribute("attr")));
14 | http.getBody("/store-attr");
15 | assertThat(http.getBody("/read-attr")).isEqualTo("Rowin"); // read (and consume) the attribute
16 | assertThat(http.getBody("/read-attr")).isEqualTo("null"); // fallback
17 | });
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/http/util/JsonEscapeUtil.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.http.util
8 |
9 | object JsonEscapeUtil {
10 | fun escape(str: String): String {
11 | val builder = StringBuilder(str.length)
12 | for (ch in str) {
13 | builder.append(
14 | when (ch) {
15 | '\"' -> "\\\""
16 | '\n' -> "\\n"
17 | '\r' -> "\\r"
18 | '\\' -> "\\\\"
19 | '\t' -> "\\t"
20 | '\b' -> "\\b"
21 | else -> ch
22 | }
23 | )
24 | }
25 | return builder.toString()
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/config/RequestLoggerConfig.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.config
2 |
3 | import io.javalin.http.RequestLogger
4 | import io.javalin.websocket.WsConfig
5 | import java.util.function.Consumer
6 |
7 | /**
8 | * Configuration for http requests and websocket loggers.
9 | *
10 | * @param cfg the parent Javalin Configuration
11 | * @see [JavalinConfig.requestLogger]
12 | */
13 | class RequestLoggerConfig(private val cfg: JavalinConfig) {
14 |
15 | /** Adds a request logger for HTTP requests. */
16 | fun http(requestLogger: RequestLogger) {
17 | cfg.pvt.requestLogger = requestLogger
18 | }
19 |
20 | /** Adds a request logger for websocket requests. */
21 | fun ws(ws: Consumer) {
22 | val logger = WsConfig()
23 | ws.accept(logger)
24 | cfg.pvt.wsLogger = logger
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/websocket/WsRouter.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.websocket
2 |
3 | import io.javalin.config.RouterConfig
4 | import io.javalin.security.RouteRole
5 | import java.util.function.Consumer
6 |
7 | class WsRouter(private val routerConfig: RouterConfig) {
8 |
9 | val wsExceptionMapper = WsExceptionMapper()
10 | val wsPathMatcher = WsPathMatcher()
11 |
12 | /** Add a WebSocket handler. */
13 | fun addHandler(handlerType: WsHandlerType, path: String, ws: Consumer, roles: Set) {
14 | wsPathMatcher.add(
15 | WsHandlerEntry(
16 | type = handlerType,
17 | path = path,
18 | routerConfig = routerConfig,
19 | wsConfig = WsConfig().apply { ws.accept(this) },
20 | roles = roles
21 | )
22 | )
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/compression/Brotli4jCompressor.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.compression
2 |
3 |
4 | import com.aayushatharva.brotli4j.encoder.BrotliOutputStream
5 | import com.aayushatharva.brotli4j.encoder.Encoder
6 | import java.io.OutputStream
7 |
8 | /** @param level Compression level. Higher yields better (but slower) compression. Range 0..11, default = 4 */
9 | class Brotli4jCompressor(val level: Int) : Compressor {
10 | init {
11 | require(level in 0..11) { "Valid range for parameter level is 0 to 11" }
12 | }
13 |
14 | override fun encoding(): String = CompressionType.BR.typeName
15 | override fun extension(): String = CompressionType.BR.extension
16 | override fun compress(out: OutputStream): OutputStream = LeveledBrotli4jStream(out, level)
17 | }
18 |
19 | class LeveledBrotli4jStream(out: OutputStream, level: Int) :
20 | BrotliOutputStream(out, Encoder.Parameters().setQuality(level))
21 |
--------------------------------------------------------------------------------
/javalin/src/test/java/io/javalin/examples/HelloWorldFuture.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.examples;
8 |
9 | import io.javalin.Javalin;
10 | import java.util.concurrent.CompletableFuture;
11 | import java.util.concurrent.Executors;
12 | import java.util.concurrent.TimeUnit;
13 |
14 | public class HelloWorldFuture {
15 |
16 | public static void main(String[] args) {
17 | Javalin app = Javalin.create().start(7070);
18 | app.get("/", ctx -> {
19 | CompletableFuture future = new CompletableFuture<>();
20 | Executors.newSingleThreadScheduledExecutor().schedule(() -> future.complete("Hello World!"), 10, TimeUnit.MILLISECONDS);
21 | ctx.future(() -> future.thenApply(ctx::result));
22 | });
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/http/RequestLogger.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.http;
8 |
9 | import org.jetbrains.annotations.NotNull;
10 |
11 | /**
12 | * Interface for logging requests.
13 | *
14 | * @see Context
15 | * @see RequestLogger in documentation
16 | */
17 | @FunctionalInterface
18 | public interface RequestLogger {
19 | /**
20 | * Handles a request
21 | *
22 | * @param ctx the current request context
23 | * @param executionTimeMs the requests' execution time in milliseconds
24 | * @throws Exception any exception while logging information about the request
25 | */
26 | void handle(@NotNull Context ctx, @NotNull Float executionTimeMs) throws Exception;
27 | }
28 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/http/util/MethodNotAllowedUtil.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.http.util
8 |
9 | import io.javalin.http.Context
10 | import io.javalin.http.HandlerType
11 | import io.javalin.http.servlet.acceptsHtml
12 | import io.javalin.router.InternalRouter
13 |
14 | object MethodNotAllowedUtil {
15 |
16 | fun findAvailableHttpHandlerTypes(router: InternalRouter, requestUri: String) =
17 | enumValues().filter { it.isHttpMethod && router.findHttpHandlerEntries(it, requestUri).findFirst().isPresent }
18 |
19 | fun getAvailableHandlerTypes(ctx: Context, availableHandlerTypes: List): Map = mapOf(
20 | (if (acceptsHtml(ctx)) "Available methods" else "availableMethods") to availableHandlerTypes.joinToString(", ")
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/javalin/src/test/java/io/javalin/examples/HelloWorldAsync.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.examples;
8 |
9 | import io.javalin.Javalin;
10 |
11 | public class HelloWorldAsync {
12 |
13 | public static void main(String[] args) {
14 | Javalin app = Javalin.create().start(7070);
15 |
16 | app.get("/", ctx -> {
17 | ctx.async(
18 | (asyncConfig) -> {
19 | asyncConfig.timeout = 1000L;
20 | asyncConfig.onTimeout(timeoutCtx -> timeoutCtx.result("Request timed out :<"));
21 | },
22 | () -> {
23 | Thread.sleep((long) (Math.random() * 2000L));
24 | ctx.result("Hello Javalin");
25 | }
26 | );
27 | });
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/javalin/src/test/kotlin/io/javalin/examples/FileUploadExample.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.examples
8 |
9 | import io.javalin.Javalin
10 | import io.javalin.util.FileUtil
11 |
12 | fun main() {
13 |
14 | Javalin.create().apply {
15 | get("/") { ctx ->
16 | ctx.html(
17 | """
18 |
22 | """
23 | )
24 | }
25 | post("/") { ctx ->
26 | ctx.uploadedFiles("files").forEach {
27 | FileUtil.streamToFile(it.content(), "upload/${it.filename()}")
28 | }
29 | }
30 | }.start(7070)
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/config/ValidationConfig.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.config
2 |
3 | class ValidationConfig() {
4 |
5 | internal val converters = mutableMapOf, (String) -> Any?>(
6 | java.lang.Boolean::class.java to { it.toBoolean() },
7 | java.lang.Double::class.java to { it.toDouble() },
8 | java.lang.Float::class.java to { it.toFloat() },
9 | java.lang.Integer::class.java to { it.toInt() },
10 | java.lang.Long::class.java to { it.toLong() },
11 | java.lang.String::class.java to { it },
12 | Boolean::class.java to { it.toBoolean() },
13 | Double::class.java to { it.toDouble() },
14 | Float::class.java to { it.toFloat() },
15 | Int::class.java to { it.toInt() },
16 | Long::class.java to { it.toLong() },
17 | String::class.java to { it }
18 | )
19 |
20 | fun register(clazz: Class<*>, converter: (String) -> Any?) {
21 | converters[clazz] = converter
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/http/ExceptionHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.http;
8 |
9 | import io.javalin.Javalin;
10 | import org.jetbrains.annotations.NotNull;
11 |
12 | /**
13 | * A handler for use with {@link Javalin#exception(Class, ExceptionHandler)}.
14 | * Is triggered when exceptions are thrown by a {@link Handler}.
15 | *
16 | * @see Context
17 | * @see Exception mapping in docs
18 | */
19 | @FunctionalInterface
20 | public interface ExceptionHandler {
21 | /**
22 | * Handles an exception thrown while handling a request
23 | *
24 | * @param exception the thrown exception
25 | * @param ctx the context of the request
26 | */
27 | void handle(@NotNull T exception, @NotNull Context ctx);
28 | }
29 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/websocket/WsHandlers.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 | package io.javalin.websocket
7 |
8 | enum class WsHandlerType { WEBSOCKET_BEFORE, WEBSOCKET, WEBSOCKET_AFTER }
9 |
10 | fun interface WsConnectHandler {
11 | @Throws(Exception::class)
12 | fun handleConnect(ctx: WsConnectContext)
13 | }
14 |
15 | fun interface WsMessageHandler {
16 | @Throws(Exception::class)
17 | fun handleMessage(ctx: WsMessageContext)
18 | }
19 |
20 | fun interface WsBinaryMessageHandler {
21 | @Throws(Exception::class)
22 | fun handleBinaryMessage(ctx: WsBinaryMessageContext)
23 | }
24 |
25 | fun interface WsErrorHandler {
26 | @Throws(Exception::class)
27 | fun handleError(ctx: WsErrorContext)
28 | }
29 |
30 | fun interface WsCloseHandler {
31 | @Throws(Exception::class)
32 | fun handleClose(ctx: WsCloseContext)
33 | }
34 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/rendering/FileRenderer.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 | package io.javalin.rendering
7 |
8 | import io.javalin.config.Key
9 | import io.javalin.http.Context
10 |
11 | /** Interface for creating renderers to be used with [Context.render]. */
12 | fun interface FileRenderer {
13 | companion object {
14 | @JvmField val FileRendererKey = Key("javalin-file-renderer")
15 | }
16 |
17 | /** Renders the given file */
18 | fun render(filePath: String, model: Map, context: Context): String
19 | }
20 |
21 | class NotImplementedRenderer : FileRenderer {
22 | override fun render(filePath: String, model: Map, context: Context): String {
23 | throw UnsupportedOperationException("No FileRenderer configured. You can configure one in config.fileRenderer(...)")
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/javalin/src/test/kotlin/io/javalin/examples/HelloWorldApi.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.examples
8 |
9 | import io.javalin.Javalin
10 | import io.javalin.apibuilder.ApiBuilder.get
11 | import io.javalin.apibuilder.ApiBuilder.path
12 | import io.javalin.http.HttpStatus
13 |
14 |
15 | fun main() {
16 | Javalin.create {
17 | it.router.apiBuilder {
18 | get("/hello") { it.result("Hello World") }
19 | path("/api") {
20 | get("/test") { it.result("Hello World") }
21 | get("/tast") { it.status(HttpStatus.OK).result("Hello world") }
22 | get("/hest") { it.status(HttpStatus.OK).result("Hello World") }
23 | get("/hast") { it.status(HttpStatus.OK).result("Hello World").header("test", "tast") }
24 | }
25 | }
26 | }.start(7070)
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/config/AppDataManager.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.config
2 |
3 | data class Key(val id: String)
4 |
5 | class KeyAlreadyExistsException(key: Key<*>) : IllegalStateException("Key '$key' already exists")
6 | class NoValueForKeyException(key: Key<*>) : IllegalStateException("No value for key '$key'")
7 |
8 | class AppDataManager {
9 |
10 | private val data: MutableMap, Any?> = mutableMapOf()
11 |
12 | fun register(key: Key, value: T) {
13 | if (data.containsKey(key)) {
14 | throw KeyAlreadyExistsException(key)
15 | }
16 | data[key] = value
17 | }
18 |
19 | fun registerIfAbsent(key: Key, value: T) {
20 | registerResolverIfAbsent(key, value)
21 | }
22 |
23 | fun registerResolverIfAbsent(key: Key, value: T) {
24 | data.putIfAbsent(key, value)
25 | }
26 |
27 | fun get(key: Key): T {
28 | return data[key] as T? ?: throw NoValueForKeyException(key)
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/javalin/src/test/java/io/javalin/LargeSeekableInput.kt:
--------------------------------------------------------------------------------
1 | package io.javalin
2 |
3 | import java.io.InputStream
4 |
5 | class LargeSeekableInput(private val prefixSize: Long, private val contentSize: Long) : InputStream() {
6 |
7 | private var alreadyRead = 0L
8 | private fun remaining(): Long = prefixSize + contentSize - alreadyRead
9 |
10 | override fun available(): Int = when (val rem = remaining()) {
11 | in 0..Int.MAX_VALUE -> rem.toInt()
12 | else -> Int.MAX_VALUE
13 | }
14 |
15 | override fun skip(toSkip: Long): Long = when {
16 | toSkip <= 0 -> 0
17 | else -> when (val rem = remaining()) {
18 | in 0..toSkip -> rem.also { alreadyRead += rem }
19 | else -> toSkip.also { alreadyRead += toSkip }
20 | }
21 | }
22 |
23 | override fun read(): Int = when {
24 | remaining() == 0L -> -1
25 | alreadyRead < prefixSize -> ' '.code.also { alreadyRead++ }
26 | else -> 'J'.code.also { alreadyRead++ }
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/util/FileUtil.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.util
8 |
9 | import java.io.File
10 | import java.io.InputStream
11 | import java.nio.file.Files
12 | import java.nio.file.StandardCopyOption
13 |
14 | object FileUtil {
15 |
16 | @JvmStatic
17 | fun streamToFile(inputStream: InputStream, path: String) {
18 | val newFile = File(path)
19 | newFile.parentFile.mkdirs() // create parent dirs if necessary
20 | newFile.createNewFile() // create file if necessary
21 | inputStream.use { input ->
22 | Files.copy(input, newFile.toPath(), StandardCopyOption.REPLACE_EXISTING)
23 | }
24 |
25 | }
26 |
27 | @JvmStatic
28 | fun readResource(path: String) = FileUtil::class.java.getResource(path).readText()
29 |
30 | @JvmStatic
31 | fun readFile(path: String) = File(path).readText()
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/http/Handler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.http;
8 |
9 | import org.jetbrains.annotations.NotNull;
10 |
11 | /**
12 | * Main interface for endpoint actions. A handler has a void return type,
13 | * so you have to use {@link Context#result} to return data to the client.
14 | *
15 | * @see Context
16 | * @see Handler in documentation
17 | */
18 | @FunctionalInterface
19 | public interface Handler {
20 | /**
21 | * Handles a request.
22 | *
23 | * @param ctx the current request's context. Use this to process the request's
24 | * parameter (query, form params, body, …) and build up the response
25 | * (status code, payload, …)
26 | * @throws Exception an exception while handling the request
27 | */
28 | void handle(@NotNull Context ctx) throws Exception;
29 | }
30 |
--------------------------------------------------------------------------------
/javalin/src/test/java/io/javalin/TestDependencyUtil.kt:
--------------------------------------------------------------------------------
1 | package io.javalin
2 |
3 | import io.javalin.util.CoreDependency
4 | import io.javalin.util.DependencyUtil
5 | import org.assertj.core.api.Assertions.assertThat
6 | import org.junit.jupiter.api.Test
7 |
8 | class TestDependencyUtil {
9 |
10 | @Test
11 | fun `DependencyUtil#missingDependencyMessage works`() {
12 | val message = DependencyUtil.missingDependencyMessage(CoreDependency.JACKSON)
13 | assertThat(message).contains("You're missing the 'Jackson' dependency in your project. Add the dependency:")
14 | }
15 |
16 | @Test
17 | fun `DependencyUtil#mavenAndGradleSnippets works`() {
18 | val dependency = CoreDependency.JACKSON
19 | val message = DependencyUtil.mavenAndGradleSnippets(dependency)
20 | assertThat(message).contains("pom.xml:")
21 | assertThat(message).contains("build.gradle or build.gradle.kts:")
22 | assertThat(message).contains("""implementation("${dependency.groupId}:${dependency.artifactId}:${dependency.version}")""")
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/.github/workflows/publish-snapshots.yml:
--------------------------------------------------------------------------------
1 | name: Snapshot build
2 |
3 | on:
4 | push:
5 | branches: [ 'master' ]
6 |
7 | jobs:
8 | publish:
9 | if: |
10 | github.repository == 'javalin/javalin' &&
11 | !contains(github.event.head_commit.message, '[maven-release-plugin] prepare release')
12 | name: Publish snapshot
13 | runs-on: ubuntu-latest
14 | steps:
15 | - uses: actions/checkout@v4
16 | - name: Set up JDK11
17 | uses: actions/setup-java@v4
18 | with:
19 | distribution: 'zulu'
20 | java-version: 11
21 | - name: Grant execute permission for mvnw
22 | run: chmod +x ./mvnw
23 | - uses: s4u/maven-settings-action@v3.1.0
24 | with:
25 | servers: |
26 | [{
27 | "id": "reposilite-repository",
28 | "username": "${{ secrets.MAVEN_NAME }}",
29 | "password": "${{ secrets.MAVEN_SECRET }}"
30 | }]
31 | - name: Publish with Maven
32 | run: ./mvnw -DRunningOnCi=true clean deploy --file pom.xml --batch-mode -P publish-snapshot
33 |
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # https://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing,
12 | # software distributed under the License is distributed on an
13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | # KIND, either express or implied. See the License for the
15 | # specific language governing permissions and limitations
16 | # under the License.
17 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip
18 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar
19 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/config/JettyInternalConfig.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.config
2 |
3 | import org.eclipse.jetty.server.Connector
4 | import org.eclipse.jetty.server.HttpConfiguration
5 | import org.eclipse.jetty.server.Server
6 | import org.eclipse.jetty.servlet.ServletContextHandler
7 | import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory
8 | import java.util.function.BiFunction
9 | import java.util.function.Consumer
10 |
11 | class JettyInternalConfig {
12 | // @formatter:off
13 | @JvmField var server: Server? = null
14 | @JvmField var serverConsumers: MutableList> = mutableListOf()
15 | @JvmField var httpConfigurationConfigs: MutableList> = mutableListOf()
16 | @JvmField var servletContextHandlerConsumers: MutableList> = mutableListOf()
17 | @JvmField var wsFactoryConfigs: MutableList> = mutableListOf()
18 | @JvmField var connectors: MutableList> = mutableListOf()
19 | // @formatter:on
20 | }
21 |
--------------------------------------------------------------------------------
/javalin/src/test/java/io/javalin/examples/FileUploadExample.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.examples;
8 |
9 | import io.javalin.Javalin;
10 | import io.javalin.util.FileUtil;
11 |
12 | public class FileUploadExample {
13 |
14 | public static void main(String[] args) {
15 |
16 | Javalin app = Javalin.create().start(7000);
17 |
18 | app.get("/", ctx ->
19 | ctx.html(
20 | ""
21 | + ""
25 | )
26 | );
27 |
28 | app.post("/", ctx -> {
29 | ctx.uploadedFiles("files").forEach(file -> {
30 | FileUtil.streamToFile(file.content(), "upload/" + file.filename());
31 | });
32 | });
33 |
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/javalin/src/test/kotlin/io/javalin/examples/HelloWorldSse.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.examples
8 |
9 | import io.javalin.Javalin
10 | import io.javalin.http.sse.SseClient
11 | import java.util.concurrent.ConcurrentLinkedQueue
12 | import java.util.concurrent.TimeUnit
13 |
14 | fun main() {
15 |
16 | val clients = ConcurrentLinkedQueue()
17 |
18 | val app = Javalin.create().start(7000)
19 | app.get("/") { it.html("") }
20 |
21 | app.sse("/sse") { client ->
22 | client.keepAlive()
23 | clients.add(client) // save the sse to use outside of this context
24 | client.onClose { clients.remove(client) }
25 | }
26 |
27 | while (true) {
28 | for (client in clients) {
29 | client.sendEvent("hi", "hello world")
30 | }
31 | TimeUnit.SECONDS.sleep(1)
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/javalin-utils/javalin-context-mock/src/main/java/io/javalin/mock/ContextMockConfig.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.mock
2 |
3 | import io.javalin.Javalin
4 | import io.javalin.config.JavalinConfig
5 | import io.javalin.mock.servlet.HttpServletRequestMock.RequestState
6 | import io.javalin.mock.servlet.HttpServletResponseMock.ResponseState
7 | import java.util.function.Consumer
8 |
9 | data class ContextMockConfig internal constructor(
10 | val req: RequestState = RequestState(),
11 | val res: ResponseState = ResponseState(),
12 | var javalinConfig: JavalinConfig = Javalin.create().unsafeConfig()
13 | ) {
14 |
15 | /** Change Javalin config used to prepare the [Context] instance. */
16 | fun javalinConfig(config: Consumer) {
17 | this.javalinConfig = Javalin.create(config).unsafeConfig()
18 | }
19 |
20 | /** Deep copy of this [ContextMockConfig] */
21 | fun clone(): ContextMockConfig =
22 | copy(
23 | req = req.copy(),
24 | res = res.copy(),
25 | javalinConfig = javalinConfig // TODO: we could clone this too (?)
26 | )
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/config/SpaRootConfig.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.config
2 |
3 | import io.javalin.http.Handler
4 | import io.javalin.http.SinglePageHandler
5 | import io.javalin.http.staticfiles.Location
6 |
7 | /**
8 | * Configures a Single Page Application root.
9 | *
10 | * Single page application (SPA) mode is similar to static file handling.
11 | * It runs after endpoint matching, and after static file handling. It’s
12 | * basically a very fancy 404 mapper, which converts any 404’s into a
13 | * specified page. You can define multiple single page handlers for your
14 | * application by specifying different root paths.
15 | *
16 | * @see [SinglePageHandler]
17 | */
18 | class SpaRootConfig(private val cfg: JavalinConfig) {
19 |
20 | @JvmOverloads
21 | fun addFile(hostedPath: String, filePath: String, location: Location = Location.CLASSPATH) {
22 | cfg.pvt.singlePageHandler.add(hostedPath, filePath, location)
23 | }
24 |
25 | fun addHandler(hostedPath: String, customHandler: Handler) {
26 | cfg.pvt.singlePageHandler.add(hostedPath, customHandler)
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/javalin/src/test/java/io/javalin/http/HttpResponseExceptionTest.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.http
2 |
3 | import java.util.Locale
4 | import org.junit.jupiter.api.Test
5 | import org.junit.jupiter.api.assertDoesNotThrow
6 |
7 | class HttpResponseExceptionTest {
8 |
9 | @Test
10 | fun `all HttpStatus values should be covered by an Exception class`() {
11 | for (httpStatus in HttpStatus.entries) {
12 | if (httpStatus == HttpStatus.UNKNOWN) {
13 | continue
14 | }
15 | val convertedEnumName = httpStatus.name.splitToSequence("_").map { word ->
16 | word.lowercase().replaceFirstChar {
17 | if (it.isLowerCase()) it.titlecase(
18 | Locale.getDefault()
19 | ) else it.toString()
20 | }
21 | }.joinToString("")
22 | val expectedClassName = "io.javalin.http.${convertedEnumName}Response"
23 | assertDoesNotThrow("$expectedClassName does not exist") {
24 | Class.forName(expectedClassName)
25 | }
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/http/sse/SseHandler.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.http.sse
2 |
3 | import io.javalin.http.Context
4 | import io.javalin.http.Handler
5 | import io.javalin.http.Header
6 | import java.util.function.Consumer
7 |
8 | class SseHandler @JvmOverloads constructor(
9 | private val timeout: Long = 0,
10 | private val clientConsumer: Consumer
11 | ) : Handler {
12 |
13 | override fun handle(ctx: Context) {
14 | if (ctx.header(Header.ACCEPT) == "text/event-stream") {
15 | ctx.res().apply {
16 | status = 200
17 | characterEncoding = "UTF-8"
18 | contentType = "text/event-stream"
19 | addHeader(Header.CONNECTION, "close")
20 | addHeader(Header.CACHE_CONTROL, "no-cache")
21 | addHeader(Header.X_ACCEL_BUFFERING, "no") // See https://serverfault.com/a/801629
22 | flushBuffer()
23 | }
24 | ctx.async({
25 | it.timeout = timeout
26 | }) {
27 | clientConsumer.accept(SseClient(ctx))
28 | }
29 | }
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/javalin/src/test/java/io/javalin/examples/HelloWorldBasicAuth.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | *
6 | */
7 |
8 | package io.javalin.examples;
9 |
10 | import io.javalin.Javalin;
11 | import io.javalin.plugin.bundled.BasicAuthPlugin;
12 |
13 | public class HelloWorldBasicAuth {
14 |
15 | public static void main(String[] args) {
16 | Javalin
17 | .create(config -> {
18 | config.registerPlugin(new BasicAuthPlugin(basicAuthCfg -> {
19 | basicAuthCfg.username = "panda";
20 | basicAuthCfg.password = "bamboo";
21 | }));
22 | config.registerPlugin(
23 | new BasicAuthPlugin(basicAuthCfg -> {
24 | basicAuthCfg.username = "panda";
25 | basicAuthCfg.password = "bamboo";
26 | })
27 | );
28 | })
29 | .get("/hello", ctx -> ctx.result("Hello World 1"))
30 | .start(7070);
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/javalin/src/test/kotlin/io/javalin/examples/HelloWorldCustomJsonMapper.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.examples
8 |
9 | import io.javalin.Javalin
10 | import io.javalin.json.JsonMapper
11 | import java.lang.reflect.Type
12 |
13 | fun main() {
14 | val rawJsonMapper: JsonMapper = object : JsonMapper {
15 | // serialize obj your favourite api
16 | override fun toJsonString(obj: Any, type: Type): String = "{ \"" + type.typeName + "\": \"" + obj + "\" }"
17 |
18 | // deserialize json your favourite api
19 | @Suppress("UNCHECKED_CAST")
20 | override fun fromJsonString(json: String, targetType: Type): T = when (targetType) {
21 | String::class.java -> json as T
22 | else -> throw UnsupportedOperationException("RawJsonMapper can deserialize only strings")
23 | }
24 | }
25 |
26 | Javalin.create { it.jsonMapper(rawJsonMapper) }
27 | .get("/") { it.json(listOf("a", "b", "c")) }
28 | .start(7070)
29 | }
30 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/websocket/WsAutomaticPing.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.websocket
2 |
3 | import io.javalin.util.ConcurrencyUtil
4 | import io.javalin.util.javalinLazy
5 | import java.nio.ByteBuffer
6 | import java.util.concurrent.ConcurrentHashMap
7 | import java.util.concurrent.ScheduledExecutorService
8 | import java.util.concurrent.ScheduledFuture
9 | import java.util.concurrent.TimeUnit
10 |
11 | val executor: ScheduledExecutorService by javalinLazy { ConcurrencyUtil.newSingleThreadScheduledExecutor("JavalinWebSocketPingThread") }
12 | val pingFutures: ConcurrentHashMap?> by javalinLazy { ConcurrentHashMap() }
13 |
14 | fun enableAutomaticPings(ctx: WsContext, interval: Long, unit: TimeUnit, applicationData: ByteBuffer?) {
15 | synchronized(ctx) {
16 | disableAutomaticPings(ctx);
17 | pingFutures[ctx] = executor.scheduleAtFixedRate({
18 | ctx.sendPing(applicationData)
19 | }, interval, interval, unit)
20 | }
21 | }
22 |
23 | fun disableAutomaticPings(ctx: WsContext) {
24 | synchronized(ctx) {
25 | pingFutures[ctx]?.cancel(false)
26 | pingFutures.remove(ctx);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/javalin-rendering/src/test/java/io/javalin/TestTemplateUtil.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | *
6 | */
7 |
8 | package io.javalin
9 |
10 | import io.javalin.rendering.template.TemplateUtil
11 | import org.assertj.core.api.Assertions.assertThat
12 | import org.junit.jupiter.api.Test
13 | import org.junit.jupiter.api.Assertions.assertThrows
14 |
15 |
16 | class TestTemplateUtil {
17 | @Test
18 | fun `model works`() {
19 | val model = TemplateUtil.model("foo", "bar", "baz", "qux")
20 | assertThat(model).isEqualTo(mapOf("foo" to "bar", "baz" to "qux"))
21 | }
22 |
23 | @Test
24 | fun `model throws exception if number of arguments is odd`() {
25 | assertThrows(IllegalArgumentException::class.java) {
26 | TemplateUtil.model("foo", "bar", "baz")
27 | }
28 | }
29 |
30 | @Test
31 | fun `model works with null values`() {
32 | val model = TemplateUtil.model("foo", "bar", "baz", null)
33 | assertThat(model).isEqualTo(mapOf("foo" to "bar", "baz" to null))
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/javalin/src/test/kotlin/io/javalin/examples/HelloWorldCors.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.examples
8 |
9 | import io.javalin.Javalin
10 | import io.javalin.apibuilder.ApiBuilder.get
11 | import io.javalin.apibuilder.ApiBuilder.patch
12 | import io.javalin.apibuilder.ApiBuilder.post
13 | import io.javalin.plugin.bundled.CorsPlugin
14 |
15 | fun main() {
16 | Javalin.create { cfg ->
17 | cfg.registerPlugin(CorsPlugin { cors ->
18 | cors.addRule {
19 | it.allowHost("http://localhost:7001/", "http://localhost:7002")
20 | }
21 | })
22 | cfg.router.apiBuilder {
23 | get { it.json("Hello Get") }
24 | post { it.json("Hello Post") }
25 | patch { it.json("Hello Patch") }
26 | }
27 | }.start(7070)
28 |
29 | Javalin.create().start(7001).get("/") { it.html("Try some CORS") }
30 | Javalin.create().start(7002).get("/") { it.html("Try some CORS") }
31 | Javalin.create().start(7003).get("/") { it.html("No CORS here") }
32 | }
33 |
--------------------------------------------------------------------------------
/javalin/src/test/java/io/javalin/examples/HelloWorldApi.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | *
6 | */
7 |
8 | package io.javalin.examples;
9 |
10 | import io.javalin.Javalin;
11 |
12 | import static io.javalin.apibuilder.ApiBuilder.get;
13 | import static io.javalin.apibuilder.ApiBuilder.path;
14 | import static io.javalin.http.HttpStatus.OK;
15 |
16 | public class HelloWorldApi {
17 |
18 | public static void main(String[] args) {
19 | Javalin.create(config -> {
20 | config.router.apiBuilder(() -> {
21 | get("/hello", ctx -> ctx.result("Hello World"));
22 | path("/api", () -> {
23 | get("/test", ctx -> ctx.result("Hello World"));
24 | get("/tast", ctx -> ctx.status(OK).result("Hello world"));
25 | get("/hest", ctx -> ctx.status(OK).result("Hello World"));
26 | get("/hast", ctx -> ctx.status(OK).result("Hello World").header("test", "tast"));
27 | });
28 | });
29 | })
30 | .start(7070);
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Javalin
2 | This readme is for Javalin developers.
3 | If you are looking for the general readme, see [.github/README.md](.github/README.md).
4 |
5 | ## Getting started
6 | ```sh
7 | gh repo clone javalin/javalin
8 | cd javalin
9 | ./mvnw package #(or `mvn package` if you have maven installed)
10 | ./mvnw test #(or `mvn test` if you have maven installed)
11 | ```
12 |
13 | If you run `test` before `package`, you will get an error in the OSGI artifact:
14 |
15 | ```
16 | [ERROR] Failed to execute goal org.apache.maven.plugins:maven-dependency-plugin:2.8:unpack-dependencies (unpack-everything) on project javalin-osgi: Artifact has not been packaged yet. When used on reactor artifact, unpack should be executed after packaging: see MDEP-98. -> [Help 1]
17 | ```
18 |
19 | ## Running maven commands
20 | We have Maven wrapper included in the project, which means that
21 | you can run Maven commands without having Maven installed on your system.
22 | Simply replace any `mvn goal` command with `./mvnw goal`.
23 |
24 | ## Deploy
25 | The `sonatype-oss-release` profile is used for releasing the project artifacts to Sonatype OSSRH (OSS Repository Hosting).
26 | This is only used by tipsy to release the project.
27 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/router/error/ErrorMapper.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.router.error
8 |
9 | import io.javalin.http.Context
10 | import io.javalin.http.Handler
11 | import io.javalin.http.Header
12 |
13 | class ErrorMapper {
14 |
15 | data class MapperEntry(val statusCode: Int, val contentType: String, val handler: Handler)
16 |
17 | private val errorHandlers = mutableSetOf()
18 |
19 | fun addHandler(statusCode: Int, contentType: String, handler: Handler) {
20 | errorHandlers.add(MapperEntry(statusCode, contentType, handler))
21 | }
22 |
23 | fun handle(statusCode: Int, ctx: Context) {
24 | errorHandlers.asSequence()
25 | .filter { it.statusCode == statusCode }
26 | .filter { it.contentType == "*" || ctx.contentTypeMatches(it.contentType) }
27 | .forEach { it.handler.handle(ctx) }
28 | }
29 |
30 | private fun Context.contentTypeMatches(contentType: String): Boolean =
31 | header(Header.ACCEPT)?.contains(contentType, ignoreCase = true) == true
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/http/UploadedFile.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.http
8 |
9 | import jakarta.servlet.http.Part
10 | import java.io.InputStream
11 |
12 | /**
13 | * Data class containing the content and meta-info of an uploaded file.
14 | * [content]: the file-content as an [InputStream]
15 | * [contentType]: the content-type passed by the client
16 | * [size]: the size of the file in bytes
17 | * [filename]: the file-name reported by the client
18 | * [extension]: the file-extension, extracted from the [filename]
19 | * @see Context.uploadedFile
20 | * @see Uploads in FAQ
21 | */
22 | class UploadedFile(private val part: Part) {
23 | fun content(): InputStream = part.inputStream
24 | fun contentAndClose(callback: (InputStream) -> T) = content().use { callback(it) }
25 | fun contentType(): String? = part.contentType
26 | fun filename(): String = part.submittedFileName
27 | fun extension(): String = part.submittedFileName.replaceBeforeLast(".", "")
28 | fun size(): Long = part.size
29 | }
30 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/websocket/WsExceptionMapper.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.websocket
8 |
9 | import io.javalin.util.JavalinLogger
10 | import io.javalin.util.Util
11 | import org.eclipse.jetty.websocket.api.StatusCode
12 |
13 | /**
14 | * Maps exception types to exception handlers.
15 | */
16 | class WsExceptionMapper {
17 |
18 | val handlers = mutableMapOf, WsExceptionHandler?>()
19 |
20 | /**
21 | * Handles the specific [exception]. If no handler is associated with the exception, then the
22 | * socket is closed with a status code that indicates internal error.
23 | */
24 | fun handle(exception: Exception, ctx: WsContext) {
25 | val handler = Util.findByClass(handlers, exception.javaClass)
26 | if (handler != null) {
27 | handler.handle(exception, ctx)
28 | } else {
29 | JavalinLogger.warn("Uncaught exception in WebSocket handler", exception)
30 | ctx.session.close(StatusCode.SERVER_ERROR, exception.message)
31 | }
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/javalin/src/test/java/io/javalin/TestContextHandlerType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2021 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 | package io.javalin;
7 |
8 | import io.javalin.http.HandlerType;
9 | import io.javalin.testing.TestUtil;
10 | import java.util.ArrayList;
11 | import java.util.List;
12 | import org.assertj.core.api.Assertions;
13 | import org.junit.jupiter.api.Test;
14 | import static io.javalin.http.HttpStatus.OK;
15 |
16 | public class TestContextHandlerType {
17 |
18 | @Test
19 | public void testHandlerTypeCanBeAccessedInContext() {
20 | TestUtil.test(Javalin.create(), (app, http) -> {
21 | List handlerTypes = new ArrayList<>();
22 | app.before(ctx -> handlerTypes.add(ctx.handlerType()));
23 | app.after(ctx -> handlerTypes.add(ctx.handlerType()));
24 | app.get("/", ctx -> handlerTypes.add(ctx.handlerType()));
25 |
26 | Assertions.assertThat(http.get("/").getStatus()).isEqualTo(OK.getCode());
27 | Assertions.assertThat(handlerTypes).containsExactly(HandlerType.BEFORE, HandlerType.GET, HandlerType.AFTER);
28 | });
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/javalin/src/test/java/io/javalin/testing/WebDriverUtil.kt:
--------------------------------------------------------------------------------
1 | package io.javalin.testing
2 |
3 | import io.github.bonigarcia.wdm.WebDriverManager
4 | import org.junit.jupiter.api.Assumptions.assumeTrue
5 | import org.openqa.selenium.chrome.ChromeDriver
6 | import org.openqa.selenium.chrome.ChromeOptions
7 |
8 | object WebDriverUtil {
9 |
10 | init {
11 | WebDriverManager.chromedriver().setup()
12 | }
13 |
14 | fun getDriver(): ChromeDriver {
15 | if (TestEnvironment.isNotCiServer && Math.random() < 0.8) {
16 | assumeTrue(false, "Skipping random WebDriver tests because we're not on a CI server and the tests are sooo slow")
17 | }
18 | if (TestEnvironment.isCiServer && TestEnvironment.isWindows) { // TODO: remove this when flakiness is fixed
19 | assumeTrue(false, "Skipping WebDriver tests on Windows CI server because they are flaky")
20 | }
21 | return ChromeDriver(ChromeOptions().apply {
22 | addArguments("--no-sandbox")
23 | addArguments("--headless=new")
24 | addArguments("--disable-gpu")
25 | addArguments("--remote-allow-origins=*")
26 | addArguments("--disable-dev-shm-usage")
27 | })
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/javalin/src/test/kotlin/io/javalin/examples/KotlinExample.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.examples
8 |
9 | import io.javalin.Javalin
10 | import io.javalin.http.HttpStatus
11 | import io.javalin.testing.TypedException
12 |
13 | fun main() {
14 |
15 | Javalin.create().apply {
16 |
17 | get("/users") { ctx ->
18 | ctx.result("")
19 | }
20 |
21 | post("/users/create") { ctx ->
22 | ctx.status(HttpStatus.CREATED)
23 | }
24 |
25 | patch("/users/update/:id") { ctx ->
26 | ctx.status(HttpStatus.NO_CONTENT)
27 | }
28 |
29 | delete("/users/delete/:id") { ctx ->
30 | ctx.status(HttpStatus.NO_CONTENT)
31 | }
32 |
33 | exception(Exception::class.java) { e, ctx ->
34 | e.printStackTrace()
35 | }
36 |
37 | exception(TypedException::class.java) { e, ctx ->
38 | e.proofOfType()
39 | }
40 |
41 | error(HttpStatus.NOT_FOUND) { ctx ->
42 | ctx.result("not found")
43 | }
44 |
45 | }.start(7070)
46 |
47 | }
48 |
49 |
--------------------------------------------------------------------------------
/javalin-rendering/src/main/java/io/javalin/rendering/template/JavalinMustache.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.rendering.template
8 |
9 | import com.github.mustachejava.DefaultMustacheFactory
10 | import com.github.mustachejava.MustacheFactory
11 | import io.javalin.http.Context
12 | import io.javalin.rendering.FileRenderer
13 | import io.javalin.rendering.util.RenderingDependency.MUSTACHE
14 | import io.javalin.rendering.util.Util
15 | import java.io.StringWriter
16 |
17 | class JavalinMustache @JvmOverloads constructor(
18 | private var mustacheFactory: MustacheFactory = defaultMustacheFactory()
19 | ) : FileRenderer {
20 |
21 | init {
22 | Util.throwIfNotAvailable(MUSTACHE)
23 | }
24 |
25 | override fun render(filePath: String, model: Map, context: Context): String {
26 | val stringWriter = StringWriter()
27 | mustacheFactory.compile(filePath).execute(stringWriter, model).close()
28 | return stringWriter.toString()
29 | }
30 |
31 | companion object {
32 | fun defaultMustacheFactory(): MustacheFactory = DefaultMustacheFactory("./")
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/javalin/src/main/java/io/javalin/validation/BodyValidator.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.validation
8 |
9 | import org.jetbrains.annotations.NotNull
10 |
11 | const val REQUEST_BODY = "REQUEST_BODY"
12 |
13 | open class BodyValidator internal constructor(value: String, clazz: Class, valueSupplier: () -> T?) : BaseValidator(Params("", clazz, value, valueSupplier = valueSupplier)) {
14 | fun check(check: Check, error: String) = check(fieldName = REQUEST_BODY, check, error)
15 | fun check(check: Check, error: ValidationError) = check(fieldName = REQUEST_BODY, check, error)
16 | fun check(fieldName: String, check: Check, error: String) = addRule(fieldName, { check(it!!) }, error) as BodyValidator
17 | fun check(fieldName: String, check: Check, error: ValidationError) = addRule(fieldName, { check(it!!) }, error) as BodyValidator
18 |
19 | @NotNull // there is a null-check in BaseValidator
20 | override fun get(): T = super.get()!!
21 |
22 | @NotNull
23 | override fun getOrThrow(exceptionFunction: (Map>>) -> Exception): T = super.getOrThrow(exceptionFunction)!!
24 | }
25 |
--------------------------------------------------------------------------------
/javalin-rendering/src/main/java/io/javalin/rendering/markdown/Commonmark.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Javalin - https://javalin.io
3 | * Copyright 2017 David Åse
4 | * Licensed under Apache 2.0: https://github.com/tipsy/javalin/blob/master/LICENSE
5 | */
6 |
7 | package io.javalin.rendering.markdown
8 |
9 | import io.javalin.http.Context
10 | import io.javalin.rendering.FileRenderer
11 | import io.javalin.rendering.util.RenderingDependency.COMMONMARK
12 | import io.javalin.rendering.util.Util
13 | import org.commonmark.parser.Parser
14 | import org.commonmark.renderer.html.HtmlRenderer
15 |
16 | class JavalinCommonmark @JvmOverloads constructor(
17 | private var renderer: HtmlRenderer = defaultRenderer(),
18 | private var parser: Parser = defaultParser()
19 | ) : FileRenderer {
20 |
21 | init {
22 | Util.throwIfNotAvailable(COMMONMARK)
23 | }
24 |
25 | override fun render(filePath: String, model: Map, context: Context): String {
26 | val fileContent = JavalinCommonmark::class.java.getResource(filePath).readText()
27 | return renderer.render(parser.parse(fileContent))
28 | }
29 |
30 | companion object {
31 | fun defaultRenderer(): HtmlRenderer = HtmlRenderer.builder().build()
32 | fun defaultParser(): Parser = Parser.builder().build()
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/javalin-ssl/src/test/resources/server/malformed.p12:
--------------------------------------------------------------------------------
1 | ����
2 | y���&]
3 | ު��fϰ��˥��K���ˠ�(�Mg���
4 | &�^��{��ބOm�Y$*q��l7����v����Co���/��r��جk�H?7��fᾉ����!"�� )�J���?=Z�h��y��Z�b���T��.m�y)1A4�n�/O6��"<͜��ǚĸM�ϼdb�y���>1�v��<�)�)�e�G�_�ײ��R�K��g�;-�m�1E