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

hazendaz / httpunit / 636

05 Dec 2025 03:27AM UTC coverage: 80.509%. Remained the same
636

push

github

hazendaz
Cleanup more old since tags

you guessed it, at this point going to jautodoc the rest so the warnings on builds go away ;)

3213 of 4105 branches covered (78.27%)

Branch coverage included in aggregate %.

8249 of 10132 relevant lines covered (81.42%)

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 jakarta.servlet.http.HttpServletRequest;
26

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

34
class RequestContext {
35

36
    private Hashtable _parameters = new Hashtable<>();
1✔
37
    private Hashtable _visibleParameters;
38
    private HttpServletRequest _parentRequest;
39
    private URL _url;
40
    private byte[] _messageBody;
41
    private String _messageEncoding;
42

43
    RequestContext(URL url) {
1✔
44
        _url = url;
1✔
45
        String file = _url.getFile();
1✔
46
        if (file.indexOf('?') >= 0) {
1✔
47
            loadParameters(file.substring(file.indexOf('?') + 1) /* urlEncoded */ );
1✔
48
        }
49
    }
1✔
50

51
    void setParentRequest(HttpServletRequest parentRequest) {
52
        _parentRequest = parentRequest;
1✔
53
        _visibleParameters = null;
1✔
54
    }
1✔
55

56
    String getRequestURI() {
57
        return _url.getPath();
1✔
58
    }
59

60
    String getParameter(String name) {
61
        String[] parameters = (String[]) getParameters().get(name);
1✔
62
        return parameters == null ? null : parameters[0];
1!
63
    }
64

65
    Enumeration getParameterNames() {
66
        return getParameters().keys();
1✔
67
    }
68

69
    Map getParameterMap() {
70
        return (Map) getParameters().clone();
1✔
71
    }
72

73
    String[] getParameterValues(String name) {
74
        return (String[]) getParameters().get(name);
1✔
75
    }
76

77
    static final private int STATE_INITIAL = 0;
78
    static final private int STATE_HAVE_NAME = 1;
79
    static final private int STATE_HAVE_EQUALS = 2;
80
    static final private int STATE_HAVE_VALUE = 3;
81

82
    /**
83
     * This method employs a state machine to parse a parameter query string. The transition rules are as follows: State
84
     * \ text '=' '&' initial: have_name - initial have_name: - have_equals initial have_equals: have_value - initial
85
     * have_value: - initial initial actions occur on the following transitions: initial -> have_name: save token as
86
     * name have_equals -> initial: record parameter with null value have_value -> initial: record parameter with value
87
     **/
88
    void loadParameters(String queryString) {
89
        if (queryString.isEmpty()) {
1✔
90
            return;
1✔
91
        }
92
        StringTokenizer st = new StringTokenizer(queryString, "&=", /* return tokens */ true);
1✔
93
        int state = STATE_INITIAL;
1✔
94
        String name = null;
1✔
95
        String value = null;
1✔
96

97
        while (st.hasMoreTokens()) {
1✔
98
            String token = st.nextToken();
1✔
99
            if (token.equals("&")) {
1✔
100
                state = STATE_INITIAL;
1✔
101
                if (name != null && value != null) {
1!
102
                    addParameter(name, value);
1✔
103
                }
104
                name = value = null;
1✔
105
            } else if (token.equals("=")) {
1✔
106
                if (state == STATE_HAVE_NAME) {
1!
107
                    state = STATE_HAVE_EQUALS;
1✔
108
                } else if (state == STATE_HAVE_VALUE) {
×
109
                    state = STATE_INITIAL;
×
110
                }
111
            } else if (state == STATE_INITIAL) {
1✔
112
                name = HttpUnitUtils.decode(token, getMessageEncoding());
1✔
113
                value = "";
1✔
114
                state = STATE_HAVE_NAME;
1✔
115
            } else {
116
                value = HttpUnitUtils.decode(token, getMessageEncoding());
1✔
117
                state = STATE_HAVE_VALUE;
1✔
118
            }
119
        }
1✔
120
        if (name != null && value != null) {
1!
121
            addParameter(name, value);
1✔
122
        }
123
    }
1✔
124

125
    private void addParameter(String name, String encodedValue) {
126
        String[] values = (String[]) _parameters.get(name);
1✔
127
        _visibleParameters = null;
1✔
128
        if (values == null) {
1✔
129
            _parameters.put(name, new String[] { encodedValue });
1✔
130
        } else {
131
            _parameters.put(name, extendedArray(values, encodedValue));
1✔
132
        }
133
    }
1✔
134

135
    private static String[] extendedArray(String[] baseArray, String newValue) {
136
        String[] result = new String[baseArray.length + 1];
1✔
137
        System.arraycopy(baseArray, 0, result, 0, baseArray.length);
1✔
138
        result[baseArray.length] = newValue;
1✔
139
        return result;
1✔
140
    }
141

142
    private Hashtable getParameters() {
143
        if (_messageBody != null) {
1✔
144
            loadParameters(getMessageBodyAsString());
1✔
145
            _messageBody = null;
1✔
146
        }
147
        if (_visibleParameters == null) {
1✔
148
            if (_parentRequest == null) {
1✔
149
                _visibleParameters = _parameters;
1✔
150
            } else {
151
                _visibleParameters = new Hashtable<>();
1✔
152
                final Map parameterMap = _parentRequest.getParameterMap();
1✔
153
                for (Object key : parameterMap.keySet()) {
1✔
154
                    _visibleParameters.put(key, parameterMap.get(key));
1✔
155
                }
1✔
156
                for (Enumeration e = _parameters.keys(); e.hasMoreElements();) {
1✔
157
                    Object key = e.nextElement();
1✔
158
                    _visibleParameters.put(key, _parameters.get(key));
1✔
159
                }
1✔
160
            }
161
        }
162
        return _visibleParameters;
1✔
163
    }
164

165
    private String getMessageBodyAsString() {
166
        return new String(_messageBody, StandardCharsets.UTF_8);
1✔
167
    }
168

169
    void setMessageBody(byte[] bytes) {
170
        _messageBody = bytes;
1✔
171
    }
1✔
172

173
    public void setMessageEncoding(String messageEncoding) {
174
        _messageEncoding = messageEncoding;
1✔
175
    }
1✔
176

177
    private String getMessageEncoding() {
178
        return _messageEncoding == null ?
1✔
179
        /* Fixing 1705925: StandardCharsets.ISO_8859_1.name() */
180
                HttpUnitOptions.getDefaultCharacterSet() : _messageEncoding;
1✔
181
    }
182

183
}
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