• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hazendaz / httpunit / 656

06 Dec 2025 09:11PM UTC coverage: 80.452% (+0.02%) from 80.435%
656

push

github

hazendaz
[maven-release-plugin] prepare for next development iteration

3213 of 4105 branches covered (78.27%)

Branch coverage included in aggregate %.

8245 of 10137 relevant lines covered (81.34%)

0.81 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.45
/src/main/java/com/meterware/servletunit/RequestContext.java
1
/*
2
 * MIT License
3
 *
4
 * Copyright 2011-2025 Russell Gold
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
7
 * documentation files (the "Software"), to deal in the Software without restriction, including without limitation
8
 * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
9
 * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions
12
 * of the Software.
13
 *
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
15
 * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
17
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
18
 * DEALINGS IN THE SOFTWARE.
19
 */
20
package com.meterware.servletunit;
21

22
import com.meterware.httpunit.HttpUnitOptions;
23
import com.meterware.httpunit.HttpUnitUtils;
24

25
import java.net.URL;
26
import java.nio.charset.StandardCharsets;
27
import java.util.Enumeration;
28
import java.util.Hashtable;
29
import java.util.Map;
30
import java.util.StringTokenizer;
31

32
import javax.servlet.http.HttpServletRequest;
33

34
/**
35
 * The Class RequestContext.
36
 */
37
class RequestContext {
38

39
    /** The parameters. */
40
    private Hashtable _parameters = new Hashtable<>();
1✔
41

42
    /** The visible parameters. */
43
    private Hashtable _visibleParameters;
44

45
    /** The parent request. */
46
    private HttpServletRequest _parentRequest;
47

48
    /** The url. */
49
    private URL _url;
50

51
    /** The message body. */
52
    private byte[] _messageBody;
53

54
    /** The message encoding. */
55
    private String _messageEncoding;
56

57
    /**
58
     * Instantiates a new request context.
59
     *
60
     * @param url
61
     *            the url
62
     */
63
    RequestContext(URL url) {
1✔
64
        _url = url;
1✔
65
        String file = _url.getFile();
1✔
66
        if (file.indexOf('?') >= 0) {
1✔
67
            loadParameters(file.substring(file.indexOf('?') + 1) /* urlEncoded */ );
1✔
68
        }
69
    }
1✔
70

71
    /**
72
     * Sets the parent request.
73
     *
74
     * @param parentRequest
75
     *            the new parent request
76
     */
77
    void setParentRequest(HttpServletRequest parentRequest) {
78
        _parentRequest = parentRequest;
1✔
79
        _visibleParameters = null;
1✔
80
    }
1✔
81

82
    /**
83
     * Gets the request URI.
84
     *
85
     * @return the request URI
86
     */
87
    String getRequestURI() {
88
        return _url.getPath();
1✔
89
    }
90

91
    /**
92
     * Gets the parameter.
93
     *
94
     * @param name
95
     *            the name
96
     *
97
     * @return the parameter
98
     */
99
    String getParameter(String name) {
100
        String[] parameters = (String[]) getParameters().get(name);
1✔
101
        return parameters == null ? null : parameters[0];
1!
102
    }
103

104
    /**
105
     * Gets the parameter names.
106
     *
107
     * @return the parameter names
108
     */
109
    Enumeration getParameterNames() {
110
        return getParameters().keys();
1✔
111
    }
112

113
    /**
114
     * Gets the parameter map.
115
     *
116
     * @return the parameter map
117
     */
118
    Map getParameterMap() {
119
        return (Map) getParameters().clone();
1✔
120
    }
121

122
    /**
123
     * Gets the parameter values.
124
     *
125
     * @param name
126
     *            the name
127
     *
128
     * @return the parameter values
129
     */
130
    String[] getParameterValues(String name) {
131
        return (String[]) getParameters().get(name);
1✔
132
    }
133

134
    /** The Constant STATE_INITIAL. */
135
    static final private int STATE_INITIAL = 0;
136

137
    /** The Constant STATE_HAVE_NAME. */
138
    static final private int STATE_HAVE_NAME = 1;
139

140
    /** The Constant STATE_HAVE_EQUALS. */
141
    static final private int STATE_HAVE_EQUALS = 2;
142

143
    /** The Constant STATE_HAVE_VALUE. */
144
    static final private int STATE_HAVE_VALUE = 3;
145

146
    /**
147
     * This method employs a state machine to parse a parameter query string. The transition rules are as follows: State
148
     * \ text '=' '&' initial: have_name - initial have_name: - have_equals initial have_equals: have_value - initial
149
     * have_value: - initial initial actions occur on the following transitions: initial -> have_name: save token as
150
     * name have_equals -> initial: record parameter with null value have_value -> initial: record parameter with value
151
     *
152
     * @param queryString
153
     *            the query string
154
     */
155
    void loadParameters(String queryString) {
156
        if (queryString.isEmpty()) {
1✔
157
            return;
1✔
158
        }
159
        StringTokenizer st = new StringTokenizer(queryString, "&=", /* return tokens */ true);
1✔
160
        int state = STATE_INITIAL;
1✔
161
        String name = null;
1✔
162
        String value = null;
1✔
163

164
        while (st.hasMoreTokens()) {
1✔
165
            String token = st.nextToken();
1✔
166
            if (token.equals("&")) {
1✔
167
                state = STATE_INITIAL;
1✔
168
                if (name != null && value != null) {
1!
169
                    addParameter(name, value);
1✔
170
                }
171
                name = value = null;
1✔
172
            } else if (token.equals("=")) {
1✔
173
                if (state == STATE_HAVE_NAME) {
1!
174
                    state = STATE_HAVE_EQUALS;
1✔
175
                } else if (state == STATE_HAVE_VALUE) {
×
176
                    state = STATE_INITIAL;
×
177
                }
178
            } else if (state == STATE_INITIAL) {
1✔
179
                name = HttpUnitUtils.decode(token, getMessageEncoding());
1✔
180
                value = "";
1✔
181
                state = STATE_HAVE_NAME;
1✔
182
            } else {
183
                value = HttpUnitUtils.decode(token, getMessageEncoding());
1✔
184
                state = STATE_HAVE_VALUE;
1✔
185
            }
186
        }
1✔
187
        if (name != null && value != null) {
1!
188
            addParameter(name, value);
1✔
189
        }
190
    }
1✔
191

192
    /**
193
     * Adds the parameter.
194
     *
195
     * @param name
196
     *            the name
197
     * @param encodedValue
198
     *            the encoded value
199
     */
200
    private void addParameter(String name, String encodedValue) {
201
        String[] values = (String[]) _parameters.get(name);
1✔
202
        _visibleParameters = null;
1✔
203
        if (values == null) {
1✔
204
            _parameters.put(name, new String[] { encodedValue });
1✔
205
        } else {
206
            _parameters.put(name, extendedArray(values, encodedValue));
1✔
207
        }
208
    }
1✔
209

210
    /**
211
     * Extended array.
212
     *
213
     * @param baseArray
214
     *            the base array
215
     * @param newValue
216
     *            the new value
217
     *
218
     * @return the string[]
219
     */
220
    private static String[] extendedArray(String[] baseArray, String newValue) {
221
        String[] result = new String[baseArray.length + 1];
1✔
222
        System.arraycopy(baseArray, 0, result, 0, baseArray.length);
1✔
223
        result[baseArray.length] = newValue;
1✔
224
        return result;
1✔
225
    }
226

227
    /**
228
     * Gets the parameters.
229
     *
230
     * @return the parameters
231
     */
232
    private Hashtable getParameters() {
233
        if (_messageBody != null) {
1✔
234
            loadParameters(getMessageBodyAsString());
1✔
235
            _messageBody = null;
1✔
236
        }
237
        if (_visibleParameters == null) {
1✔
238
            if (_parentRequest == null) {
1✔
239
                _visibleParameters = _parameters;
1✔
240
            } else {
241
                _visibleParameters = new Hashtable<>();
1✔
242
                final Map parameterMap = _parentRequest.getParameterMap();
1✔
243
                for (Object key : parameterMap.keySet()) {
1✔
244
                    _visibleParameters.put(key, parameterMap.get(key));
1✔
245
                }
1✔
246
                for (Enumeration e = _parameters.keys(); e.hasMoreElements();) {
1✔
247
                    Object key = e.nextElement();
1✔
248
                    _visibleParameters.put(key, _parameters.get(key));
1✔
249
                }
1✔
250
            }
251
        }
252
        return _visibleParameters;
1✔
253
    }
254

255
    /**
256
     * Gets the message body as string.
257
     *
258
     * @return the message body as string
259
     */
260
    private String getMessageBodyAsString() {
261
        return new String(_messageBody, StandardCharsets.UTF_8);
1✔
262
    }
263

264
    /**
265
     * Sets the message body.
266
     *
267
     * @param bytes
268
     *            the new message body
269
     */
270
    void setMessageBody(byte[] bytes) {
271
        _messageBody = bytes;
1✔
272
    }
1✔
273

274
    /**
275
     * Sets the message encoding.
276
     *
277
     * @param messageEncoding
278
     *            the new message encoding
279
     */
280
    public void setMessageEncoding(String messageEncoding) {
281
        _messageEncoding = messageEncoding;
1✔
282
    }
1✔
283

284
    /**
285
     * Gets the message encoding.
286
     *
287
     * @return the message encoding
288
     */
289
    private String getMessageEncoding() {
290
        return _messageEncoding == null ?
1✔
291
        /* Fixing 1705925: StandardCharsets.ISO_8859_1.name() */
292
                HttpUnitOptions.getDefaultCharacterSet() : _messageEncoding;
1✔
293
    }
294

295
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc