Request.java

1
package com.renomad.minum.web;
2
3
import java.util.Objects;
4
5
public final class Request implements IRequest {
6
7
    private final Headers headers;
8
    private final RequestLine requestLine;
9
    private Body body;
10
    private final String remoteRequester;
11
    private final ISocketWrapper socketWrapper;
12
    private final IBodyProcessor bodyProcessor;
13
    private boolean hasStartedReadingBody;
14
15
    /**
16
     * Constructor for a HTTP request
17
     * @param  remoteRequester This is the remote address making the request
18
     */
19
    public Request(Headers headers,
20
            RequestLine requestLine,
21
            String remoteRequester,
22
            ISocketWrapper socketWrapper,
23
            IBodyProcessor bodyProcessor
24
    ) {
25
        this.headers = headers;
26
        this.requestLine = requestLine;
27
        this.remoteRequester = remoteRequester;
28
        this.socketWrapper = socketWrapper;
29
        this.bodyProcessor = bodyProcessor;
30
        this.hasStartedReadingBody = false;
31
    }
32
33
    @Override
34
    public Headers getHeaders() {
35 1 1. getHeaders : replaced return value with null for com/renomad/minum/web/Request::getHeaders → KILLED
        return headers;
36
    }
37
38
    @Override
39
    public RequestLine getRequestLine() {
40 1 1. getRequestLine : replaced return value with null for com/renomad/minum/web/Request::getRequestLine → KILLED
        return requestLine;
41
    }
42
43
    @Override
44
    public Body getBody() {
45 1 1. getBody : negated conditional → KILLED
        if (hasStartedReadingBody) {
46
            throw new WebServerException("The InputStream in Request has already been accessed for reading, preventing body extraction from stream." +
47
                    " If intending to use getBody(), use it exclusively");
48
        }
49 1 1. getBody : negated conditional → KILLED
        if (body == null) {
50
            body = bodyProcessor.extractData(socketWrapper.getInputStream(), headers);
51
        }
52 1 1. getBody : replaced return value with null for com/renomad/minum/web/Request::getBody → KILLED
        return body;
53
    }
54
55
    @Override
56
    public String getRemoteRequester() {
57 1 1. getRemoteRequester : replaced return value with "" for com/renomad/minum/web/Request::getRemoteRequester → KILLED
        return remoteRequester;
58
    }
59
60
    @Override
61
    public ISocketWrapper getSocketWrapper() {
62 1 1. getSocketWrapper : removed call to com/renomad/minum/web/Request::checkForExistingBody → KILLED
        checkForExistingBody();
63
        hasStartedReadingBody = true;
64 1 1. getSocketWrapper : replaced return value with null for com/renomad/minum/web/Request::getSocketWrapper → KILLED
        return socketWrapper;
65
    }
66
67
    @Override
68
    public boolean equals(Object o) {
69 2 1. equals : replaced boolean return with false for com/renomad/minum/web/Request::equals → TIMED_OUT
2. equals : negated conditional → KILLED
        if (this == o) return true;
70 3 1. equals : negated conditional → TIMED_OUT
2. equals : replaced boolean return with true for com/renomad/minum/web/Request::equals → TIMED_OUT
3. equals : negated conditional → TIMED_OUT
        if (o == null || getClass() != o.getClass()) return false;
71
        Request request = (Request) o;
72 8 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 : negated conditional → TIMED_OUT
7. equals : negated conditional → TIMED_OUT
8. equals : replaced boolean return with true for com/renomad/minum/web/Request::equals → KILLED
        return hasStartedReadingBody == request.hasStartedReadingBody && Objects.equals(headers, request.headers) && Objects.equals(requestLine, request.requestLine) && Objects.equals(body, request.body) && Objects.equals(remoteRequester, request.remoteRequester) && Objects.equals(socketWrapper, request.socketWrapper) && Objects.equals(bodyProcessor, request.bodyProcessor);
73
    }
74
75
    @Override
76
    public int hashCode() {
77 1 1. hashCode : replaced int return with 0 for com/renomad/minum/web/Request::hashCode → TIMED_OUT
        return Objects.hash(headers, requestLine, body, remoteRequester, socketWrapper, bodyProcessor, hasStartedReadingBody);
78
    }
79
80
    @Override
81
    public String toString() {
82 1 1. toString : replaced return value with "" for com/renomad/minum/web/Request::toString → KILLED
        return "Request{" +
83
                "headers=" + headers +
84
                ", requestLine=" + requestLine +
85
                ", body=" + body +
86
                ", remoteRequester='" + remoteRequester + '\'' +
87
                ", socketWrapper=" + socketWrapper +
88
                ", hasStartedReadingBody=" + hasStartedReadingBody +
89
                '}';
90
    }
91
92
    @Override
93
    public Iterable<UrlEncodedKeyValue> getUrlEncodedIterable() {
94 1 1. getUrlEncodedIterable : removed call to com/renomad/minum/web/Request::checkForExistingBody → KILLED
        checkForExistingBody();
95 1 1. getUrlEncodedIterable : negated conditional → KILLED
        if (!headers.contentType().contains("application/x-www-form-urlencoded")) {
96
            throw new WebServerException("This request was not sent with a content type of application/x-www-form-urlencoded.  The content type was: " + headers.contentType());
97
        }
98 1 1. getUrlEncodedIterable : replaced return value with Collections.emptyList for com/renomad/minum/web/Request::getUrlEncodedIterable → KILLED
        return bodyProcessor.getUrlEncodedDataIterable(getSocketWrapper().getInputStream(), getHeaders().contentLength());
99
    }
100
101
    /**
102
     * This method is for verifying that the body is null, and throwing an exception
103
     * if not.  Several of the methods in this class depend on the InputStream not
104
     * having been read already - if the body was read, then the InputStream is finished,
105
     * and any further reading would be incorrect.
106
     */
107
    private void checkForExistingBody() {
108 1 1. checkForExistingBody : negated conditional → KILLED
        if (body != null) {
109
            throw new WebServerException("Requesting this after getting the body with getBody() will result in incorrect behavior.  " +
110
                    "If you intend to work with the Request at this level, do not use getBody");
111
        }
112 1 1. checkForExistingBody : negated conditional → KILLED
        if (hasStartedReadingBody) {
113
            throw new WebServerException("The InputStream has begun processing elsewhere.  Results are invalid.");
114
        }
115
    }
116
117
    @Override
118
    public Iterable<StreamingMultipartPartition> getMultipartIterable() {
119 1 1. getMultipartIterable : removed call to com/renomad/minum/web/Request::checkForExistingBody → KILLED
        checkForExistingBody();
120 1 1. getMultipartIterable : negated conditional → KILLED
        if (!headers.contentType().contains("multipart/form-data")) {
121
            throw new WebServerException("This request was not sent with a content type of multipart/form-data.  The content type was: " + headers.contentType());
122
        }
123
        String boundaryKey = "boundary=";
124
        String contentType = getHeaders().contentType();
125
        int indexOfBoundaryKey = contentType.indexOf(boundaryKey);
126
        String boundaryValue = "";
127 2 1. getMultipartIterable : changed conditional boundary → SURVIVED
2. getMultipartIterable : negated conditional → KILLED
        if (indexOfBoundaryKey > 0) {
128
            // grab all the text after the key to obtain the boundary value
129 1 1. getMultipartIterable : Replaced integer addition with subtraction → KILLED
            boundaryValue = contentType.substring(indexOfBoundaryKey + boundaryKey.length());
130
        } else {
131
            String parsingError = "Did not find a valid boundary value for the multipart input. Returning an empty map and the raw bytes for the body. Header was: " + contentType;
132
            throw new WebServerException(parsingError);
133
        }
134
135 1 1. getMultipartIterable : negated conditional → KILLED
        if (boundaryValue.isBlank()) {
136
            String parsingError = "Boundary value was blank. Returning an empty map and the raw bytes for the body. Header was: " + contentType;
137
            throw new WebServerException(parsingError);
138
        }
139
140 1 1. getMultipartIterable : replaced return value with Collections.emptyList for com/renomad/minum/web/Request::getMultipartIterable → KILLED
        return bodyProcessor.getMultiPartIterable(getSocketWrapper().getInputStream(), boundaryValue, getHeaders().contentLength());
141
    }
142
}

Mutations

35

1.1
Location : getHeaders
Killed by : com.renomad.minum.web.RequestTests.testRequest_ExpectComplaintAfterBegunReading_10(com.renomad.minum.web.RequestTests)
replaced return value with null for com/renomad/minum/web/Request::getHeaders → KILLED

40

1.1
Location : getRequestLine
Killed by : com.renomad.minum.web.RequestTests.testSimplerRequest(com.renomad.minum.web.RequestTests)
replaced return value with null for com/renomad/minum/web/Request::getRequestLine → KILLED

45

1.1
Location : getBody
Killed by : com.renomad.minum.web.RequestTests.testRequest_ExpectComplaintAfterBegunReading_2(com.renomad.minum.web.RequestTests)
negated conditional → KILLED

49

1.1
Location : getBody
Killed by : com.renomad.minum.web.RequestTests.test_Request_getMultipartForm_EdgeCase_ComplaintAfterGetBody(com.renomad.minum.web.RequestTests)
negated conditional → KILLED

52

1.1
Location : getBody
Killed by : com.renomad.minum.web.RequestTests.testSimplerRequest(com.renomad.minum.web.RequestTests)
replaced return value with null for com/renomad/minum/web/Request::getBody → KILLED

57

1.1
Location : getRemoteRequester
Killed by : com.renomad.minum.web.RequestTests.testSimplerRequest(com.renomad.minum.web.RequestTests)
replaced return value with "" for com/renomad/minum/web/Request::getRemoteRequester → KILLED

62

1.1
Location : getSocketWrapper
Killed by : com.renomad.minum.web.RequestTests.testRequest_ExpectComplaintAfterBegunReading_13(com.renomad.minum.web.RequestTests)
removed call to com/renomad/minum/web/Request::checkForExistingBody → KILLED

64

1.1
Location : getSocketWrapper
Killed by : com.renomad.minum.web.RequestTests.testRequest_ExpectComplaintAfterBegunReading_10(com.renomad.minum.web.RequestTests)
replaced return value with null for com/renomad/minum/web/Request::getSocketWrapper → KILLED

69

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

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

70

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

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

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

72

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

2.2
Location : equals
Killed by : com.renomad.minum.web.RequestTests.equalsTest(com.renomad.minum.web.RequestTests)
replaced boolean return with true for com/renomad/minum/web/Request::equals → KILLED

3.3
Location : equals
Killed by : none
negated conditional → 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

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

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

77

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

82

1.1
Location : toString
Killed by : com.renomad.minum.web.RequestTests.test_Request_ToString(com.renomad.minum.web.RequestTests)
replaced return value with "" for com/renomad/minum/web/Request::toString → KILLED

94

1.1
Location : getUrlEncodedIterable
Killed by : com.renomad.minum.web.RequestTests.testRequest_ExpectComplaintAfterBegunReading_7(com.renomad.minum.web.RequestTests)
removed call to com/renomad/minum/web/Request::checkForExistingBody → KILLED

95

1.1
Location : getUrlEncodedIterable
Killed by : com.renomad.minum.web.RequestTests.testRequest_ExpectComplaintAfterBegunReading_10(com.renomad.minum.web.RequestTests)
negated conditional → KILLED

98

1.1
Location : getUrlEncodedIterable
Killed by : com.renomad.minum.web.RequestTests.testSimplerRequest2(com.renomad.minum.web.RequestTests)
replaced return value with Collections.emptyList for com/renomad/minum/web/Request::getUrlEncodedIterable → KILLED

108

1.1
Location : checkForExistingBody
Killed by : com.renomad.minum.web.RequestTests.testRequest_ExpectComplaintAfterBegunReading_10(com.renomad.minum.web.RequestTests)
negated conditional → KILLED

112

1.1
Location : checkForExistingBody
Killed by : com.renomad.minum.web.RequestTests.testRequest_ExpectComplaintAfterBegunReading_10(com.renomad.minum.web.RequestTests)
negated conditional → KILLED

119

1.1
Location : getMultipartIterable
Killed by : com.renomad.minum.web.RequestTests.testRequest_ExpectComplaintAfterBegunReading_6(com.renomad.minum.web.RequestTests)
removed call to com/renomad/minum/web/Request::checkForExistingBody → KILLED

120

1.1
Location : getMultipartIterable
Killed by : com.renomad.minum.web.RequestTests.testEndOfStreamWhileReadingStreamingMultipartPartition(com.renomad.minum.web.RequestTests)
negated conditional → KILLED

127

1.1
Location : getMultipartIterable
Killed by : none
changed conditional boundary → SURVIVED
Covering tests

2.2
Location : getMultipartIterable
Killed by : com.renomad.minum.web.RequestTests.testEndOfStreamWhileReadingStreamingMultipartPartition(com.renomad.minum.web.RequestTests)
negated conditional → KILLED

129

1.1
Location : getMultipartIterable
Killed by : com.renomad.minum.web.RequestTests.test_Request_getMultipartIterable_EdgeCase_No_Valid_Boundary_2(com.renomad.minum.web.RequestTests)
Replaced integer addition with subtraction → KILLED

135

1.1
Location : getMultipartIterable
Killed by : com.renomad.minum.web.RequestTests.testEndOfStreamWhileReadingStreamingMultipartPartition(com.renomad.minum.web.RequestTests)
negated conditional → KILLED

140

1.1
Location : getMultipartIterable
Killed by : com.renomad.minum.web.RequestTests.testEndOfStreamWhileReadingStreamingMultipartPartition(com.renomad.minum.web.RequestTests)
replaced return value with Collections.emptyList for com/renomad/minum/web/Request::getMultipartIterable → KILLED

Active mutators

Tests examined


Report generated by PIT 1.17.0