| 1 | package com.jsql.model.accessible; | |
| 2 | ||
| 3 | import com.jsql.model.InjectionModel; | |
| 4 | import com.jsql.view.subscriber.Seal; | |
| 5 | import com.jsql.util.ConnectionUtil; | |
| 6 | import com.jsql.util.LogLevelUtil; | |
| 7 | import org.apache.commons.lang3.StringUtils; | |
| 8 | import org.apache.logging.log4j.LogManager; | |
| 9 | import org.apache.logging.log4j.Logger; | |
| 10 | ||
| 11 | import java.net.URI; | |
| 12 | import java.net.http.HttpRequest; | |
| 13 | import java.net.http.HttpRequest.BodyPublishers; | |
| 14 | import java.net.http.HttpResponse; | |
| 15 | import java.net.http.HttpResponse.BodyHandlers; | |
| 16 | import java.time.Duration; | |
| 17 | import java.util.AbstractMap.SimpleEntry; | |
| 18 | import java.util.Objects; | |
| 19 | import java.util.Optional; | |
| 20 | import java.util.concurrent.Callable; | |
| 21 | import java.util.stream.Stream; | |
| 22 | ||
| 23 | /** | |
| 24 | * Thread unit to test if an administration page exists on the server. | |
| 25 | * The process can be cancelled by the user. | |
| 26 | */ | |
| 27 | public class CallableHttpHead implements Callable<CallableHttpHead> { | |
| 28 | | |
| 29 | private static final Logger LOGGER = LogManager.getRootLogger(); | |
| 30 | | |
| 31 | /** | |
| 32 | * URL to an administration page on the website to get tested. | |
| 33 | */ | |
| 34 | private final String urlAdminPage; | |
| 35 | | |
| 36 | /** | |
| 37 | * HTTP header response code. | |
| 38 | */ | |
| 39 | private String responseCodeHttp = StringUtils.EMPTY; | |
| 40 | ||
| 41 | private final InjectionModel injectionModel; | |
| 42 | ||
| 43 | private final String metadataInjectionProcess; | |
| 44 | | |
| 45 | /** | |
| 46 | * Create a callable to find admin page. | |
| 47 | * @param urlAdminPage URL of admin page | |
| 48 | */ | |
| 49 | public CallableHttpHead(String urlAdminPage, InjectionModel injectionModel, String metadataInjectionProcess) { | |
| 50 | this.urlAdminPage = urlAdminPage; | |
| 51 | this.injectionModel= injectionModel; | |
| 52 | this.metadataInjectionProcess= metadataInjectionProcess; | |
| 53 | } | |
| 54 | ||
| 55 | /** | |
| 56 | * Call URL to an administration page in HEAD mode and send the result back to view. | |
| 57 | */ | |
| 58 | @Override | |
| 59 | public CallableHttpHead call() { | |
| 60 |
1
1. call : negated conditional → NO_COVERAGE |
if (this.injectionModel.getResourceAccess().isSearchAdminStopped()) { |
| 61 |
1
1. call : replaced return value with null for com/jsql/model/accessible/CallableHttpHead::call → NO_COVERAGE |
return this; |
| 62 | } | |
| 63 | | |
| 64 | try { | |
| 65 | var builderHttpRequest = HttpRequest.newBuilder() | |
| 66 | .uri(URI.create(this.urlAdminPage)) | |
| 67 | .method("HEAD", BodyPublishers.noBody()) | |
| 68 | .timeout(Duration.ofSeconds(4)); | |
| 69 | | |
| 70 | Stream.of( | |
| 71 | this.injectionModel.getMediatorUtils().parameterUtil().getHeaderFromEntries().split("\\\\r\\\\n") | |
| 72 | ) | |
| 73 | .map(e -> { | |
| 74 |
1
1. lambda$call$0 : negated conditional → NO_COVERAGE |
if (e.split(":").length == 2) { |
| 75 |
1
1. lambda$call$0 : replaced return value with null for com/jsql/model/accessible/CallableHttpHead::lambda$call$0 → NO_COVERAGE |
return new SimpleEntry<>( |
| 76 | e.split(":")[0], | |
| 77 | e.split(":")[1] | |
| 78 | ); | |
| 79 | } else { | |
| 80 | return null; | |
| 81 | } | |
| 82 | }) | |
| 83 | .filter(Objects::nonNull) | |
| 84 |
1
1. call : removed call to java/util/stream/Stream::forEach → NO_COVERAGE |
.forEach(e -> builderHttpRequest.header(e.getKey(), e.getValue())); |
| 85 | | |
| 86 | var httpRequest = builderHttpRequest.build(); | |
| 87 | var httpClient = this.injectionModel.getMediatorUtils().connectionUtil().getHttpClient() | |
| 88 | .connectTimeout(Duration.ofSeconds(4)) | |
| 89 | .build(); | |
| 90 | HttpResponse<Void> response = httpClient.send(httpRequest, BodyHandlers.discarding()); | |
| 91 | ||
| 92 | this.responseCodeHttp = String.valueOf(response.statusCode()); | |
| 93 | ||
| 94 |
1
1. call : removed call to com/jsql/model/InjectionModel::sendToViews → NO_COVERAGE |
this.injectionModel.sendToViews(new Seal.MessageHeader( |
| 95 | this.urlAdminPage, | |
| 96 | null, | |
| 97 | ConnectionUtil.getHeadersMap(httpRequest.headers()), | |
| 98 | ConnectionUtil.getHeadersMap(response), | |
| 99 | null, | |
| 100 | null, | |
| 101 | null, | |
| 102 | this.metadataInjectionProcess, | |
| 103 | null | |
| 104 | )); | |
| 105 | } catch (InterruptedException e) { | |
| 106 | LOGGER.log(LogLevelUtil.IGNORE, e, e); | |
| 107 |
1
1. call : removed call to java/lang/Thread::interrupt → NO_COVERAGE |
Thread.currentThread().interrupt(); |
| 108 | } catch (Exception e) { | |
| 109 | var eMessageImplicit = String.format( | |
| 110 | "Problem connecting to %s (implicit reason): %s", | |
| 111 | this.urlAdminPage, | |
| 112 | InjectionModel.getImplicitReason(e) | |
| 113 | ); | |
| 114 | String eMessage = Optional.ofNullable(e.getMessage()).orElse(eMessageImplicit); | |
| 115 | LOGGER.log(LogLevelUtil.CONSOLE_ERROR, eMessage); | |
| 116 | } | |
| 117 | | |
| 118 |
1
1. call : replaced return value with null for com/jsql/model/accessible/CallableHttpHead::call → NO_COVERAGE |
return this; |
| 119 | } | |
| 120 | ||
| 121 | /** | |
| 122 | * Check if HTTP response is either 2xx or 3xx, which corresponds to | |
| 123 | * an acceptable response from the website. | |
| 124 | * @return true if HTTP code start with 2 or 3 | |
| 125 | */ | |
| 126 | public boolean isHttpResponseOk() { | |
| 127 |
2
1. isHttpResponseOk : replaced boolean return with false for com/jsql/model/accessible/CallableHttpHead::isHttpResponseOk → NO_COVERAGE 2. isHttpResponseOk : replaced boolean return with true for com/jsql/model/accessible/CallableHttpHead::isHttpResponseOk → NO_COVERAGE |
return this.responseCodeHttp.matches("[23]\\d\\d"); |
| 128 | } | |
| 129 | | |
| 130 | | |
| 131 | // Getters | |
| 132 | | |
| 133 | public String getUrl() { | |
| 134 |
1
1. getUrl : replaced return value with "" for com/jsql/model/accessible/CallableHttpHead::getUrl → NO_COVERAGE |
return this.urlAdminPage; |
| 135 | } | |
| 136 | } | |
Mutations | ||
| 60 |
1.1 |
|
| 61 |
1.1 |
|
| 74 |
1.1 |
|
| 75 |
1.1 |
|
| 84 |
1.1 |
|
| 94 |
1.1 |
|
| 107 |
1.1 |
|
| 118 |
1.1 |
|
| 127 |
1.1 2.2 |
|
| 134 |
1.1 |