15
15
*/
16
16
package io .qameta .allure ;
17
17
18
+ import com .sun .net .httpserver .HttpExchange ;
19
+ import com .sun .net .httpserver .HttpServer ;
18
20
import io .qameta .allure .config .ConfigLoader ;
19
21
import io .qameta .allure .core .Configuration ;
20
22
import io .qameta .allure .core .Plugin ;
23
25
import io .qameta .allure .option .ReportNameOptions ;
24
26
import io .qameta .allure .plugin .DefaultPluginLoader ;
25
27
import io .qameta .allure .util .DeleteVisitor ;
26
- import io .undertow .Handlers ;
27
- import io .undertow .Undertow ;
28
- import io .undertow .server .handlers .resource .PathResourceManager ;
29
28
import org .apache .commons .io .FileUtils ;
30
29
import org .slf4j .Logger ;
31
30
import org .slf4j .LoggerFactory ;
32
31
33
32
import java .awt .AWTError ;
34
33
import java .awt .Desktop ;
35
34
import java .io .IOException ;
35
+ import java .io .OutputStream ;
36
36
import java .net .InetSocketAddress ;
37
37
import java .net .URI ;
38
+ import java .nio .charset .StandardCharsets ;
38
39
import java .nio .file .DirectoryStream ;
39
40
import java .nio .file .Files ;
40
41
import java .nio .file .Path ;
44
45
import java .util .Optional ;
45
46
import java .util .stream .Collectors ;
46
47
48
+ import static io .qameta .allure .DefaultResultsVisitor .probeContentType ;
47
49
import static java .lang .String .format ;
48
50
49
51
/**
@@ -235,7 +237,7 @@ public ExitCode serve(final List<Path> resultsDirectories,
235
237
*/
236
238
public ExitCode open (final Path reportDirectory , final String host , final int port ) {
237
239
LOGGER .info ("Starting web server..." );
238
- final Undertow server ;
240
+ final HttpServer server ;
239
241
try {
240
242
server = setUpServer (host , port , reportDirectory );
241
243
server .start ();
@@ -244,19 +246,11 @@ public ExitCode open(final Path reportDirectory, final String host, final int po
244
246
return ExitCode .GENERIC_ERROR ;
245
247
}
246
248
247
- final List <Undertow .ListenerInfo > listenerInfos = server .getListenerInfo ();
248
- if (listenerInfos .isEmpty ()) {
249
- LOGGER .error ("Can't find any listener info" );
250
- return ExitCode .GENERIC_ERROR ;
251
- }
252
- final Undertow .ListenerInfo listenerInfo = listenerInfos .get (0 );
253
- final InetSocketAddress socketAddress = (InetSocketAddress ) listenerInfo .getAddress ();
254
- final URI uri = URI .create (
255
- listenerInfo .getProtcol ()
256
- + "://"
257
- + socketAddress .getHostString ()
258
- + ":"
259
- + socketAddress .getPort ()
249
+ final InetSocketAddress socketAddress = server .getAddress ();
250
+ final URI uri = URI .create ("http://"
251
+ + socketAddress .getHostString ()
252
+ + ":"
253
+ + socketAddress .getPort ()
260
254
);
261
255
262
256
try {
@@ -320,22 +314,45 @@ protected Configuration createReportConfiguration(
320
314
}
321
315
322
316
/**
323
- * Set up Undertow server to serve Allure Report.
317
+ * Set up HttpServer to serve Allure Report.
324
318
*
325
319
* @param host the host
326
320
* @param port the port
327
321
* @param reportDirectory the report directory
328
322
* @return self for method chaining
329
323
* @throws IOException the io exception
330
324
*/
331
- protected Undertow setUpServer (final String host , final int port , final Path reportDirectory ) throws IOException {
332
- return Undertow .builder ()
333
- .addHttpListener (port , Objects .isNull (host ) ? "localhost" : host )
334
- .setHandler (Handlers
335
- .resource (new PathResourceManager (reportDirectory .toRealPath ()))
336
- .setDirectoryListingEnabled (true )
337
- )
338
- .build ();
325
+ protected HttpServer setUpServer (final String host , final int port , final Path reportDirectory ) throws IOException {
326
+ final HttpServer server = HttpServer
327
+ .create (new InetSocketAddress (Objects .isNull (host ) ? "localhost" : host , port ), 0 );
328
+
329
+ server .createContext ("/" , exchange -> {
330
+ final Path resolve = reportDirectory .resolve ("." + exchange .getRequestURI ().getPath ());
331
+ if (Files .isDirectory (resolve )) {
332
+ serveFile (exchange , resolve .resolve ("index.html" ));
333
+ } else {
334
+ serveFile (exchange , resolve );
335
+ }
336
+ });
337
+
338
+ return server ;
339
+ }
340
+
341
+ private static void serveFile (final HttpExchange exchange , final Path resolve ) throws IOException {
342
+ if (Files .isRegularFile (resolve )) {
343
+ final String contentType = probeContentType (resolve );
344
+ exchange .sendResponseHeaders (200 , Files .size (resolve ));
345
+ exchange .getResponseHeaders ().add ("Content-Type" , contentType );
346
+ try (OutputStream os = exchange .getResponseBody ()) {
347
+ Files .copy (resolve , os );
348
+ }
349
+ } else {
350
+ final String response = "404 Not Found" ;
351
+ exchange .sendResponseHeaders (404 , response .length ());
352
+ try (OutputStream os = exchange .getResponseBody ()) {
353
+ os .write (response .getBytes (StandardCharsets .UTF_8 ));
354
+ }
355
+ }
339
356
}
340
357
341
358
/**
0 commit comments