RequestLine.java

1
package com.renomad.minum.web;
2
3
import com.renomad.minum.logging.ILogger;
4
import com.renomad.minum.security.ForbiddenUseException;
5
6
import java.net.URLDecoder;
7
import java.util.*;
8
9
import static com.renomad.minum.utils.Invariants.mustNotBeNull;
10
import static java.nio.charset.StandardCharsets.UTF_8;
11
12
/**
13
 * This class holds data and methods for dealing with the
14
 * "start line" in an HTTP request.  For example,
15
 * GET /foo HTTP/1.1
16
 */
17
public final class RequestLine {
18
19
    private final Method method;
20
    private final PathDetails pathDetails;
21
    private final HttpVersion version;
22
    private final String rawValue;
23
    private final ILogger logger;
24
    static final int MAX_QUERY_STRING_KEYS_COUNT = 50;
25
26
    /**
27
     * @param method GET, POST, etc.
28
     * @param pathDetails See {@link PathDetails}
29
     * @param version the version of HTTP (1.0 or 1.1) we're receiving
30
     * @param rawValue the entire raw string of the start line
31
     */
32
    public RequestLine(
33
            Method method,
34
            PathDetails pathDetails,
35
            HttpVersion version,
36
            String rawValue,
37
            ILogger logger
38
    ) {
39
        this.method = method;
40
        this.pathDetails = pathDetails;
41
        this.version = version;
42
        this.rawValue = rawValue;
43
        this.logger = logger;
44
    }
45
46
47
48
    public static final RequestLine EMPTY = new RequestLine(Method.NONE, PathDetails.empty, HttpVersion.NONE, "", null);
49
50
    /**
51
     * Returns a map of the key-value pairs in the URL,
52
     * for example in {@code http://foo.com?name=alice} you
53
     * have a key of name and a value of alice.
54
     */
55
    public Map<String, String> queryString() {
56 2 1. queryString : negated conditional → KILLED
2. queryString : negated conditional → KILLED
        if (pathDetails == null || pathDetails.getQueryString().isEmpty()) {
57
            return Map.of();
58
        } else {
59 1 1. queryString : replaced return value with Collections.emptyMap for com/renomad/minum/web/RequestLine::queryString → KILLED
            return new HashMap<>(pathDetails.getQueryString());
60
        }
61
62
    }
63
64
    /**
65
     * These are the HTTP methods we handle.
66
     */
67
    public enum Method {
68
        GET,
69
        POST,
70
        PUT,
71
        DELETE,
72
        TRACE,
73
        PATCH,
74
        OPTIONS,
75
        HEAD,
76
77
        /**
78
         * Represents the null value of Method
79
         */
80
        NONE;
81
82
        /**
83
         * Get the correct HTTP method for a string provided by the user
84
         */
85
        public static Method getMethod(String userSuppliedMethod) {
86
            // if the method they gave us is longer than the maximum method
87
            // we know about, it's invalid, and return NONE.
88 2 1. getMethod : changed conditional boundary → TIMED_OUT
2. getMethod : negated conditional → KILLED
            if (userSuppliedMethod.length() > 7) {
89 1 1. getMethod : replaced return value with null for com/renomad/minum/web/RequestLine$Method::getMethod → KILLED
                return NONE;
90
            }
91
            // necessary because we need to potentially convert to lowercase
92
            var sb = new StringBuilder(userSuppliedMethod.length());
93
94 2 1. getMethod : negated conditional → KILLED
2. getMethod : changed conditional boundary → KILLED
            for (int i = 0; i < userSuppliedMethod.length(); i++) {
95
                char c = userSuppliedMethod.charAt(i);
96 4 1. getMethod : negated conditional → KILLED
2. getMethod : changed conditional boundary → KILLED
3. getMethod : negated conditional → KILLED
4. getMethod : changed conditional boundary → KILLED
                if ((c >= 65 && c <= 90)) { // characters in methods are pure ascii, no UTF-8 to worry about
97
                    sb.append(c);
98 4 1. getMethod : changed conditional boundary → SURVIVED
2. getMethod : changed conditional boundary → KILLED
3. getMethod : negated conditional → KILLED
4. getMethod : negated conditional → KILLED
                } else if (c >= 97 && c <= 122) { // if characters are lower-case, make them upper-case
99 1 1. getMethod : Replaced integer subtraction with addition → KILLED
                    sb.append((char)(c - 32));
100
                } else {
101 1 1. getMethod : replaced return value with null for com/renomad/minum/web/RequestLine$Method::getMethod → KILLED
                    return NONE; // if any of the characters are non-ascii-alphabet, it's invalid, bail.
102
                }
103
            }
104 1 1. getMethod : replaced return value with null for com/renomad/minum/web/RequestLine$Method::getMethod → KILLED
            return switch (sb.toString()) {
105
                case "GET" -> GET;
106
                case "POST" -> POST;
107
                case "PUT" -> PUT;
108
                case "DELETE" -> DELETE;
109
                case "TRACE" -> TRACE;
110
                case "PATCH" -> PATCH;
111
                case "OPTIONS" -> OPTIONS;
112
                case "HEAD" -> HEAD;
113
                default -> NONE;
114
            };
115
        }
116
    }
117
118
    /**
119
     * Given the string value of a Request Line (like GET /hello HTTP/1.1)
120
     * validate and extract the values for our use.
121
     */
122
    public RequestLine extractRequestLine(String rawFullStartLine) {
123
        mustNotBeNull(rawFullStartLine);
124 1 1. extractRequestLine : negated conditional → KILLED
        if (rawFullStartLine.isEmpty()) {
125
            throw new BadRequestException("Error: The request line was empty");
126
        }
127
        RequestLineRawValues rawValues = requestLineTokenizer(rawFullStartLine);
128 1 1. extractRequestLine : negated conditional → KILLED
        if (rawValues == null) {
129
            throw new BadRequestException("Unable to tokenize the request line into its constituent three parts, GET + path + protocol: " + rawFullStartLine);
130
        }
131
        Method myMethod;
132
        myMethod = Method.getMethod(rawValues.method());
133 1 1. extractRequestLine : negated conditional → KILLED
        if (myMethod.equals(Method.NONE)) {
134
            throw new BadRequestException("Unable to convert method to enum.  Returning empty request line.  Method value provided: " + rawValues.method() + ".  Full line: " + rawFullStartLine);
135
        }
136 1 1. extractRequestLine : negated conditional → KILLED
        if (rawValues.path().isBlank()) {
137
            throw new BadRequestException("No path provided in request line.  Raw value: " + rawFullStartLine);
138
        }
139
        PathDetails pd = extractPathDetails(rawValues.path(), rawFullStartLine);
140
        HttpVersion httpVersion = getHttpVersion(rawValues.protocol());
141 1 1. extractRequestLine : negated conditional → KILLED
        if (httpVersion.equals(HttpVersion.NONE)) {
142
            throw new BadRequestException("Did not recognize the HTTP protocol as one we handle: " + rawValues.protocol() + ".  Full line: " + rawFullStartLine);
143
        }
144
145 1 1. extractRequestLine : replaced return value with null for com/renomad/minum/web/RequestLine::extractRequestLine → KILLED
        return new RequestLine(myMethod, pd, httpVersion, rawFullStartLine, logger);
146
    }
147
148
    /**
149
     * Split the request line into three parts - a method (e.g. GET), a
150
     * path (e.g. "/" or "/helloworld/hi/foo?name=hello") and a protocol,
151
     * which is typically "HTTP/1.1" but might be "HTTP/1.0" in some cases
152
     * <br>
153
     * If we don't find exactly three parts, we will return null, which
154
     * is interpreted by the calling method to mean we didn't receive a
155
     * valid request line.
156
     * @param rawRequestLine the full string of the first line received
157
     *                       after the socket is connected to the client.
158
     */
159
    private RequestLineRawValues requestLineTokenizer(String rawRequestLine) {
160
        int firstSpace = rawRequestLine.indexOf(' ');
161 1 1. requestLineTokenizer : negated conditional → KILLED
        if (firstSpace == -1) {
162
            return null;
163
        }
164 1 1. requestLineTokenizer : Replaced integer addition with subtraction → KILLED
        int secondSpace = rawRequestLine.indexOf(' ', firstSpace + 1);
165 1 1. requestLineTokenizer : negated conditional → KILLED
        if (secondSpace == -1) {
166
            return null;
167
        }
168 1 1. requestLineTokenizer : Replaced integer addition with subtraction → KILLED
        int thirdSpace = rawRequestLine.indexOf(' ', secondSpace + 1);
169 1 1. requestLineTokenizer : negated conditional → KILLED
        if (thirdSpace != -1) {
170
            return null;
171
        }
172
        String myMethod = rawRequestLine.substring(0, firstSpace);
173 1 1. requestLineTokenizer : Replaced integer addition with subtraction → KILLED
        String path = rawRequestLine.substring(firstSpace + 1, secondSpace);
174 1 1. requestLineTokenizer : Replaced integer addition with subtraction → KILLED
        String protocol = rawRequestLine.substring(secondSpace + 1);
175 1 1. requestLineTokenizer : replaced return value with null for com/renomad/minum/web/RequestLine::requestLineTokenizer → KILLED
        return new RequestLineRawValues(myMethod, path, protocol);
176
    }
177
178
    private PathDetails extractPathDetails(String path, String rawFullStartLine) {
179
        PathDetails pd;
180
        // the request line will have a forward slash at the beginning of
181
        // the path.  Remove that here.
182 1 1. extractPathDetails : negated conditional → KILLED
        if (path.charAt(0) != '/') {
183
            throw new BadRequestException("Minum only handles origin-form request targets. Our input: " + path + ". Full line: " + rawFullStartLine);
184
        }
185
186
        String adjustedPath = path.substring(1);
187
        int locationOfQueryBegin = adjustedPath.indexOf("?");
188 2 1. extractPathDetails : negated conditional → KILLED
2. extractPathDetails : changed conditional boundary → KILLED
        if (locationOfQueryBegin >= 0) {
189
            // in this case, we found a question mark, suggesting that a query string exists
190 1 1. extractPathDetails : Replaced integer addition with subtraction → KILLED
            String rawQueryString = adjustedPath.substring(locationOfQueryBegin + 1);
191
            String isolatedPath = adjustedPath.substring(0, locationOfQueryBegin);
192
            Map<String, String> queryString = extractMapFromQueryString(rawQueryString);
193
            pd = new PathDetails(isolatedPath, rawQueryString, queryString);
194
        } else {
195
            // in this case, no question mark was found, thus no query string
196
            pd = new PathDetails(adjustedPath, null, null);
197
        }
198 1 1. extractPathDetails : replaced return value with null for com/renomad/minum/web/RequestLine::extractPathDetails → KILLED
        return pd;
199
    }
200
201
202
    /**
203
     * Given a string containing the combined key-values in
204
     * a query string (e.g. foo=bar&name=alice), split that
205
     * into a map of the key to value (e.g. foo to bar, and name to alice)
206
     */
207
    Map<String, String> extractMapFromQueryString(String rawQueryString) {
208
        Map<String, String> queryStrings = new HashMap<>();
209
        StringTokenizer tokenizer = new StringTokenizer(rawQueryString, "&");
210
        // we'll only take less than MAX_QUERY_STRING_KEYS_COUNT
211 2 1. extractMapFromQueryString : Changed increment from 1 to -1 → TIMED_OUT
2. extractMapFromQueryString : negated conditional → KILLED
        for (int i = 0; tokenizer.hasMoreTokens(); i++) {
212 2 1. extractMapFromQueryString : changed conditional boundary → TIMED_OUT
2. extractMapFromQueryString : negated conditional → KILLED
            if (i >= MAX_QUERY_STRING_KEYS_COUNT) throw new ForbiddenUseException("User tried providing too many query string keys.  max: " + MAX_QUERY_STRING_KEYS_COUNT);
213
            // this should give us a key and value joined with an equal sign, e.g. foo=bar
214
            String currentKeyValue = tokenizer.nextToken();
215
            int equalSignLocation = currentKeyValue.indexOf("=");
216
217 1 1. extractMapFromQueryString : negated conditional → KILLED
            if (equalSignLocation == -1) {
218
                throw new BadRequestException("Discovered invalid key-value pair in query string for key (\"%s\").  Full query string: %s".formatted(currentKeyValue, rawQueryString));
219
            }
220
            String key = currentKeyValue.substring(0, equalSignLocation);
221 1 1. extractMapFromQueryString : Replaced integer addition with subtraction → KILLED
            String myRawValue = currentKeyValue.substring(equalSignLocation + 1);
222
            try {
223
                String value = URLDecoder.decode(myRawValue, UTF_8);
224
                final var result = queryStrings.put(key, value);
225
226 1 1. extractMapFromQueryString : negated conditional → KILLED
                if (result != null) {
227
                    throw new BadRequestException("Unexpected: key (" +key + ") was duplicated in the query line - previous value was " + result + " and was overwritten by " + value);
228
                }
229
            } catch (IllegalArgumentException ex) {
230
                throw new BadRequestException("Query string parsing failed for key: (%s) value: (%s)".formatted(key, myRawValue), ex);
231
            }
232
        }
233 1 1. extractMapFromQueryString : replaced return value with Collections.emptyMap for com/renomad/minum/web/RequestLine::extractMapFromQueryString → KILLED
        return queryStrings;
234
    }
235
236
    /**
237
     * Extract the HTTP version from the start line
238
     */
239
    private HttpVersion getHttpVersion(String version) {
240 1 1. getHttpVersion : negated conditional → KILLED
        if (version.equals("HTTP/1.1")) {
241 1 1. getHttpVersion : replaced return value with null for com/renomad/minum/web/RequestLine::getHttpVersion → KILLED
            return HttpVersion.ONE_DOT_ONE;
242 1 1. getHttpVersion : negated conditional → KILLED
        } else if (version.equals("HTTP/1.0")) {
243 1 1. getHttpVersion : replaced return value with null for com/renomad/minum/web/RequestLine::getHttpVersion → KILLED
            return HttpVersion.ONE_DOT_ZERO;
244
        } else {
245 1 1. getHttpVersion : replaced return value with null for com/renomad/minum/web/RequestLine::getHttpVersion → TIMED_OUT
            return HttpVersion.NONE;
246
        }
247
    }
248
249
    /**
250
     * Return the method of this request-line.  For example, GET, PUT, POST...
251
     */
252
    public Method getMethod() {
253 1 1. getMethod : replaced return value with null for com/renomad/minum/web/RequestLine::getMethod → KILLED
        return method;
254
    }
255
256
    /**
257
     * This returns an object which contains essential information about the path
258
     * in the request line.  For example, if the request line is "GET /sample?foo=bar HTTP/1.1",
259
     * this would hold data for the path ("sample") and the query string ("foo=bar")
260
     */
261
    public PathDetails getPathDetails() {
262 1 1. getPathDetails : replaced return value with null for com/renomad/minum/web/RequestLine::getPathDetails → KILLED
        return pathDetails;
263
    }
264
265
    /**
266
     * Gets the HTTP version, either 1.0 or 1.1
267
     */
268
    public HttpVersion getVersion() {
269 1 1. getVersion : replaced return value with null for com/renomad/minum/web/RequestLine::getVersion → TIMED_OUT
        return this.version;
270
    }
271
272
    /**
273
     * Get the string value of this request line, such as "GET /sample.html HTTP/1.1"
274
     */
275
    public String getRawValue() {
276 1 1. getRawValue : replaced return value with "" for com/renomad/minum/web/RequestLine::getRawValue → KILLED
        return rawValue;
277
    }
278
279
    @Override
280
    public boolean equals(Object o) {
281 2 1. equals : negated conditional → KILLED
2. equals : replaced boolean return with false for com/renomad/minum/web/RequestLine::equals → KILLED
        if (this == o) return true;
282 3 1. equals : negated conditional → TIMED_OUT
2. equals : negated conditional → TIMED_OUT
3. equals : replaced boolean return with true for com/renomad/minum/web/RequestLine::equals → TIMED_OUT
        if (o == null || getClass() != o.getClass()) return false;
283
        RequestLine that = (RequestLine) o;
284 6 1. equals : negated conditional → TIMED_OUT
2. equals : negated conditional → TIMED_OUT
3. equals : negated conditional → TIMED_OUT
4. equals : negated conditional → TIMED_OUT
5. equals : negated conditional → TIMED_OUT
6. equals : replaced boolean return with true for com/renomad/minum/web/RequestLine::equals → KILLED
        return method == that.method && Objects.equals(pathDetails, that.pathDetails) && version == that.version && Objects.equals(rawValue, that.rawValue) && Objects.equals(logger, that.logger);
285
    }
286
287
    @Override
288
    public int hashCode() {
289 1 1. hashCode : replaced int return with 0 for com/renomad/minum/web/RequestLine::hashCode → KILLED
        return Objects.hash(method, pathDetails, version, rawValue, logger);
290
    }
291
292
    @Override
293
    public String toString() {
294 1 1. toString : replaced return value with "" for com/renomad/minum/web/RequestLine::toString → TIMED_OUT
        return "RequestLine{" +
295
                "method=" + method +
296
                ", pathDetails=" + pathDetails +
297
                ", version=" + version +
298
                ", rawValue='" + rawValue + '\'' +
299
                ", logger=" + logger +
300
                '}';
301
    }
302
}

Mutations

56

1.1
Location : queryString
Killed by : com.renomad.minum.web.EndpointTests
negated conditional → KILLED

2.2
Location : queryString
Killed by : com.renomad.minum.web.EndpointTests
negated conditional → KILLED

59

1.1
Location : queryString
Killed by : com.renomad.minum.web.EndpointTests
replaced return value with Collections.emptyMap for com/renomad/minum/web/RequestLine::queryString → KILLED

88

1.1
Location : getMethod
Killed by : none
changed conditional boundary → TIMED_OUT

2.2
Location : getMethod
Killed by : com.renomad.minum.web.RequestLineTests
negated conditional → KILLED

89

1.1
Location : getMethod
Killed by : com.renomad.minum.web.RequestLineTests
replaced return value with null for com/renomad/minum/web/RequestLine$Method::getMethod → KILLED

94

1.1
Location : getMethod
Killed by : com.renomad.minum.web.RequestLineTests
negated conditional → KILLED

2.2
Location : getMethod
Killed by : com.renomad.minum.web.RequestLineTests
changed conditional boundary → KILLED

96

1.1
Location : getMethod
Killed by : com.renomad.minum.web.RequestLineTests
negated conditional → KILLED

2.2
Location : getMethod
Killed by : com.renomad.minum.web.RequestLineTests
changed conditional boundary → KILLED

3.3
Location : getMethod
Killed by : com.renomad.minum.web.RequestLineTests
negated conditional → KILLED

4.4
Location : getMethod
Killed by : com.renomad.minum.FunctionalTests.test_EdgeCase_Response_MultiCookies(com.renomad.minum.FunctionalTests)
changed conditional boundary → KILLED

98

1.1
Location : getMethod
Killed by : com.renomad.minum.web.RequestLineTests
changed conditional boundary → KILLED

2.2
Location : getMethod
Killed by : com.renomad.minum.web.RequestLineTests
negated conditional → KILLED

3.3
Location : getMethod
Killed by : none
changed conditional boundary → SURVIVED
Covering tests

4.4
Location : getMethod
Killed by : com.renomad.minum.web.RequestLineTests
negated conditional → KILLED

99

1.1
Location : getMethod
Killed by : com.renomad.minum.web.RequestLineTests
Replaced integer subtraction with addition → KILLED

101

1.1
Location : getMethod
Killed by : com.renomad.minum.web.RequestLineTests
replaced return value with null for com/renomad/minum/web/RequestLine$Method::getMethod → KILLED

104

1.1
Location : getMethod
Killed by : com.renomad.minum.web.RequestLineTests
replaced return value with null for com/renomad/minum/web/RequestLine$Method::getMethod → KILLED

124

1.1
Location : extractRequestLine
Killed by : com.renomad.minum.web.RequestLineTests
negated conditional → KILLED

128

1.1
Location : extractRequestLine
Killed by : com.renomad.minum.web.RequestLineTests
negated conditional → KILLED

133

1.1
Location : extractRequestLine
Killed by : com.renomad.minum.web.RequestLineTests
negated conditional → KILLED

136

1.1
Location : extractRequestLine
Killed by : com.renomad.minum.web.RequestLineTests
negated conditional → KILLED

141

1.1
Location : extractRequestLine
Killed by : com.renomad.minum.web.RequestLineTests
negated conditional → KILLED

145

1.1
Location : extractRequestLine
Killed by : com.renomad.minum.web.RequestLineTests
replaced return value with null for com/renomad/minum/web/RequestLine::extractRequestLine → KILLED

161

1.1
Location : requestLineTokenizer
Killed by : com.renomad.minum.web.RequestLineTests
negated conditional → KILLED

164

1.1
Location : requestLineTokenizer
Killed by : com.renomad.minum.web.RequestLineTests
Replaced integer addition with subtraction → KILLED

165

1.1
Location : requestLineTokenizer
Killed by : com.renomad.minum.web.RequestLineTests
negated conditional → KILLED

168

1.1
Location : requestLineTokenizer
Killed by : com.renomad.minum.web.RequestLineTests
Replaced integer addition with subtraction → KILLED

169

1.1
Location : requestLineTokenizer
Killed by : com.renomad.minum.web.RequestLineTests
negated conditional → KILLED

173

1.1
Location : requestLineTokenizer
Killed by : com.renomad.minum.web.RequestLineTests
Replaced integer addition with subtraction → KILLED

174

1.1
Location : requestLineTokenizer
Killed by : com.renomad.minum.web.RequestLineTests
Replaced integer addition with subtraction → KILLED

175

1.1
Location : requestLineTokenizer
Killed by : com.renomad.minum.web.RequestLineTests
replaced return value with null for com/renomad/minum/web/RequestLine::requestLineTokenizer → KILLED

182

1.1
Location : extractPathDetails
Killed by : com.renomad.minum.web.RequestLineTests
negated conditional → KILLED

188

1.1
Location : extractPathDetails
Killed by : com.renomad.minum.web.RequestLineTests
negated conditional → KILLED

2.2
Location : extractPathDetails
Killed by : com.renomad.minum.web.RequestLineTests
changed conditional boundary → KILLED

190

1.1
Location : extractPathDetails
Killed by : com.renomad.minum.web.RequestLineTests
Replaced integer addition with subtraction → KILLED

198

1.1
Location : extractPathDetails
Killed by : com.renomad.minum.web.RequestLineTests
replaced return value with null for com/renomad/minum/web/RequestLine::extractPathDetails → KILLED

211

1.1
Location : extractMapFromQueryString
Killed by : none
Changed increment from 1 to -1 → TIMED_OUT

2.2
Location : extractMapFromQueryString
Killed by : com.renomad.minum.web.RequestLineTests
negated conditional → KILLED

212

1.1
Location : extractMapFromQueryString
Killed by : none
changed conditional boundary → TIMED_OUT

2.2
Location : extractMapFromQueryString
Killed by : com.renomad.minum.web.RequestLineTests
negated conditional → KILLED

217

1.1
Location : extractMapFromQueryString
Killed by : com.renomad.minum.web.RequestLineTests
negated conditional → KILLED

221

1.1
Location : extractMapFromQueryString
Killed by : com.renomad.minum.web.RequestLineTests
Replaced integer addition with subtraction → KILLED

226

1.1
Location : extractMapFromQueryString
Killed by : com.renomad.minum.web.RequestLineTests
negated conditional → KILLED

233

1.1
Location : extractMapFromQueryString
Killed by : com.renomad.minum.web.RequestLineTests
replaced return value with Collections.emptyMap for com/renomad/minum/web/RequestLine::extractMapFromQueryString → KILLED

240

1.1
Location : getHttpVersion
Killed by : com.renomad.minum.web.RequestLineTests
negated conditional → KILLED

241

1.1
Location : getHttpVersion
Killed by : com.renomad.minum.web.RequestLineTests
replaced return value with null for com/renomad/minum/web/RequestLine::getHttpVersion → KILLED

242

1.1
Location : getHttpVersion
Killed by : com.renomad.minum.web.WebTests
negated conditional → KILLED

243

1.1
Location : getHttpVersion
Killed by : com.renomad.minum.web.WebTests
replaced return value with null for com/renomad/minum/web/RequestLine::getHttpVersion → KILLED

245

1.1
Location : getHttpVersion
Killed by : none
replaced return value with null for com/renomad/minum/web/RequestLine::getHttpVersion → TIMED_OUT

253

1.1
Location : getMethod
Killed by : com.renomad.minum.web.WebPerformanceTests.webPerfTest(com.renomad.minum.web.WebPerformanceTests)
replaced return value with null for com/renomad/minum/web/RequestLine::getMethod → KILLED

262

1.1
Location : getPathDetails
Killed by : com.renomad.minum.web.RequestLineTests
replaced return value with null for com/renomad/minum/web/RequestLine::getPathDetails → KILLED

269

1.1
Location : getVersion
Killed by : none
replaced return value with null for com/renomad/minum/web/RequestLine::getVersion → TIMED_OUT

276

1.1
Location : getRawValue
Killed by : com.renomad.minum.web.RequestLineTests
replaced return value with "" for com/renomad/minum/web/RequestLine::getRawValue → KILLED

281

1.1
Location : equals
Killed by : com.renomad.minum.web.RequestTests
negated conditional → KILLED

2.2
Location : equals
Killed by : com.renomad.minum.web.RequestTests
replaced boolean return with false for com/renomad/minum/web/RequestLine::equals → KILLED

282

1.1
Location : equals
Killed by : none
negated conditional → TIMED_OUT

2.2
Location : equals
Killed by : none
negated conditional → TIMED_OUT

3.3
Location : equals
Killed by : none
replaced boolean return with true for com/renomad/minum/web/RequestLine::equals → TIMED_OUT

284

1.1
Location : equals
Killed by : none
negated conditional → TIMED_OUT

2.2
Location : equals
Killed by : none
negated conditional → TIMED_OUT

3.3
Location : equals
Killed by : com.renomad.minum.web.RequestTests
replaced boolean return with true for com/renomad/minum/web/RequestLine::equals → KILLED

4.4
Location : equals
Killed by : none
negated conditional → TIMED_OUT

5.5
Location : equals
Killed by : none
negated conditional → TIMED_OUT

6.6
Location : equals
Killed by : none
negated conditional → TIMED_OUT

289

1.1
Location : hashCode
Killed by : com.renomad.minum.web.RequestTests
replaced int return with 0 for com/renomad/minum/web/RequestLine::hashCode → KILLED

294

1.1
Location : toString
Killed by : none
replaced return value with "" for com/renomad/minum/web/RequestLine::toString → TIMED_OUT

Active mutators

Tests examined


Report generated by PIT 1.17.0