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