• 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

82.75
/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.StandardCharsets;
47
import java.util.ArrayList;
48
import java.util.Base64;
49
import java.util.Collection;
50
import java.util.Collections;
51
import java.util.Date;
52
import java.util.Dictionary;
53
import java.util.Enumeration;
54
import java.util.Hashtable;
55
import java.util.Iterator;
56
import java.util.Locale;
57
import java.util.Map;
58
import java.util.StringTokenizer;
59
import java.util.Vector;
60

61
class ServletUnitHttpRequest implements HttpServletRequest {
62

63
    private ServletInputStreamImpl _inputStream;
64
    private Vector _locales;
65
    private String _protocol;
66
    private boolean _secure;
67
    private RequestContext _requestContext;
68
    private String _charset;
69
    private boolean _gotReader;
70
    private boolean _gotInputStream;
71
    private BufferedReader _reader;
72
    private int _serverPort;
73
    private String _serverName;
74

75
    /**
76
     * Constructs a ServletUnitHttpRequest from a WebRequest object.
77
     **/
78
    ServletUnitHttpRequest(ServletMetaData servletRequest, WebRequest request, ServletUnitContext context,
79
            Dictionary clientHeaders, byte[] messageBody) throws MalformedURLException {
1✔
80
        if (context == null) {
1!
81
            throw new IllegalArgumentException("Context must not be null");
×
82
        }
83

84
        _servletRequest = servletRequest;
1✔
85
        _request = request;
1✔
86
        _context = context;
1✔
87
        _headers = new WebClient.HeaderDictionary();
1✔
88
        _headers.addEntries(clientHeaders);
1✔
89
        _headers.addEntries(request.getHeaders());
1✔
90
        setCookiesFromHeader(_headers);
1✔
91
        _messageBody = messageBody;
1✔
92
        _protocol = request.getURL().getProtocol().toLowerCase();
1✔
93
        _secure = _protocol.endsWith("s");
1✔
94
        _serverName = request.getURL().getHost();
1✔
95
        _serverPort = request.getURL().getPort();
1✔
96
        if (_serverPort == -1) {
1✔
97
            _serverPort = request.getURL().getDefaultPort();
1✔
98
        }
99

100
        _requestContext = new RequestContext(request.getURL());
1✔
101
        String contentTypeHeader = (String) _headers.get("Content-Type");
1✔
102
        if (contentTypeHeader != null) {
1✔
103
            String[] res = HttpUnitUtils.parseContentTypeHeader(contentTypeHeader);
1✔
104
            _charset = res[1];
1✔
105
            _requestContext.setMessageEncoding(_charset);
1✔
106
        }
107
        if (_headers.get("Content-Length") == null) {
1!
108
            _headers.put("Content-Length", Integer.toString(messageBody.length));
1✔
109
        }
110

111
        boolean setBody =
1!
112
                // pre [ 1509117 ] getContentType()
113
                // _messageBody != null && (_contentType == null || _contentType.indexOf( "x-www-form-urlencoded" ) >= 0
114
                // );
115
                // patch version:
116
                _messageBody != null
117
                        && (contentTypeHeader == null || contentTypeHeader.indexOf("x-www-form-urlencoded") >= 0);
1✔
118
        if (setBody) {
1✔
119
            _requestContext.setMessageBody(_messageBody);
1✔
120
        }
121
    }
1✔
122

123
    // ----------------------------------------- HttpServletRequest methods --------------------------
124

125
    /**
126
     * Returns the name of the authentication scheme used to protect the servlet, for example, "BASIC" or "SSL," or null
127
     * if the servlet was not protected.
128
     **/
129
    @Override
130
    public String getAuthType() {
131
        return null;
1✔
132
    }
133

134
    /**
135
     * Returns the query string that is contained in the request URL after the path.
136
     **/
137
    @Override
138
    public String getQueryString() {
139
        return _request.getQueryString();
1✔
140
    }
141

142
    /**
143
     * Returns an array containing all of the Cookie objects the client sent with this request. This method returns null
144
     * if no cookies were sent.
145
     **/
146
    @Override
147
    public Cookie[] getCookies() {
148
        if (_cookies.size() == 0) {
1✔
149
            return null;
1✔
150
        }
151
        Cookie[] result = new Cookie[_cookies.size()];
1✔
152
        _cookies.copyInto(result);
1✔
153
        return result;
1✔
154
    }
155

156
    /**
157
     * Returns the value of the specified request header as an int. If the request does not have a header of the
158
     * specified name, this method returns -1. If the header cannot be converted to an integer, this method throws a
159
     * NumberFormatException.
160
     **/
161
    @Override
162
    public int getIntHeader(String name) {
163
        return Integer.parseInt(getHeader(name));
1✔
164
    }
165

166
    /**
167
     * Returns the value of the specified request header as a long value that represents a Date object. Use this method
168
     * with headers that contain dates, such as If-Modified-Since. <br>
169
     * The date is returned as the number of milliseconds since January 1, 1970 GMT. The header name is case
170
     * insensitive. If the request did not have a header of the specified name, this method returns -1. If the header
171
     * can't be converted to a date, the method throws an IllegalArgumentException.
172
     **/
173
    @Override
174
    public long getDateHeader(String name) {
175
        try {
176
            String dateString = getHeader(name);
1✔
177
            Date headerDate = new Date(dateString);
1✔
178
            return headerDate.getTime();
1✔
179
        } catch (Exception e) {
1✔
180
            return -1;
1✔
181
        }
182
    }
183

184
    /**
185
     * Returns the value of the specified request header as a String. If the request did not include a header of the
186
     * specified name, this method returns null. The header name is case insensitive. You can use this method with any
187
     * request header.
188
     **/
189
    @Override
190
    public String getHeader(String name) {
191
        return (String) _headers.get(name);
1✔
192
    }
193

194
    /**
195
     * Returns an enumeration of all the header names this request contains. If the request has no headers, this method
196
     * returns an empty enumeration. Some servlet containers do not allow do not allow servlets to access headers using
197
     * this method, in which case this method returns null.
198
     **/
199
    @Override
200
    public Enumeration getHeaderNames() {
201
        return _headers.keys();
1✔
202
    }
203

204
    /**
205
     * Returns the part of this request's URL that calls the servlet. This includes either the servlet name or a path to
206
     * the servlet, but does not include any extra path information or a query string.
207
     **/
208
    @Override
209
    public String getServletPath() {
210
        return _servletRequest.getServletPath();
1✔
211
    }
212

213
    /**
214
     * Returns the name of the HTTP method with which this request was made, for example, GET, POST, or PUT.
215
     **/
216
    @Override
217
    public String getMethod() {
218
        return _request.getMethod();
1✔
219
    }
220

221
    /**
222
     * Returns any extra path information associated with the URL the client sent when it made this request. The extra
223
     * path information follows the servlet path but precedes the query string. This method returns null if there was no
224
     * extra path information.
225
     **/
226
    @Override
227
    public String getPathInfo() {
228
        return _servletRequest.getPathInfo();
1✔
229
    }
230

231
    /**
232
     * Returns any extra path information after the servlet name but before the query string, and translates it to a
233
     * real path. If the URL does not have any extra path information, this method returns null.
234
     **/
235
    @Override
236
    public String getPathTranslated() {
237
        return null;
×
238
    }
239

240
    /**
241
     * Checks whether the requested session ID came in as a cookie.
242
     **/
243
    @Override
244
    public boolean isRequestedSessionIdFromCookie() {
245
        return _sessionID != null;
×
246
    }
247

248
    /**
249
     * Returns the login of the user making this request, if the user has been authenticated, or null if the user has
250
     * not been authenticated. Whether the user name is sent with each subsequent request depends on the browser and
251
     * type of authentication.
252
     **/
253
    @Override
254
    public String getRemoteUser() {
255
        return _userName;
1✔
256
    }
257

258
    /**
259
     * Returns the session ID specified by the client. This may not be the same as the ID of the actual session in use.
260
     * For example, if the request specified an old (expired) session ID and the server has started a new session, this
261
     * method gets a new session with a new ID. If the request did not specify a session ID, this method returns null.
262
     **/
263
    @Override
264
    public String getRequestedSessionId() {
265
        return _sessionID;
1✔
266
    }
267

268
    /**
269
     * Returns the part of this request's URL from the protocol name up to the query string in the first line of the
270
     * HTTP request.
271
     **/
272
    @Override
273
    public String getRequestURI() {
274
        return _requestContext.getRequestURI();
1✔
275
    }
276

277
    /**
278
     * Returns the current HttpSession associated with this request or, if there is no current session and create is
279
     * true, returns a new session. <br>
280
     * If create is false and the request has no valid HttpSession, this method returns null.
281
     **/
282
    @Override
283
    public HttpSession getSession(boolean create) {
284
        _session = _context.getValidSession(getRequestedSessionId(), _session, create);
1✔
285
        return _session;
1✔
286
    }
287

288
    /**
289
     * Returns the current session associated with this request, or if the request does not have a session, creates one.
290
     **/
291
    @Override
292
    public HttpSession getSession() {
293
        return getSession(true);
1✔
294
    }
295

296
    /**
297
     * Checks whether the requested session ID is still valid.
298
     **/
299
    @Override
300
    public boolean isRequestedSessionIdValid() {
301
        return false;
×
302
    }
303

304
    /**
305
     * Checks whether the requested session ID came in as part of the request URL.
306
     **/
307
    @Override
308
    public boolean isRequestedSessionIdFromURL() {
309
        return false;
×
310
    }
311

312
    // --------------------------------- ServletRequest methods ----------------------------------------------------
313

314
    /**
315
     * Returns the length, in bytes, of the content contained in the request and sent by way of the input stream or -1
316
     * if the length is not known.
317
     **/
318
    @Override
319
    public int getContentLength() {
320
        return getIntHeader("Content-length");
1✔
321
    }
322

323
    /**
324
     * Returns the value of the named attribute as an <code>Object</code>. This method allows the servlet engine to give
325
     * the servlet custom information about a request. This method returns <code>null</code> if no attribute of the
326
     * given name exists.
327
     **/
328
    @Override
329
    public Object getAttribute(String name) {
330
        return _attributes.get(name);
1✔
331
    }
332

333
    /**
334
     * Returns an <code>Enumeration</code> containing the names of the attributes available to this request. This method
335
     * returns an empty <code>Enumeration</code> if the request has no attributes available to it.
336
     **/
337
    @Override
338
    public Enumeration getAttributeNames() {
339
        return _attributes.keys();
1✔
340
    }
341

342
    /**
343
     * Retrieves binary data from the body of the request as a {@link ServletInputStream}, which gives you the ability
344
     * to read one line at a time.
345
     *
346
     * @return a {@link ServletInputStream} object containing the body of the request
347
     *
348
     * @exception IllegalStateException
349
     *                if the {@link #getReader} method has already been called for this request
350
     * @exception IOException
351
     *                if an input or output exception occurred
352
     */
353
    @Override
354
    public ServletInputStream getInputStream() throws IOException {
355
        if (_gotReader) {
1✔
356
            throw new IllegalStateException("getReader() has already been called for this request");
1✔
357
        }
358
        initializeInputStream();
1✔
359
        _gotInputStream = true;
1✔
360
        return _inputStream;
1✔
361
    }
362

363
    /**
364
     * initialize the inputStream
365
     */
366
    private void initializeInputStream() {
367
        if (_inputStream == null) {
1✔
368
            _inputStream = new ServletInputStreamImpl(_messageBody);
1✔
369
        }
370
    }
1✔
371

372
    /**
373
     * Returns the name of the character encoding style used in this request. This method returns <code>null</code> if
374
     * the request does not use character encoding.
375
     **/
376
    @Override
377
    public String getCharacterEncoding() {
378
        return _charset;
1✔
379
    }
380

381
    /**
382
     * Returns an <code>Enumeration</code> of <code>String</code> objects containing the names of the parameters
383
     * contained in this request. If the request has no parameters or if the input stream is empty, returns an empty
384
     * <code>Enumeration</code>. The input stream is empty when all the data returned by {@link #getInputStream} has
385
     * been read.
386
     **/
387
    @Override
388
    public Enumeration getParameterNames() {
389
        return _requestContext.getParameterNames();
×
390
    }
391

392
    /**
393
     * Returns the MIME type of the content of the request, or <code>null</code> if the type is not known. Same as the
394
     * value of the CGI variable CONTENT_TYPE.
395
     **/
396
    @Override
397
    public String getContentType() {
398
        return this.getHeader("Content-Type");
1✔
399
    }
400

401
    /**
402
     * Returns the value of a request parameter as a <code>String</code>, or <code>null</code> if the parameter does not
403
     * exist. Request parameters are extra information sent with the request.
404
     **/
405
    @Override
406
    public String getParameter(String name) {
407
        String[] parameters = getParameterValues(name);
1✔
408
        return parameters == null ? null : parameters[0];
1✔
409
    }
410

411
    /**
412
     * Returns an array of <code>String</code> objects containing all of the values the given request parameter has, or
413
     * <code>null</code> if the parameter does not exist. For example, in an HTTP servlet, this method returns an array
414
     * of <code>String</code> objects containing the values of a query string or posted form.
415
     **/
416
    @Override
417
    public String[] getParameterValues(String name) {
418
        return _requestContext.getParameterValues(name);
1✔
419
    }
420

421
    /**
422
     * Returns the name and version of the protocol the request uses in the form
423
     * <i>protocol/majorVersion.minorVersion</i>, for example, HTTP/1.1.
424
     **/
425
    @Override
426
    public String getProtocol() {
427
        return "HTTP/1.1";
×
428
    }
429

430
    /**
431
     * Returns the name of the scheme used to make this request, for example, <code>http</code>, <code>https</code>, or
432
     * <code>ftp</code>. Different schemes have different rules for constructing URLs, as noted in RFC 1738.
433
     **/
434
    @Override
435
    public String getScheme() {
436
        return _protocol;
1✔
437
    }
438

439
    /**
440
     * Returns the fully qualified name of the client that sent the request.
441
     **/
442
    @Override
443
    public String getRemoteHost() {
444
        return "localhost";
×
445
    }
446

447
    /**
448
     * Returns the host name of the server that received the request.
449
     **/
450
    @Override
451
    public String getServerName() {
452
        return _serverName;
1✔
453
    }
454

455
    /**
456
     * Returns the port number on which this request was received.
457
     **/
458
    @Override
459
    public int getServerPort() {
460
        return _serverPort;
1✔
461
    }
462

463
    /**
464
     * Returns the body of the request as a <code>BufferedReader</code> that translates character set encodings.
465
     *
466
     * @return the reader
467
     **/
468
    @Override
469
    public BufferedReader getReader() throws IOException {
470
        if (_gotInputStream) {
1✔
471
            throw new IllegalStateException("getInputStream() has already been called on this request");
1✔
472
        }
473
        if (_reader == null) {
1✔
474
            initializeInputStream();
1✔
475
            String encoding = getCharacterEncoding();
1✔
476
            if (encoding == null) {
1!
477
                encoding = StandardCharsets.ISO_8859_1.name();
1✔
478
            }
479
            _reader = new BufferedReader(new InputStreamReader(_inputStream, encoding));
1✔
480
            _gotReader = true;
1✔
481
        }
482
        return _reader;
1✔
483
    }
484

485
    /**
486
     * Returns the Internet Protocol (IP) address of the client that sent the request.
487
     **/
488
    @Override
489
    public String getRemoteAddr() {
490
        return LOOPBACK_ADDRESS;
×
491
    }
492

493
    /**
494
     * Stores an attribute in the context of this request. Attributes are reset between requests.
495
     **/
496
    @Override
497
    public void setAttribute(String key, Object o) {
498
        if (o == null) {
1✔
499
            _attributes.remove(key);
1✔
500
        } else {
501
            _attributes.put(key, o);
1✔
502
        }
503
    }
1✔
504

505
    // --------------------------------- methods added to ServletRequest in Servlet API 2.2
506
    // ------------------------------------------------
507

508
    /**
509
     * Returns a boolean indicating whether this request was made using a secure channel, such as HTTPS.
510
     **/
511
    @Override
512
    public boolean isSecure() {
513
        return _secure;
1✔
514
    }
515

516
    /**
517
     * Returns the preferred Locale that the client will accept content in, based on the Accept-Language header. If the
518
     * client request doesn't provide an Accept-Language header, this method returns the default locale for the server.
519
     **/
520
    @Override
521
    public Locale getLocale() {
522
        return (Locale) getPreferredLocales().firstElement();
1✔
523
    }
524

525
    /**
526
     * Returns an Enumeration of Locale objects indicating, in decreasing order starting with the preferred locale, the
527
     * locales that are acceptable to the client based on the Accept-Language header. If the client request doesn't
528
     * provide an Accept-Language header, this method returns an Enumeration containing one Locale, the default locale
529
     * for the server.
530
     **/
531
    @Override
532
    public java.util.Enumeration getLocales() {
533
        return getPreferredLocales().elements();
1✔
534
    }
535

536
    /**
537
     * Parses the accept-language header to obtain a vector of preferred locales
538
     *
539
     * @return the preferred locales, sorted by qvalue
540
     */
541
    private Vector getPreferredLocales() {
542
        if (_locales == null) {
1✔
543
            _locales = new Vector<>();
1✔
544
            String languages = getHeader("accept-language");
1✔
545
            if (languages == null) {
1✔
546
                _locales.add(Locale.getDefault());
1✔
547
            } else {
548
                StringTokenizer st = new StringTokenizer(languages, ",");
1✔
549
                ArrayList al = new ArrayList<>();
1✔
550
                while (st.hasMoreTokens()) {
1✔
551
                    String token = st.nextToken();
1✔
552
                    al.add(new PrioritizedLocale(token));
1✔
553
                }
1✔
554
                Collections.sort(al);
1✔
555
                for (Iterator iterator = al.iterator(); iterator.hasNext();) {
1✔
556
                    _locales.add(((PrioritizedLocale) iterator.next()).getLocale());
1✔
557
                }
558
            }
559
        }
560
        return _locales;
1✔
561
    }
562

563
    /**
564
     * Removes an attribute from this request. This method is not generally needed as attributes only persist as long as
565
     * the request is being handled.
566
     **/
567
    @Override
568
    public void removeAttribute(String name) {
569
        _attributes.remove(name);
×
570
    }
×
571

572
    /**
573
     * Returns a RequestDispatcher object that acts as a wrapper for the resource located at the given path. A
574
     * RequestDispatcher object can be used to forward a request to the resource or to include the resource in a
575
     * response. The resource can be dynamic or static. The pathname specified may be relative, although it cannot
576
     * extend outside the current servlet context. If the path begins with a "/" it is interpreted as relative to the
577
     * current context root. This method returns null if the servlet container cannot return a RequestDispatcher. The
578
     * difference between this method and ServletContext.getRequestDispatcher(java.lang.String) is that this method can
579
     * take a relative path.
580
     **/
581
    @Override
582
    public RequestDispatcher getRequestDispatcher(String path) {
583
        try {
584
            if (!path.startsWith("/")) {
1✔
585
                path = combinedPath(getServletPath(), path);
1✔
586
            }
587
            return _servletRequest.getServlet().getServletConfig().getServletContext().getRequestDispatcher(path);
1✔
588
        } catch (ServletException e) {
×
589
            return null;
×
590
        }
591
    }
592

593
    private String combinedPath(String basePath, String relativePath) {
594
        if (basePath.indexOf('/') < 0) {
1!
595
            return relativePath;
×
596
        }
597
        return basePath.substring(0, basePath.lastIndexOf('/')) + '/' + relativePath;
1✔
598
    }
599

600
    // --------------------------------- methods added to HttpServletRequest in Servlet API 2.2
601
    // ------------------------------------------------
602

603
    /**
604
     * Returns a java.security.Principal object containing the name of the current authenticated user. If the user has
605
     * not been authenticated, the method returns null.
606
     **/
607
    @Override
608
    public java.security.Principal getUserPrincipal() {
609
        return null;
×
610
    }
611

612
    /**
613
     * Returns a boolean indicating whether the authenticated user is included in the specified logical "role". Roles
614
     * and role membership can be defined using deployment descriptors. If the user has not been authenticated, the
615
     * method returns false.
616
     **/
617
    @Override
618
    public boolean isUserInRole(String role) {
619
        if (_roles == null) {
1✔
620
            return false;
1✔
621
        }
622
        for (String _role : _roles) {
1✔
623
            if (role.equals(_role)) {
1✔
624
                return true;
1✔
625
            }
626
        }
627
        return false;
1✔
628
    }
629

630
    /**
631
     * Returns all the values of the specified request header as an Enumeration of String objects.
632
     **/
633
    @Override
634
    public java.util.Enumeration getHeaders(String name) {
635
        Vector list = new Vector<>();
1✔
636
        if (_headers.containsKey(name)) {
1!
637
            list.add(_headers.get(name));
1✔
638
        }
639
        return list.elements();
1✔
640
    }
641

642
    /**
643
     * Returns the portion of the request URI that indicates the context of the request. The context path always comes
644
     * first in a request URI. The path starts with a "/" character but does not end with a "/" character. For servlets
645
     * in the default (root) context, this method returns "".
646
     **/
647
    @Override
648
    public String getContextPath() {
649
        return _context.getContextPath();
1✔
650
    }
651

652
    // --------------------------------------- methods added to ServletRequest in Servlet API 2.3
653
    // ----------------------------
654

655
    /**
656
     * Returns a java.util.Map of the parameters of this request. Request parameters are extra information sent with the
657
     * request. For HTTP servlets, parameters are contained in the query string or posted form data.
658
     **/
659
    @Override
660
    public Map getParameterMap() {
661
        return _requestContext.getParameterMap();
1✔
662
    }
663

664
    /**
665
     * Overrides the name of the character encoding used in the body of this request. This method must be called prior
666
     * to reading request parameters or reading input using getReader().
667
     **/
668
    @Override
669
    public void setCharacterEncoding(String charset) {
670
        _charset = charset;
1✔
671
        _requestContext.setMessageEncoding(charset);
1✔
672
    }
1✔
673

674
    // --------------------------------------- methods added to HttpServletRequest in Servlet API 2.3
675
    // ----------------------------
676

677
    /**
678
     * Reconstructs the URL the client used to make the request. The returned URL contains a protocol, server name, port
679
     * number, and server path, but it does not include query string parameters. Because this method returns a
680
     * StringBuffer, not a string, you can modify the URL easily, for example, to append query parameters. This method
681
     * is useful for creating redirect messages and for reporting errors.
682
     */
683
    @Override
684
    public StringBuffer getRequestURL() {
685
        StringBuilder url = new StringBuilder();
1✔
686
        try {
687
            url.append(_request.getURL().getProtocol()).append("://");
1✔
688
            url.append(_request.getURL().getHost());
1✔
689
            String portPortion = _request.getURL().getPort() == -1 ? "" : ":" + _request.getURL().getPort();
1✔
690
            url.append(portPortion);
1✔
691
            url.append(_request.getURL().getPath());
1✔
692
        } catch (MalformedURLException e) {
×
693
            throw new RuntimeException("unable to read URL from request: " + _request);
×
694
        }
1✔
695
        return new StringBuffer(url);
1✔
696
    }
697

698
    // --------------------------------------- methods added to ServletRequest in Servlet API 2.4
699
    // ----------------------------
700

701
    @Override
702
    public int getRemotePort() {
703
        return 0; // To change body of implemented methods use File | Settings | File Templates.
×
704
    }
705

706
    @Override
707
    public String getLocalName() {
708
        return "localhost";
×
709
    }
710

711
    @Override
712
    public String getLocalAddr() {
713
        return "127.0.0.1";
×
714
    }
715

716
    @Override
717
    public int getLocalPort() {
718
        return 0; // To change body of implemented methods use File | Settings | File Templates.
×
719
    }
720

721
    // --------------------------------------------- package members ----------------------------------------------
722

723
    private void addCookie(Cookie cookie) {
724
        _cookies.addElement(cookie);
1✔
725
        if (cookie.getName().equalsIgnoreCase(ServletUnitHttpSession.SESSION_COOKIE_NAME)) {
1✔
726
            _sessionID = cookie.getValue();
1✔
727
        }
728
    }
1✔
729

730
    private ServletUnitHttpSession getServletSession() {
731
        return (ServletUnitHttpSession) getSession();
1✔
732
    }
733

734
    void readFormAuthentication() {
735
        if (getSession( /* create */ false) != null) {
1✔
736
            recordAuthenticationInfo(getServletSession().getUserName(), getServletSession().getRoles());
1✔
737
        }
738
    }
1✔
739

740
    void readBasicAuthentication() {
741
        String authorizationHeader = (String) _headers.get("Authorization");
1✔
742

743
        if (authorizationHeader != null) {
1✔
744
            String userAndPassword = new String(Base64.getDecoder().decode(authorizationHeader
1✔
745
                    .substring(authorizationHeader.indexOf(' ') + 1).getBytes(StandardCharsets.UTF_8)),
1✔
746
                    StandardCharsets.UTF_8);
747
            int colonPos = userAndPassword.indexOf(':');
1✔
748
            recordAuthenticationInfo(userAndPassword.substring(0, colonPos),
1✔
749
                    toArray(userAndPassword.substring(colonPos + 1)));
1✔
750
        }
751
    }
1✔
752

753
    static String[] toArray(String roleList) {
754
        StringTokenizer st = new StringTokenizer(roleList, ",");
1✔
755
        String[] result = new String[st.countTokens()];
1✔
756
        for (int i = 0; i < result.length; i++) {
1✔
757
            result[i] = st.nextToken();
1✔
758
        }
759
        return result;
1✔
760
    }
761

762
    void recordAuthenticationInfo(String userName, String[] roles) {
763
        _userName = userName;
1✔
764
        _roles = roles;
1✔
765
    }
1✔
766

767
    // --------------------------------------------- private members ----------------------------------------------
768

769
    static final private String LOOPBACK_ADDRESS = "127.0.0.1";
770

771
    private WebRequest _request;
772
    private ServletMetaData _servletRequest;
773
    private WebClient.HeaderDictionary _headers;
774
    private ServletUnitContext _context;
775
    private ServletUnitHttpSession _session;
776
    private Hashtable _attributes = new Hashtable<>();
1✔
777
    private Vector _cookies = new Vector<>();
1✔
778
    private String _sessionID;
779
    private byte[] _messageBody;
780

781
    private String _userName;
782
    private String[] _roles;
783

784
    private void throwNotImplementedYet() {
785
        throw new RuntimeException("Not implemented yet");
×
786
    }
787

788
    private void setCookiesFromHeader(Dictionary clientHeaders) {
789
        String cookieHeader = (String) clientHeaders.get("Cookie");
1✔
790
        if (cookieHeader == null) {
1✔
791
            return;
1✔
792
        }
793

794
        StringTokenizer st = new StringTokenizer(cookieHeader, ",;=", true);
1✔
795
        String lastToken = st.nextToken();
1✔
796
        while (st.hasMoreTokens()) {
1✔
797
            String token = st.nextToken();
1✔
798
            if (token.equals("=") && st.hasMoreTokens()) {
1!
799
                addCookie(new Cookie(lastToken.trim(), st.nextToken().trim()));
1✔
800
            }
801
            lastToken = token;
1✔
802
        }
1✔
803
    }
1✔
804

805
    static class PrioritizedLocale implements Comparable {
806

807
        private Locale _locale;
808
        private float _priority;
809

810
        PrioritizedLocale(String languageSpec) {
1✔
811
            int semiIndex = languageSpec.indexOf(';');
1✔
812
            if (semiIndex < 0) {
1✔
813
                _priority = 1;
1✔
814
                _locale = parseLocale(languageSpec);
1✔
815
            } else {
816
                _priority = Float.parseFloat(languageSpec.substring(languageSpec.indexOf('=', semiIndex) + 1));
1✔
817
                _locale = parseLocale(languageSpec.substring(0, semiIndex));
1✔
818
            }
819
        }
1✔
820

821
        private Locale parseLocale(String range) {
822
            range = range.trim();
1✔
823
            int dashIndex = range.indexOf('-');
1✔
824
            if (dashIndex < 0) {
1✔
825
                return new Locale(range, "");
1✔
826
            }
827
            return new Locale(range.substring(0, dashIndex), range.substring(dashIndex + 1));
1✔
828
        }
829

830
        public Locale getLocale() {
831
            return _locale;
1✔
832
        }
833

834
        @Override
835
        public int compareTo(Object o) {
836
            if (!(o instanceof PrioritizedLocale)) {
1!
837
                throw new IllegalArgumentException("may only combine with other prioritized locales");
×
838
            }
839
            PrioritizedLocale other = (PrioritizedLocale) o;
1✔
840
            return _priority == other._priority ? _locale.getLanguage().compareTo(other._locale.getLanguage())
1!
841
                    : _priority < other._priority ? +1 : -1;
1✔
842
        }
843

844
    }
845

846
    @Override
847
    public ServletContext getServletContext() {
848
        try {
849
            return _servletRequest.getServlet().getServletConfig().getServletContext();
×
850
        } catch (ServletException e) {
×
851
            return null;
×
852
        }
853
    }
854

855
    @Override
856
    public AsyncContext startAsync() throws IllegalStateException {
857
        // TODO Auto-generated method stub
858
        return null;
×
859
    }
860

861
    @Override
862
    public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse)
863
            throws IllegalStateException {
864
        // TODO Auto-generated method stub
865
        return null;
×
866
    }
867

868
    @Override
869
    public boolean isAsyncStarted() {
870
        // TODO Auto-generated method stub
871
        return false;
×
872
    }
873

874
    @Override
875
    public boolean isAsyncSupported() {
876
        // TODO Auto-generated method stub
877
        return false;
×
878
    }
879

880
    @Override
881
    public AsyncContext getAsyncContext() {
882
        // TODO Auto-generated method stub
883
        return null;
×
884
    }
885

886
    @Override
887
    public DispatcherType getDispatcherType() {
888
        // TODO Auto-generated method stub
889
        return null;
×
890
    }
891

892
    @Override
893
    public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {
894
        // TODO Auto-generated method stub
895
        return false;
×
896
    }
897

898
    @Override
899
    public void login(String username, String password) throws ServletException {
900
        // TODO Auto-generated method stub
901

902
    }
×
903

904
    @Override
905
    public void logout() throws ServletException {
906
        // TODO Auto-generated method stub
907

908
    }
×
909

910
    @Override
911
    public Collection<Part> getParts() throws IOException, ServletException {
912
        // TODO Auto-generated method stub
913
        return null;
×
914
    }
915

916
    @Override
917
    public Part getPart(String name) throws IOException, ServletException {
918
        // TODO Auto-generated method stub
919
        return null;
×
920
    }
921

922
    @Override
923
    public long getContentLengthLong() {
924
        // TODO Auto-generated method stub
925
        return 0;
×
926
    }
927

928
    @Override
929
    public String changeSessionId() {
930
        // TODO Auto-generated method stub
931
        return null;
×
932
    }
933

934
    @Override
935
    public <T extends HttpUpgradeHandler> T upgrade(Class<T> handlerClass) throws IOException, ServletException {
936
        // TODO Auto-generated method stub
937
        return null;
×
938
    }
939

940
    @Override
941
    public String getRequestId() {
942
        // TODO Auto-generated method stub
943
        return null;
×
944
    }
945

946
    @Override
947
    public String getProtocolRequestId() {
948
        // TODO Auto-generated method stub
949
        return null;
×
950
    }
951

952
    @Override
953
    public ServletConnection getServletConnection() {
954
        // TODO Auto-generated method stub
955
        return null;
×
956
    }
957
}
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