Request.java

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

Mutations

39

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

44

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

49

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

53

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

56

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

61

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

66

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

68

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

73

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

74

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

76

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

81

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

86

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

98

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

99

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

102

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

112

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

116

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

123

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

124

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

131

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

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

133

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

139

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

144

1.1
Location : getMultipartIterable
Killed by : com.renomad.minum.web.RequestTests.testSimplerRequest3(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