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

hazendaz / httpunit / 343

07 Jun 2025 08:37PM UTC coverage: 80.528% (-0.06%) from 80.591%
343

push

github

hazendaz
[ci] Remove old jakarta support note from readme as now mainline

3216 of 4105 branches covered (78.34%)

Branch coverage included in aggregate %.

8252 of 10136 relevant lines covered (81.41%)

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.io.UnsupportedEncodingException;
46
import java.net.MalformedURLException;
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.Locale;
58
import java.util.Map;
59
import java.util.StringTokenizer;
60
import java.util.Vector;
61

62
/**
63
 * This class represents a servlet request created from a WebRequest.
64
 **/
65
class ServletUnitHttpRequest implements HttpServletRequest {
66

67
    private ServletInputStreamImpl _inputStream;
68
    private Vector _locales;
69
    private String _protocol;
70
    private boolean _secure;
71
    private RequestContext _requestContext;
72
    private String _charset;
73
    private boolean _gotReader;
74
    private boolean _gotInputStream;
75
    private BufferedReader _reader;
76
    private int _serverPort;
77
    private String _serverName;
78

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

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

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

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

127
    // ----------------------------------------- HttpServletRequest methods --------------------------
128

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

300
    /**
301
     * Checks whether the requested session ID is still valid.
302
     **/
303
    @Override
304
    public boolean isRequestedSessionIdValid() {
305
        return false;
×
306
    }
307

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

316
    // --------------------------------- ServletRequest methods ----------------------------------------------------
317

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

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

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

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

367
    /**
368
     * initialize the inputStream
369
     */
370
    private void initializeInputStream() {
371
        if (_inputStream == null) {
1✔
372
            _inputStream = new ServletInputStreamImpl(_messageBody);
1✔
373
        }
374
    }
1✔
375

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

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

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

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

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

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

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

443
    /**
444
     * Returns the fully qualified name of the client that sent the request.
445
     **/
446
    @Override
447
    public String getRemoteHost() {
448
        return "localhost";
×
449
    }
450

451
    /**
452
     * Returns the host name of the server that received the request.
453
     **/
454
    @Override
455
    public String getServerName() {
456
        return _serverName;
1✔
457
    }
458

459
    /**
460
     * Returns the port number on which this request was received.
461
     **/
462
    @Override
463
    public int getServerPort() {
464
        return _serverPort;
1✔
465
    }
466

467
    /**
468
     * Returns the body of the request as a <code>BufferedReader</code> that translates character set encodings.
469
     *
470
     * @since [ 1221537 ] Patch: ServletUnitHttpRequest.getReader not implemented yet
471
     *
472
     * @author Tim - timmorrow (SourceForge)
473
     *
474
     * @return the reader
475
     **/
476
    @Override
477
    public BufferedReader getReader() throws IOException {
478
        if (_gotInputStream) {
1✔
479
            throw new IllegalStateException("getInputStream() has already been called on this request");
1✔
480
        }
481
        if (_reader == null) {
1✔
482
            initializeInputStream();
1✔
483
            String encoding = getCharacterEncoding();
1✔
484
            if (encoding == null) {
1!
485
                encoding = HttpUnitUtils.DEFAULT_CHARACTER_SET;
1✔
486
            }
487
            _reader = new BufferedReader(new InputStreamReader(_inputStream, encoding));
1✔
488
            _gotReader = true;
1✔
489
        }
490
        return _reader;
1✔
491
    }
492

493
    /**
494
     * Returns the Internet Protocol (IP) address of the client that sent the request.
495
     **/
496
    @Override
497
    public String getRemoteAddr() {
498
        return LOOPBACK_ADDRESS;
×
499
    }
500

501
    /**
502
     * Stores an attribute in the context of this request. Attributes are reset between requests.
503
     **/
504
    @Override
505
    public void setAttribute(String key, Object o) {
506
        if (o == null) {
1✔
507
            _attributes.remove(key);
1✔
508
        } else {
509
            _attributes.put(key, o);
1✔
510
        }
511
    }
1✔
512

513
    // --------------------------------- methods added to ServletRequest in Servlet API 2.2
514
    // ------------------------------------------------
515

516
    /**
517
     * Returns a boolean indicating whether this request was made using a secure channel, such as HTTPS.
518
     **/
519
    @Override
520
    public boolean isSecure() {
521
        return _secure;
1✔
522
    }
523

524
    /**
525
     * Returns the preferred Locale that the client will accept content in, based on the Accept-Language header. If the
526
     * client request doesn't provide an Accept-Language header, this method returns the default locale for the server.
527
     **/
528
    @Override
529
    public Locale getLocale() {
530
        return (Locale) getPreferredLocales().firstElement();
1✔
531
    }
532

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

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

571
    /**
572
     * Removes an attribute from this request. This method is not generally needed as attributes only persist as long as
573
     * the request is being handled.
574
     **/
575
    @Override
576
    public void removeAttribute(String name) {
577
        _attributes.remove(name);
×
578
    }
×
579

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

601
    private String combinedPath(String basePath, String relativePath) {
602
        if (basePath.indexOf('/') < 0) {
1!
603
            return relativePath;
×
604
        }
605
        return basePath.substring(0, basePath.lastIndexOf('/')) + '/' + relativePath;
1✔
606
    }
607

608
    // --------------------------------- methods added to HttpServletRequest in Servlet API 2.2
609
    // ------------------------------------------------
610

611
    /**
612
     * Returns a java.security.Principal object containing the name of the current authenticated user. If the user has
613
     * not been authenticated, the method returns null.
614
     **/
615
    @Override
616
    public java.security.Principal getUserPrincipal() {
617
        return null;
×
618
    }
619

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

638
    /**
639
     * Returns all the values of the specified request header as an Enumeration of String objects.
640
     **/
641
    @Override
642
    public java.util.Enumeration getHeaders(String name) {
643
        Vector list = new Vector<>();
1✔
644
        if (_headers.containsKey(name)) {
1!
645
            list.add(_headers.get(name));
1✔
646
        }
647
        return list.elements();
1✔
648
    }
649

650
    /**
651
     * Returns the portion of the request URI that indicates the context of the request. The context path always comes
652
     * first in a request URI. The path starts with a "/" character but does not end with a "/" character. For servlets
653
     * in the default (root) context, this method returns "".
654
     **/
655
    @Override
656
    public String getContextPath() {
657
        return _context.getContextPath();
1✔
658
    }
659

660
    // --------------------------------------- methods added to ServletRequest in Servlet API 2.3
661
    // ----------------------------
662

663
    /**
664
     * Returns a java.util.Map of the parameters of this request. Request parameters are extra information sent with the
665
     * request. For HTTP servlets, parameters are contained in the query string or posted form data.
666
     *
667
     * @since 1.3
668
     **/
669
    @Override
670
    public Map getParameterMap() {
671
        return _requestContext.getParameterMap();
1✔
672
    }
673

674
    /**
675
     * Overrides the name of the character encoding used in the body of this request. This method must be called prior
676
     * to reading request parameters or reading input using getReader().
677
     *
678
     * @since 1.3
679
     **/
680
    @Override
681
    public void setCharacterEncoding(String charset) throws UnsupportedEncodingException {
682
        _charset = charset;
1✔
683
        _requestContext.setMessageEncoding(charset);
1✔
684
    }
1✔
685

686
    // --------------------------------------- methods added to HttpServletRequest in Servlet API 2.3
687
    // ----------------------------
688

689
    /**
690
     * Reconstructs the URL the client used to make the request. The returned URL contains a protocol, server name, port
691
     * number, and server path, but it does not include query string parameters. Because this method returns a
692
     * StringBuffer, not a string, you can modify the URL easily, for example, to append query parameters. This method
693
     * is useful for creating redirect messages and for reporting errors.
694
     *
695
     * @since 1.3
696
     */
697
    @Override
698
    public StringBuffer getRequestURL() {
699
        StringBuilder url = new StringBuilder();
1✔
700
        try {
701
            url.append(_request.getURL().getProtocol()).append("://");
1✔
702
            url.append(_request.getURL().getHost());
1✔
703
            String portPortion = _request.getURL().getPort() == -1 ? "" : ":" + _request.getURL().getPort();
1✔
704
            url.append(portPortion);
1✔
705
            url.append(_request.getURL().getPath());
1✔
706
        } catch (MalformedURLException e) {
×
707
            throw new RuntimeException("unable to read URL from request: " + _request);
×
708
        }
1✔
709
        return new StringBuffer(url);
1✔
710
    }
711

712
    // --------------------------------------- methods added to ServletRequest in Servlet API 2.4
713
    // ----------------------------
714

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

720
    @Override
721
    public String getLocalName() {
722
        return "localhost";
×
723
    }
724

725
    @Override
726
    public String getLocalAddr() {
727
        return "127.0.0.1";
×
728
    }
729

730
    @Override
731
    public int getLocalPort() {
732
        return 0; // To change body of implemented methods use File | Settings | File Templates.
×
733
    }
734

735
    // --------------------------------------------- package members ----------------------------------------------
736

737
    private void addCookie(Cookie cookie) {
738
        _cookies.addElement(cookie);
1✔
739
        if (cookie.getName().equalsIgnoreCase(ServletUnitHttpSession.SESSION_COOKIE_NAME)) {
1✔
740
            _sessionID = cookie.getValue();
1✔
741
        }
742
    }
1✔
743

744
    private ServletUnitHttpSession getServletSession() {
745
        return (ServletUnitHttpSession) getSession();
1✔
746
    }
747

748
    void readFormAuthentication() {
749
        if (getSession( /* create */ false) != null) {
1✔
750
            recordAuthenticationInfo(getServletSession().getUserName(), getServletSession().getRoles());
1✔
751
        }
752
    }
1✔
753

754
    void readBasicAuthentication() {
755
        String authorizationHeader = (String) _headers.get("Authorization");
1✔
756

757
        if (authorizationHeader != null) {
1✔
758
            String userAndPassword = new String(Base64.getDecoder().decode(authorizationHeader
1✔
759
                    .substring(authorizationHeader.indexOf(' ') + 1).getBytes(StandardCharsets.UTF_8)),
1✔
760
                    StandardCharsets.UTF_8);
761
            int colonPos = userAndPassword.indexOf(':');
1✔
762
            recordAuthenticationInfo(userAndPassword.substring(0, colonPos),
1✔
763
                    toArray(userAndPassword.substring(colonPos + 1)));
1✔
764
        }
765
    }
1✔
766

767
    static String[] toArray(String roleList) {
768
        StringTokenizer st = new StringTokenizer(roleList, ",");
1✔
769
        String[] result = new String[st.countTokens()];
1✔
770
        for (int i = 0; i < result.length; i++) {
1✔
771
            result[i] = st.nextToken();
1✔
772
        }
773
        return result;
1✔
774
    }
775

776
    void recordAuthenticationInfo(String userName, String[] roles) {
777
        _userName = userName;
1✔
778
        _roles = roles;
1✔
779
    }
1✔
780

781
    // --------------------------------------------- private members ----------------------------------------------
782

783
    static final private String LOOPBACK_ADDRESS = "127.0.0.1";
784

785
    private WebRequest _request;
786
    private ServletMetaData _servletRequest;
787
    private WebClient.HeaderDictionary _headers;
788
    private ServletUnitContext _context;
789
    private ServletUnitHttpSession _session;
790
    private Hashtable _attributes = new Hashtable<>();
1✔
791
    private Vector _cookies = new Vector<>();
1✔
792
    private String _sessionID;
793
    private byte[] _messageBody;
794

795
    private String _userName;
796
    private String[] _roles;
797

798
    private void throwNotImplementedYet() {
799
        throw new RuntimeException("Not implemented yet");
×
800
    }
801

802
    private void setCookiesFromHeader(Dictionary clientHeaders) {
803
        String cookieHeader = (String) clientHeaders.get("Cookie");
1✔
804
        if (cookieHeader == null) {
1✔
805
            return;
1✔
806
        }
807

808
        StringTokenizer st = new StringTokenizer(cookieHeader, ",;=", true);
1✔
809
        String lastToken = st.nextToken();
1✔
810
        while (st.hasMoreTokens()) {
1✔
811
            String token = st.nextToken();
1✔
812
            if (token.equals("=") && st.hasMoreTokens()) {
1!
813
                addCookie(new Cookie(lastToken.trim(), st.nextToken().trim()));
1✔
814
            }
815
            lastToken = token;
1✔
816
        }
1✔
817
    }
1✔
818

819
    static class PrioritizedLocale implements Comparable {
820

821
        private Locale _locale;
822
        private float _priority;
823

824
        PrioritizedLocale(String languageSpec) {
1✔
825
            int semiIndex = languageSpec.indexOf(';');
1✔
826
            if (semiIndex < 0) {
1✔
827
                _priority = 1;
1✔
828
                _locale = parseLocale(languageSpec);
1✔
829
            } else {
830
                _priority = Float.parseFloat(languageSpec.substring(languageSpec.indexOf('=', semiIndex) + 1));
1✔
831
                _locale = parseLocale(languageSpec.substring(0, semiIndex));
1✔
832
            }
833
        }
1✔
834

835
        private Locale parseLocale(String range) {
836
            range = range.trim();
1✔
837
            int dashIndex = range.indexOf('-');
1✔
838
            if (dashIndex < 0) {
1✔
839
                return new Locale(range, "");
1✔
840
            }
841
            return new Locale(range.substring(0, dashIndex), range.substring(dashIndex + 1));
1✔
842
        }
843

844
        public Locale getLocale() {
845
            return _locale;
1✔
846
        }
847

848
        @Override
849
        public int compareTo(Object o) {
850
            if (!(o instanceof PrioritizedLocale)) {
1!
851
                throw new IllegalArgumentException("may only combine with other prioritized locales");
×
852
            }
853
            PrioritizedLocale other = (PrioritizedLocale) o;
1✔
854
            return _priority == other._priority ? _locale.getLanguage().compareTo(other._locale.getLanguage())
1!
855
                    : _priority < other._priority ? +1 : -1;
1✔
856
        }
857

858
    }
859

860
    @Override
861
    public ServletContext getServletContext() {
862
        try {
863
            return _servletRequest.getServlet().getServletConfig().getServletContext();
×
864
        } catch (ServletException e) {
×
865
            return null;
×
866
        }
867
    }
868

869
    @Override
870
    public AsyncContext startAsync() throws IllegalStateException {
871
        // TODO Auto-generated method stub
872
        return null;
×
873
    }
874

875
    @Override
876
    public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse)
877
            throws IllegalStateException {
878
        // TODO Auto-generated method stub
879
        return null;
×
880
    }
881

882
    @Override
883
    public boolean isAsyncStarted() {
884
        // TODO Auto-generated method stub
885
        return false;
×
886
    }
887

888
    @Override
889
    public boolean isAsyncSupported() {
890
        // TODO Auto-generated method stub
891
        return false;
×
892
    }
893

894
    @Override
895
    public AsyncContext getAsyncContext() {
896
        // TODO Auto-generated method stub
897
        return null;
×
898
    }
899

900
    @Override
901
    public DispatcherType getDispatcherType() {
902
        // TODO Auto-generated method stub
903
        return null;
×
904
    }
905

906
    @Override
907
    public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {
908
        // TODO Auto-generated method stub
909
        return false;
×
910
    }
911

912
    @Override
913
    public void login(String username, String password) throws ServletException {
914
        // TODO Auto-generated method stub
915

916
    }
×
917

918
    @Override
919
    public void logout() throws ServletException {
920
        // TODO Auto-generated method stub
921

922
    }
×
923

924
    @Override
925
    public Collection<Part> getParts() throws IOException, ServletException {
926
        // TODO Auto-generated method stub
927
        return null;
×
928
    }
929

930
    @Override
931
    public Part getPart(String name) throws IOException, ServletException {
932
        // TODO Auto-generated method stub
933
        return null;
×
934
    }
935

936
    @Override
937
    public long getContentLengthLong() {
938
        // TODO Auto-generated method stub
939
        return 0;
×
940
    }
941

942
    @Override
943
    public String changeSessionId() {
944
        // TODO Auto-generated method stub
945
        return null;
×
946
    }
947

948
    @Override
949
    public <T extends HttpUpgradeHandler> T upgrade(Class<T> handlerClass) throws IOException, ServletException {
950
        // TODO Auto-generated method stub
951
        return null;
×
952
    }
953

954
    @Override
955
    public String getRequestId() {
956
        // TODO Auto-generated method stub
957
        return null;
×
958
    }
959

960
    @Override
961
    public String getProtocolRequestId() {
962
        // TODO Auto-generated method stub
963
        return null;
×
964
    }
965

966
    @Override
967
    public ServletConnection getServletConnection() {
968
        // TODO Auto-generated method stub
969
        return null;
×
970
    }
971
}
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