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

hazendaz / httpunit / 646

06 Dec 2025 08:11PM UTC coverage: 80.526% (+0.02%) from 80.509%
646

push

github

hazendaz
Cleanup array usage

3213 of 4105 branches covered (78.27%)

Branch coverage included in aggregate %.

4 of 4 new or added lines in 3 files covered. (100.0%)

532 existing lines in 26 files now uncovered.

8245 of 10124 relevant lines covered (81.44%)

0.81 hits per line

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

82.64
/src/main/java/com/meterware/servletunit/ServletUnitHttpRequest.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.HttpUnitUtils;
23
import com.meterware.httpunit.WebClient;
24
import com.meterware.httpunit.WebRequest;
25

26
import jakarta.servlet.AsyncContext;
27
import jakarta.servlet.DispatcherType;
28
import jakarta.servlet.RequestDispatcher;
29
import jakarta.servlet.ServletConnection;
30
import jakarta.servlet.ServletContext;
31
import jakarta.servlet.ServletException;
32
import jakarta.servlet.ServletInputStream;
33
import jakarta.servlet.ServletRequest;
34
import jakarta.servlet.ServletResponse;
35
import jakarta.servlet.http.Cookie;
36
import jakarta.servlet.http.HttpServletRequest;
37
import jakarta.servlet.http.HttpServletResponse;
38
import jakarta.servlet.http.HttpSession;
39
import jakarta.servlet.http.HttpUpgradeHandler;
40
import jakarta.servlet.http.Part;
41

42
import java.io.BufferedReader;
43
import java.io.IOException;
44
import java.io.InputStreamReader;
45
import java.net.MalformedURLException;
46
import java.nio.charset.Charset;
47
import java.nio.charset.StandardCharsets;
48
import java.util.ArrayList;
49
import java.util.Base64;
50
import java.util.Collection;
51
import java.util.Collections;
52
import java.util.Date;
53
import java.util.Dictionary;
54
import java.util.Enumeration;
55
import java.util.Hashtable;
56
import java.util.Iterator;
57
import java.util.List;
58
import java.util.Locale;
59
import java.util.Map;
60
import java.util.StringTokenizer;
61

62
/**
63
 * The Class ServletUnitHttpRequest.
64
 */
65
class ServletUnitHttpRequest implements HttpServletRequest {
66

67
    /** The input stream. */
68
    private ServletInputStreamImpl _inputStream;
69

70
    /** The locales. */
71
    private List _locales;
72

73
    /** The protocol. */
74
    private String _protocol;
75

76
    /** The secure. */
77
    private boolean _secure;
78

79
    /** The request context. */
80
    private RequestContext _requestContext;
81

82
    /** The charset. */
83
    private String _charset;
84

85
    /** The got reader. */
86
    private boolean _gotReader;
87

88
    /** The got input stream. */
89
    private boolean _gotInputStream;
90

91
    /** The reader. */
92
    private BufferedReader _reader;
93

94
    /** The server port. */
95
    private int _serverPort;
96

97
    /** The server name. */
98
    private String _serverName;
99

100
    /**
101
     * Constructs a ServletUnitHttpRequest from a WebRequest object.
102
     *
103
     * @param servletRequest
104
     *            the servlet request
105
     * @param request
106
     *            the request
107
     * @param context
108
     *            the context
109
     * @param clientHeaders
110
     *            the client headers
111
     * @param messageBody
112
     *            the message body
113
     *
114
     * @throws MalformedURLException
115
     *             the malformed URL exception
116
     */
117
    ServletUnitHttpRequest(ServletMetaData servletRequest, WebRequest request, ServletUnitContext context,
118
            Dictionary clientHeaders, byte[] messageBody) throws MalformedURLException {
1✔
119
        if (context == null) {
1!
UNCOV
120
            throw new IllegalArgumentException("Context must not be null");
×
121
        }
122

123
        _servletRequest = servletRequest;
1✔
124
        _request = request;
1✔
125
        _context = context;
1✔
126
        _headers = new WebClient.HeaderDictionary();
1✔
127
        _headers.addEntries(clientHeaders);
1✔
128
        _headers.addEntries(request.getHeaders());
1✔
129
        setCookiesFromHeader(_headers);
1✔
130
        _messageBody = messageBody;
1✔
131
        _protocol = request.getURL().getProtocol().toLowerCase(Locale.ENGLISH);
1✔
132
        _secure = _protocol.endsWith("s");
1✔
133
        _serverName = request.getURL().getHost();
1✔
134
        _serverPort = request.getURL().getPort();
1✔
135
        if (_serverPort == -1) {
1✔
136
            _serverPort = request.getURL().getDefaultPort();
1✔
137
        }
138

139
        _requestContext = new RequestContext(request.getURL());
1✔
140
        String contentTypeHeader = (String) _headers.get("Content-Type");
1✔
141
        if (contentTypeHeader != null) {
1✔
142
            String[] res = HttpUnitUtils.parseContentTypeHeader(contentTypeHeader);
1✔
143
            _charset = res[1];
1✔
144
            _requestContext.setMessageEncoding(_charset);
1✔
145
        }
146
        if (_headers.get("Content-Length") == null) {
1!
147
            _headers.put("Content-Length", Integer.toString(messageBody.length));
1✔
148
        }
149

150
        boolean setBody =
1!
151
                // pre [ 1509117 ] getContentType()
152
                // _messageBody != null && (_contentType == null || _contentType.indexOf( "x-www-form-urlencoded" ) >= 0
153
                // );
154
                // patch version:
155
                _messageBody != null
156
                        && (contentTypeHeader == null || contentTypeHeader.indexOf("x-www-form-urlencoded") >= 0);
1✔
157
        if (setBody) {
1✔
158
            _requestContext.setMessageBody(_messageBody);
1✔
159
        }
160
    }
1✔
161

162
    // ----------------------------------------- HttpServletRequest methods --------------------------
163

164
    /**
165
     * Returns the name of the authentication scheme used to protect the servlet, for example, "BASIC" or "SSL," or null
166
     * if the servlet was not protected.
167
     **/
168
    @Override
169
    public String getAuthType() {
170
        return null;
1✔
171
    }
172

173
    /**
174
     * Returns the query string that is contained in the request URL after the path.
175
     **/
176
    @Override
177
    public String getQueryString() {
178
        return _request.getQueryString();
1✔
179
    }
180

181
    /**
182
     * Returns an array containing all of the Cookie objects the client sent with this request. This method returns null
183
     * if no cookies were sent.
184
     **/
185
    @Override
186
    public Cookie[] getCookies() {
187
        if (_cookies.size() == 0) {
1✔
188
            return null;
1✔
189
        }
190
        return _cookies.toArray(new Cookie[0]);
1✔
191
    }
192

193
    /**
194
     * Returns the value of the specified request header as an int. If the request does not have a header of the
195
     * specified name, this method returns -1. If the header cannot be converted to an integer, this method throws a
196
     * NumberFormatException.
197
     **/
198
    @Override
199
    public int getIntHeader(String name) {
200
        return Integer.parseInt(getHeader(name));
1✔
201
    }
202

203
    /**
204
     * Returns the value of the specified request header as a long value that represents a Date object. Use this method
205
     * with headers that contain dates, such as If-Modified-Since. <br>
206
     * The date is returned as the number of milliseconds since January 1, 1970 GMT. The header name is case
207
     * insensitive. If the request did not have a header of the specified name, this method returns -1. If the header
208
     * can't be converted to a date, the method throws an IllegalArgumentException.
209
     **/
210
    @Override
211
    public long getDateHeader(String name) {
212
        try {
213
            String dateString = getHeader(name);
1✔
214
            Date headerDate = new Date(dateString);
1✔
215
            return headerDate.getTime();
1✔
216
        } catch (Exception e) {
1✔
217
            return -1;
1✔
218
        }
219
    }
220

221
    /**
222
     * Returns the value of the specified request header as a String. If the request did not include a header of the
223
     * specified name, this method returns null. The header name is case insensitive. You can use this method with any
224
     * request header.
225
     **/
226
    @Override
227
    public String getHeader(String name) {
228
        return (String) _headers.get(name);
1✔
229
    }
230

231
    /**
232
     * Returns an enumeration of all the header names this request contains. If the request has no headers, this method
233
     * returns an empty enumeration. Some servlet containers do not allow do not allow servlets to access headers using
234
     * this method, in which case this method returns null.
235
     **/
236
    @Override
237
    public Enumeration getHeaderNames() {
238
        return _headers.keys();
1✔
239
    }
240

241
    /**
242
     * Returns the part of this request's URL that calls the servlet. This includes either the servlet name or a path to
243
     * the servlet, but does not include any extra path information or a query string.
244
     **/
245
    @Override
246
    public String getServletPath() {
247
        return _servletRequest.getServletPath();
1✔
248
    }
249

250
    /**
251
     * Returns the name of the HTTP method with which this request was made, for example, GET, POST, or PUT.
252
     **/
253
    @Override
254
    public String getMethod() {
255
        return _request.getMethod();
1✔
256
    }
257

258
    /**
259
     * Returns any extra path information associated with the URL the client sent when it made this request. The extra
260
     * path information follows the servlet path but precedes the query string. This method returns null if there was no
261
     * extra path information.
262
     **/
263
    @Override
264
    public String getPathInfo() {
265
        return _servletRequest.getPathInfo();
1✔
266
    }
267

268
    /**
269
     * Returns any extra path information after the servlet name but before the query string, and translates it to a
270
     * real path. If the URL does not have any extra path information, this method returns null.
271
     **/
272
    @Override
273
    public String getPathTranslated() {
UNCOV
274
        return null;
×
275
    }
276

277
    /**
278
     * Checks whether the requested session ID came in as a cookie.
279
     **/
280
    @Override
281
    public boolean isRequestedSessionIdFromCookie() {
UNCOV
282
        return _sessionID != null;
×
283
    }
284

285
    /**
286
     * Returns the login of the user making this request, if the user has been authenticated, or null if the user has
287
     * not been authenticated. Whether the user name is sent with each subsequent request depends on the browser and
288
     * type of authentication.
289
     **/
290
    @Override
291
    public String getRemoteUser() {
292
        return _userName;
1✔
293
    }
294

295
    /**
296
     * Returns the session ID specified by the client. This may not be the same as the ID of the actual session in use.
297
     * For example, if the request specified an old (expired) session ID and the server has started a new session, this
298
     * method gets a new session with a new ID. If the request did not specify a session ID, this method returns null.
299
     **/
300
    @Override
301
    public String getRequestedSessionId() {
302
        return _sessionID;
1✔
303
    }
304

305
    /**
306
     * Returns the part of this request's URL from the protocol name up to the query string in the first line of the
307
     * HTTP request.
308
     **/
309
    @Override
310
    public String getRequestURI() {
311
        return _requestContext.getRequestURI();
1✔
312
    }
313

314
    /**
315
     * Returns the current HttpSession associated with this request or, if there is no current session and create is
316
     * true, returns a new session. <br>
317
     * If create is false and the request has no valid HttpSession, this method returns null.
318
     **/
319
    @Override
320
    public HttpSession getSession(boolean create) {
321
        _session = _context.getValidSession(getRequestedSessionId(), _session, create);
1✔
322
        return _session;
1✔
323
    }
324

325
    /**
326
     * Returns the current session associated with this request, or if the request does not have a session, creates one.
327
     **/
328
    @Override
329
    public HttpSession getSession() {
330
        return getSession(true);
1✔
331
    }
332

333
    /**
334
     * Checks whether the requested session ID is still valid.
335
     **/
336
    @Override
337
    public boolean isRequestedSessionIdValid() {
UNCOV
338
        return false;
×
339
    }
340

341
    /**
342
     * Checks whether the requested session ID came in as part of the request URL.
343
     **/
344
    @Override
345
    public boolean isRequestedSessionIdFromURL() {
UNCOV
346
        return false;
×
347
    }
348

349
    // --------------------------------- ServletRequest methods ----------------------------------------------------
350

351
    /**
352
     * Returns the length, in bytes, of the content contained in the request and sent by way of the input stream or -1
353
     * if the length is not known.
354
     **/
355
    @Override
356
    public int getContentLength() {
357
        return getIntHeader("Content-length");
1✔
358
    }
359

360
    /**
361
     * Returns the value of the named attribute as an <code>Object</code>. This method allows the servlet engine to give
362
     * the servlet custom information about a request. This method returns <code>null</code> if no attribute of the
363
     * given name exists.
364
     **/
365
    @Override
366
    public Object getAttribute(String name) {
367
        return _attributes.get(name);
1✔
368
    }
369

370
    /**
371
     * Returns an <code>Enumeration</code> containing the names of the attributes available to this request. This method
372
     * returns an empty <code>Enumeration</code> if the request has no attributes available to it.
373
     **/
374
    @Override
375
    public Enumeration getAttributeNames() {
376
        return _attributes.keys();
1✔
377
    }
378

379
    /**
380
     * Retrieves binary data from the body of the request as a {@link ServletInputStream}, which gives you the ability
381
     * to read one line at a time.
382
     *
383
     * @return a {@link ServletInputStream} object containing the body of the request
384
     *
385
     * @exception IllegalStateException
386
     *                if the {@link #getReader} method has already been called for this request
387
     * @exception IOException
388
     *                if an input or output exception occurred
389
     */
390
    @Override
391
    public ServletInputStream getInputStream() throws IOException {
392
        if (_gotReader) {
1✔
393
            throw new IllegalStateException("getReader() has already been called for this request");
1✔
394
        }
395
        initializeInputStream();
1✔
396
        _gotInputStream = true;
1✔
397
        return _inputStream;
1✔
398
    }
399

400
    /**
401
     * initialize the inputStream.
402
     */
403
    private void initializeInputStream() {
404
        if (_inputStream == null) {
1✔
405
            _inputStream = new ServletInputStreamImpl(_messageBody);
1✔
406
        }
407
    }
1✔
408

409
    /**
410
     * Returns the name of the character encoding style used in this request. This method returns <code>null</code> if
411
     * the request does not use character encoding.
412
     **/
413
    @Override
414
    public String getCharacterEncoding() {
415
        return _charset;
1✔
416
    }
417

418
    /**
419
     * Returns an <code>Enumeration</code> of <code>String</code> objects containing the names of the parameters
420
     * contained in this request. If the request has no parameters or if the input stream is empty, returns an empty
421
     * <code>Enumeration</code>. The input stream is empty when all the data returned by {@link #getInputStream} has
422
     * been read.
423
     **/
424
    @Override
425
    public Enumeration getParameterNames() {
UNCOV
426
        return _requestContext.getParameterNames();
×
427
    }
428

429
    /**
430
     * Returns the MIME type of the content of the request, or <code>null</code> if the type is not known. Same as the
431
     * value of the CGI variable CONTENT_TYPE.
432
     **/
433
    @Override
434
    public String getContentType() {
435
        return this.getHeader("Content-Type");
1✔
436
    }
437

438
    /**
439
     * Returns the value of a request parameter as a <code>String</code>, or <code>null</code> if the parameter does not
440
     * exist. Request parameters are extra information sent with the request.
441
     **/
442
    @Override
443
    public String getParameter(String name) {
444
        String[] parameters = getParameterValues(name);
1✔
445
        return parameters == null ? null : parameters[0];
1✔
446
    }
447

448
    /**
449
     * Returns an array of <code>String</code> objects containing all of the values the given request parameter has, or
450
     * <code>null</code> if the parameter does not exist. For example, in an HTTP servlet, this method returns an array
451
     * of <code>String</code> objects containing the values of a query string or posted form.
452
     **/
453
    @Override
454
    public String[] getParameterValues(String name) {
455
        return _requestContext.getParameterValues(name);
1✔
456
    }
457

458
    /**
459
     * Returns the name and version of the protocol the request uses in the form
460
     * <i>protocol/majorVersion.minorVersion</i>, for example, HTTP/1.1.
461
     **/
462
    @Override
463
    public String getProtocol() {
UNCOV
464
        return "HTTP/1.1";
×
465
    }
466

467
    /**
468
     * Returns the name of the scheme used to make this request, for example, <code>http</code>, <code>https</code>, or
469
     * <code>ftp</code>. Different schemes have different rules for constructing URLs, as noted in RFC 1738.
470
     **/
471
    @Override
472
    public String getScheme() {
473
        return _protocol;
1✔
474
    }
475

476
    /**
477
     * Returns the fully qualified name of the client that sent the request.
478
     **/
479
    @Override
480
    public String getRemoteHost() {
UNCOV
481
        return "localhost";
×
482
    }
483

484
    /**
485
     * Returns the host name of the server that received the request.
486
     **/
487
    @Override
488
    public String getServerName() {
489
        return _serverName;
1✔
490
    }
491

492
    /**
493
     * Returns the port number on which this request was received.
494
     **/
495
    @Override
496
    public int getServerPort() {
497
        return _serverPort;
1✔
498
    }
499

500
    /**
501
     * Returns the body of the request as a <code>BufferedReader</code> that translates character set encodings.
502
     *
503
     * @return the reader
504
     **/
505
    @Override
506
    public BufferedReader getReader() throws IOException {
507
        if (_gotInputStream) {
1✔
508
            throw new IllegalStateException("getInputStream() has already been called on this request");
1✔
509
        }
510
        if (_reader == null) {
1✔
511
            initializeInputStream();
1✔
512
            String encoding = getCharacterEncoding();
1✔
513
            if (encoding == null) {
1!
514
                encoding = StandardCharsets.ISO_8859_1.name();
1✔
515
            }
516
            _reader = new BufferedReader(new InputStreamReader(_inputStream, Charset.forName(encoding)));
1✔
517
            _gotReader = true;
1✔
518
        }
519
        return _reader;
1✔
520
    }
521

522
    /**
523
     * Returns the Internet Protocol (IP) address of the client that sent the request.
524
     **/
525
    @Override
526
    public String getRemoteAddr() {
UNCOV
527
        return LOOPBACK_ADDRESS;
×
528
    }
529

530
    /**
531
     * Stores an attribute in the context of this request. Attributes are reset between requests.
532
     **/
533
    @Override
534
    public void setAttribute(String key, Object o) {
535
        if (o == null) {
1✔
536
            _attributes.remove(key);
1✔
537
        } else {
538
            _attributes.put(key, o);
1✔
539
        }
540
    }
1✔
541

542
    // --------------------------------- methods added to ServletRequest in Servlet API 2.2
543
    // ------------------------------------------------
544

545
    /**
546
     * Returns a boolean indicating whether this request was made using a secure channel, such as HTTPS.
547
     **/
548
    @Override
549
    public boolean isSecure() {
550
        return _secure;
1✔
551
    }
552

553
    /**
554
     * Returns the preferred Locale that the client will accept content in, based on the Accept-Language header. If the
555
     * client request doesn't provide an Accept-Language header, this method returns the default locale for the server.
556
     **/
557
    @Override
558
    public Locale getLocale() {
559
        return (Locale) getPreferredLocales().get(0);
1✔
560
    }
561

562
    /**
563
     * Returns an Enumeration of Locale objects indicating, in decreasing order starting with the preferred locale, the
564
     * locales that are acceptable to the client based on the Accept-Language header. If the client request doesn't
565
     * provide an Accept-Language header, this method returns an Enumeration containing one Locale, the default locale
566
     * for the server.
567
     **/
568
    @Override
569
    public java.util.Enumeration getLocales() {
570
        return Collections.enumeration(getPreferredLocales());
1✔
571
    }
572

573
    /**
574
     * Parses the accept-language header to obtain a list of preferred locales.
575
     *
576
     * @return the preferred locales, sorted by qvalue
577
     */
578
    private List getPreferredLocales() {
579
        if (_locales == null) {
1✔
580
            _locales = new ArrayList<>();
1✔
581
            String languages = getHeader("accept-language");
1✔
582
            if (languages == null) {
1✔
583
                _locales.add(Locale.getDefault());
1✔
584
            } else {
585
                StringTokenizer st = new StringTokenizer(languages, ",");
1✔
586
                ArrayList al = new ArrayList<>();
1✔
587
                while (st.hasMoreTokens()) {
1✔
588
                    String token = st.nextToken();
1✔
589
                    al.add(new PrioritizedLocale(token));
1✔
590
                }
1✔
591
                Collections.sort(al);
1✔
592
                for (Iterator iterator = al.iterator(); iterator.hasNext();) {
1✔
593
                    _locales.add(((PrioritizedLocale) iterator.next()).getLocale());
1✔
594
                }
595
            }
596
        }
597
        return _locales;
1✔
598
    }
599

600
    /**
601
     * Removes an attribute from this request. This method is not generally needed as attributes only persist as long as
602
     * the request is being handled.
603
     **/
604
    @Override
605
    public void removeAttribute(String name) {
UNCOV
606
        _attributes.remove(name);
×
607
    }
×
608

609
    /**
610
     * Returns a RequestDispatcher object that acts as a wrapper for the resource located at the given path. A
611
     * RequestDispatcher object can be used to forward a request to the resource or to include the resource in a
612
     * response. The resource can be dynamic or static. The pathname specified may be relative, although it cannot
613
     * extend outside the current servlet context. If the path begins with a "/" it is interpreted as relative to the
614
     * current context root. This method returns null if the servlet container cannot return a RequestDispatcher. The
615
     * difference between this method and ServletContext.getRequestDispatcher(java.lang.String) is that this method can
616
     * take a relative path.
617
     **/
618
    @Override
619
    public RequestDispatcher getRequestDispatcher(String path) {
620
        try {
621
            if (!path.startsWith("/")) {
1✔
622
                path = combinedPath(getServletPath(), path);
1✔
623
            }
624
            return _servletRequest.getServlet().getServletConfig().getServletContext().getRequestDispatcher(path);
1✔
UNCOV
625
        } catch (ServletException e) {
×
626
            return null;
×
627
        }
628
    }
629

630
    /**
631
     * Combined path.
632
     *
633
     * @param basePath
634
     *            the base path
635
     * @param relativePath
636
     *            the relative path
637
     *
638
     * @return the string
639
     */
640
    private String combinedPath(String basePath, String relativePath) {
641
        if (basePath.indexOf('/') < 0) {
1!
UNCOV
642
            return relativePath;
×
643
        }
644
        return basePath.substring(0, basePath.lastIndexOf('/')) + '/' + relativePath;
1✔
645
    }
646

647
    // --------------------------------- methods added to HttpServletRequest in Servlet API 2.2
648
    // ------------------------------------------------
649

650
    /**
651
     * Returns a java.security.Principal object containing the name of the current authenticated user. If the user has
652
     * not been authenticated, the method returns null.
653
     **/
654
    @Override
655
    public java.security.Principal getUserPrincipal() {
UNCOV
656
        return null;
×
657
    }
658

659
    /**
660
     * Returns a boolean indicating whether the authenticated user is included in the specified logical "role". Roles
661
     * and role membership can be defined using deployment descriptors. If the user has not been authenticated, the
662
     * method returns false.
663
     **/
664
    @Override
665
    public boolean isUserInRole(String role) {
666
        if (_roles == null) {
1✔
667
            return false;
1✔
668
        }
669
        for (String _role : _roles) {
1✔
670
            if (role.equals(_role)) {
1✔
671
                return true;
1✔
672
            }
673
        }
674
        return false;
1✔
675
    }
676

677
    /**
678
     * Returns all the values of the specified request header as an Enumeration of String objects.
679
     **/
680
    @Override
681
    public java.util.Enumeration getHeaders(String name) {
682
        List list = new ArrayList<>();
1✔
683
        if (_headers.containsKey(name)) {
1!
684
            list.add(_headers.get(name));
1✔
685
        }
686
        return Collections.enumeration(list);
1✔
687
    }
688

689
    /**
690
     * Returns the portion of the request URI that indicates the context of the request. The context path always comes
691
     * first in a request URI. The path starts with a "/" character but does not end with a "/" character. For servlets
692
     * in the default (root) context, this method returns "".
693
     **/
694
    @Override
695
    public String getContextPath() {
696
        return _context.getContextPath();
1✔
697
    }
698

699
    // --------------------------------------- methods added to ServletRequest in Servlet API 2.3
700
    // ----------------------------
701

702
    /**
703
     * Returns a java.util.Map of the parameters of this request. Request parameters are extra information sent with the
704
     * request. For HTTP servlets, parameters are contained in the query string or posted form data.
705
     **/
706
    @Override
707
    public Map getParameterMap() {
708
        return _requestContext.getParameterMap();
1✔
709
    }
710

711
    /**
712
     * Overrides the name of the character encoding used in the body of this request. This method must be called prior
713
     * to reading request parameters or reading input using getReader().
714
     **/
715
    @Override
716
    public void setCharacterEncoding(String charset) {
717
        _charset = charset;
1✔
718
        _requestContext.setMessageEncoding(charset);
1✔
719
    }
1✔
720

721
    // --------------------------------------- methods added to HttpServletRequest in Servlet API 2.3
722
    // ----------------------------
723

724
    /**
725
     * Reconstructs the URL the client used to make the request. The returned URL contains a protocol, server name, port
726
     * number, and server path, but it does not include query string parameters. Because this method returns a
727
     * StringBuffer, not a string, you can modify the URL easily, for example, to append query parameters. This method
728
     * is useful for creating redirect messages and for reporting errors.
729
     */
730
    @Override
731
    public StringBuffer getRequestURL() {
732
        StringBuilder url = new StringBuilder();
1✔
733
        try {
734
            url.append(_request.getURL().getProtocol()).append("://");
1✔
735
            url.append(_request.getURL().getHost());
1✔
736
            String portPortion = _request.getURL().getPort() == -1 ? "" : ":" + _request.getURL().getPort();
1✔
737
            url.append(portPortion);
1✔
738
            url.append(_request.getURL().getPath());
1✔
UNCOV
739
        } catch (MalformedURLException e) {
×
740
            throw new RuntimeException("unable to read URL from request: " + _request);
×
741
        }
1✔
742
        return new StringBuffer(url);
1✔
743
    }
744

745
    // --------------------------------------- methods added to ServletRequest in Servlet API 2.4
746
    // ----------------------------
747

748
    @Override
749
    public int getRemotePort() {
UNCOV
750
        return 0; // To change body of implemented methods use File | Settings | File Templates.
×
751
    }
752

753
    @Override
754
    public String getLocalName() {
UNCOV
755
        return "localhost";
×
756
    }
757

758
    @Override
759
    public String getLocalAddr() {
UNCOV
760
        return "127.0.0.1";
×
761
    }
762

763
    @Override
764
    public int getLocalPort() {
UNCOV
765
        return 0; // To change body of implemented methods use File | Settings | File Templates.
×
766
    }
767

768
    // --------------------------------------------- package members ----------------------------------------------
769

770
    /**
771
     * Adds the cookie.
772
     *
773
     * @param cookie
774
     *            the cookie
775
     */
776
    private void addCookie(Cookie cookie) {
777
        _cookies.add(cookie);
1✔
778
        if (cookie.getName().equalsIgnoreCase(ServletUnitHttpSession.SESSION_COOKIE_NAME)) {
1✔
779
            _sessionID = cookie.getValue();
1✔
780
        }
781
    }
1✔
782

783
    /**
784
     * Gets the servlet session.
785
     *
786
     * @return the servlet session
787
     */
788
    private ServletUnitHttpSession getServletSession() {
789
        return (ServletUnitHttpSession) getSession();
1✔
790
    }
791

792
    /**
793
     * Read form authentication.
794
     */
795
    void readFormAuthentication() {
796
        if (getSession( /* create */ false) != null) {
1✔
797
            recordAuthenticationInfo(getServletSession().getUserName(), getServletSession().getRoles());
1✔
798
        }
799
    }
1✔
800

801
    /**
802
     * Read basic authentication.
803
     */
804
    void readBasicAuthentication() {
805
        String authorizationHeader = (String) _headers.get("Authorization");
1✔
806

807
        if (authorizationHeader != null) {
1✔
808
            String userAndPassword = new String(Base64.getDecoder().decode(authorizationHeader
1✔
809
                    .substring(authorizationHeader.indexOf(' ') + 1).getBytes(StandardCharsets.UTF_8)),
1✔
810
                    StandardCharsets.UTF_8);
811
            int colonPos = userAndPassword.indexOf(':');
1✔
812
            recordAuthenticationInfo(userAndPassword.substring(0, colonPos),
1✔
813
                    toArray(userAndPassword.substring(colonPos + 1)));
1✔
814
        }
815
    }
1✔
816

817
    /**
818
     * To array.
819
     *
820
     * @param roleList
821
     *            the role list
822
     *
823
     * @return the string[]
824
     */
825
    static String[] toArray(String roleList) {
826
        StringTokenizer st = new StringTokenizer(roleList, ",");
1✔
827
        String[] result = new String[st.countTokens()];
1✔
828
        for (int i = 0; i < result.length; i++) {
1✔
829
            result[i] = st.nextToken();
1✔
830
        }
831
        return result;
1✔
832
    }
833

834
    /**
835
     * Record authentication info.
836
     *
837
     * @param userName
838
     *            the user name
839
     * @param roles
840
     *            the roles
841
     */
842
    void recordAuthenticationInfo(String userName, String[] roles) {
843
        _userName = userName;
1✔
844
        _roles = roles;
1✔
845
    }
1✔
846

847
    // --------------------------------------------- private members ----------------------------------------------
848

849
    /** The Constant LOOPBACK_ADDRESS. */
850
    private static final String LOOPBACK_ADDRESS = "127.0.0.1";
851

852
    /** The request. */
853
    private WebRequest _request;
854

855
    /** The servlet request. */
856
    private ServletMetaData _servletRequest;
857

858
    /** The headers. */
859
    private WebClient.HeaderDictionary _headers;
860

861
    /** The context. */
862
    private ServletUnitContext _context;
863

864
    /** The session. */
865
    private ServletUnitHttpSession _session;
866

867
    /** The attributes. */
868
    private Hashtable _attributes = new Hashtable<>();
1✔
869

870
    /** The cookies. */
871
    private List<Cookie> _cookies = new ArrayList<>();
1✔
872

873
    /** The session ID. */
874
    private String _sessionID;
875

876
    /** The message body. */
877
    private byte[] _messageBody;
878

879
    /** The user name. */
880
    private String _userName;
881

882
    /** The roles. */
883
    private String[] _roles;
884

885
    /**
886
     * Throw not implemented yet.
887
     */
888
    private void throwNotImplementedYet() {
UNCOV
889
        throw new RuntimeException("Not implemented yet");
×
890
    }
891

892
    /**
893
     * Sets the cookies from header.
894
     *
895
     * @param clientHeaders
896
     *            the new cookies from header
897
     */
898
    private void setCookiesFromHeader(Dictionary clientHeaders) {
899
        String cookieHeader = (String) clientHeaders.get("Cookie");
1✔
900
        if (cookieHeader == null) {
1✔
901
            return;
1✔
902
        }
903

904
        StringTokenizer st = new StringTokenizer(cookieHeader, ",;=", true);
1✔
905
        String lastToken = st.nextToken();
1✔
906
        while (st.hasMoreTokens()) {
1✔
907
            String token = st.nextToken();
1✔
908
            if (token.equals("=") && st.hasMoreTokens()) {
1!
909
                addCookie(new Cookie(lastToken.trim(), st.nextToken().trim()));
1✔
910
            }
911
            lastToken = token;
1✔
912
        }
1✔
913
    }
1✔
914

915
    /**
916
     * The Class PrioritizedLocale.
917
     */
918
    static class PrioritizedLocale implements Comparable {
919

920
        /** The locale. */
921
        private Locale _locale;
922

923
        /** The priority. */
924
        private float _priority;
925

926
        /**
927
         * Instantiates a new prioritized locale.
928
         *
929
         * @param languageSpec
930
         *            the language spec
931
         */
932
        PrioritizedLocale(String languageSpec) {
1✔
933
            int semiIndex = languageSpec.indexOf(';');
1✔
934
            if (semiIndex < 0) {
1✔
935
                _priority = 1;
1✔
936
                _locale = parseLocale(languageSpec);
1✔
937
            } else {
938
                _priority = Float.parseFloat(languageSpec.substring(languageSpec.indexOf('=', semiIndex) + 1));
1✔
939
                _locale = parseLocale(languageSpec.substring(0, semiIndex));
1✔
940
            }
941
        }
1✔
942

943
        /**
944
         * Parses the locale.
945
         *
946
         * @param range
947
         *            the range
948
         *
949
         * @return the locale
950
         */
951
        private Locale parseLocale(String range) {
952
            range = range.trim();
1✔
953
            int dashIndex = range.indexOf('-');
1✔
954
            if (dashIndex < 0) {
1✔
955
                return new Locale(range, "");
1✔
956
            }
957
            return new Locale(range.substring(0, dashIndex), range.substring(dashIndex + 1));
1✔
958
        }
959

960
        /**
961
         * Gets the locale.
962
         *
963
         * @return the locale
964
         */
965
        public Locale getLocale() {
966
            return _locale;
1✔
967
        }
968

969
        @Override
970
        public int compareTo(Object o) {
971
            if (!(o instanceof PrioritizedLocale)) {
1!
UNCOV
972
                throw new IllegalArgumentException("may only combine with other prioritized locales");
×
973
            }
974
            PrioritizedLocale other = (PrioritizedLocale) o;
1✔
975
            return _priority == other._priority ? _locale.getLanguage().compareTo(other._locale.getLanguage())
1!
976
                    : _priority < other._priority ? +1 : -1;
1✔
977
        }
978

979
    }
980

981
    @Override
982
    public ServletContext getServletContext() {
983
        try {
UNCOV
984
            return _servletRequest.getServlet().getServletConfig().getServletContext();
×
985
        } catch (ServletException e) {
×
986
            return null;
×
987
        }
988
    }
989

990
    @Override
991
    public AsyncContext startAsync() throws IllegalStateException {
992
        // TODO Auto-generated method stub
UNCOV
993
        return null;
×
994
    }
995

996
    @Override
997
    public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse)
998
            throws IllegalStateException {
999
        // TODO Auto-generated method stub
UNCOV
1000
        return null;
×
1001
    }
1002

1003
    @Override
1004
    public boolean isAsyncStarted() {
1005
        // TODO Auto-generated method stub
UNCOV
1006
        return false;
×
1007
    }
1008

1009
    @Override
1010
    public boolean isAsyncSupported() {
1011
        // TODO Auto-generated method stub
UNCOV
1012
        return false;
×
1013
    }
1014

1015
    @Override
1016
    public AsyncContext getAsyncContext() {
1017
        // TODO Auto-generated method stub
UNCOV
1018
        return null;
×
1019
    }
1020

1021
    @Override
1022
    public DispatcherType getDispatcherType() {
1023
        // TODO Auto-generated method stub
UNCOV
1024
        return null;
×
1025
    }
1026

1027
    @Override
1028
    public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {
1029
        // TODO Auto-generated method stub
UNCOV
1030
        return false;
×
1031
    }
1032

1033
    @Override
1034
    public void login(String username, String password) throws ServletException {
1035
        // TODO Auto-generated method stub
1036

UNCOV
1037
    }
×
1038

1039
    @Override
1040
    public void logout() throws ServletException {
1041
        // TODO Auto-generated method stub
1042

UNCOV
1043
    }
×
1044

1045
    @Override
1046
    public Collection<Part> getParts() throws IOException, ServletException {
1047
        // TODO Auto-generated method stub
UNCOV
1048
        return null;
×
1049
    }
1050

1051
    @Override
1052
    public Part getPart(String name) throws IOException, ServletException {
1053
        // TODO Auto-generated method stub
UNCOV
1054
        return null;
×
1055
    }
1056

1057
    @Override
1058
    public long getContentLengthLong() {
1059
        // TODO Auto-generated method stub
UNCOV
1060
        return 0;
×
1061
    }
1062

1063
    @Override
1064
    public String changeSessionId() {
1065
        // TODO Auto-generated method stub
UNCOV
1066
        return null;
×
1067
    }
1068

1069
    @Override
1070
    public <T extends HttpUpgradeHandler> T upgrade(Class<T> handlerClass) throws IOException, ServletException {
1071
        // TODO Auto-generated method stub
UNCOV
1072
        return null;
×
1073
    }
1074

1075
    @Override
1076
    public String getRequestId() {
1077
        // TODO Auto-generated method stub
UNCOV
1078
        return null;
×
1079
    }
1080

1081
    @Override
1082
    public String getProtocolRequestId() {
1083
        // TODO Auto-generated method stub
UNCOV
1084
        return null;
×
1085
    }
1086

1087
    @Override
1088
    public ServletConnection getServletConnection() {
1089
        // TODO Auto-generated method stub
UNCOV
1090
        return null;
×
1091
    }
1092
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc