RequestLine.java

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

Mutations

55

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

58

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

87

1.1
Location : getMethod
Killed by : com.renomad.minum.web.WebPerformanceTests.test3(com.renomad.minum.web.WebPerformanceTests)
changed conditional boundary → KILLED

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

88

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

93

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

95

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.web.WebPerformanceTests.test3(com.renomad.minum.web.WebPerformanceTests)
changed conditional boundary → KILLED

97

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

98

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

100

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

103

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

123

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

127

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

132

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

137

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
replaced return value with null for com/renomad/minum/web/RequestLine::extractRequestLine → KILLED

157

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

160

1.1
Location : requestLineTokenizer
Killed by : com.renomad.minum.web.RequestLineTests
Replaced integer addition with subtraction → 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

169

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

170

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

171

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

180

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

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

182

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

190

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

203

1.1
Location : extractMapFromQueryString
Killed by : com.renomad.minum.web.WebPerformanceTests.test3(com.renomad.minum.web.WebPerformanceTests)
Changed increment from 1 to -1 → KILLED

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

204

1.1
Location : extractMapFromQueryString
Killed by : com.renomad.minum.web.WebPerformanceTests.test3(com.renomad.minum.web.WebPerformanceTests)
changed conditional boundary → KILLED

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

209

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

213

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

218

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

225

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

232

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

233

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

234

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

235

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

237

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 : getMethod
Killed by : none
replaced return value with null for com/renomad/minum/web/RequestLine::getMethod → TIMED_OUT

254

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

261

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

268

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

273

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

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

274

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

276

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

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

281

1.1
Location : hashCode
Killed by : none
replaced int return with 0 for com/renomad/minum/web/RequestLine::hashCode → TIMED_OUT

286

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