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

hazendaz / httpunit / 292

20 Apr 2025 09:03PM UTC coverage: 80.582% (+0.05%) from 80.53%
292

push

github

hazendaz
Merge remote-tracking branch 'origin/jakarta'

3231 of 4121 branches covered (78.4%)

Branch coverage included in aggregate %.

0 of 9 new or added lines in 3 files covered. (0.0%)

1 existing line in 1 file now uncovered.

8285 of 10170 relevant lines covered (81.47%)

0.81 hits per line

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

82.69
/src/main/java/com/meterware/servletunit/ServletUnitHttpRequest.java
1
/*
2
 * MIT License
3
 *
4
 * Copyright 2011-2024 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.Base64;
23
import com.meterware.httpunit.HttpUnitUtils;
24
import com.meterware.httpunit.WebClient;
25
import com.meterware.httpunit.WebRequest;
26

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

43
import java.io.BufferedReader;
44
import java.io.IOException;
45
import java.io.InputStreamReader;
46
import java.io.UnsupportedEncodingException;
47
import java.net.MalformedURLException;
48
import java.util.ArrayList;
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
/**
62
 * This class represents a servlet request created from a WebRequest.
63
 **/
64
class ServletUnitHttpRequest implements HttpServletRequest {
65

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

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

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

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

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

126
    // ----------------------------------------- HttpServletRequest methods --------------------------
127

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

315
    // --------------------------------- ServletRequest methods ----------------------------------------------------
316

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

734
    // --------------------------------------------- package members ----------------------------------------------
735

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

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

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

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

756
        if (authorizationHeader != null) {
1✔
757
            String userAndPassword = Base64.decode(authorizationHeader.substring(authorizationHeader.indexOf(' ') + 1));
1✔
758
            int colonPos = userAndPassword.indexOf(':');
1✔
759
            recordAuthenticationInfo(userAndPassword.substring(0, colonPos),
1✔
760
                    toArray(userAndPassword.substring(colonPos + 1)));
1✔
761
        }
762
    }
1✔
763

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

773
    void recordAuthenticationInfo(String userName, String[] roles) {
774
        _userName = userName;
1✔
775
        _roles = roles;
1✔
776
    }
1✔
777

778
    // --------------------------------------------- private members ----------------------------------------------
779

780
    final static private String LOOPBACK_ADDRESS = "127.0.0.1";
781

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

792
    private String _userName;
793
    private String[] _roles;
794

795
    private void throwNotImplementedYet() {
796
        throw new RuntimeException("Not implemented yet");
×
797
    }
798

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

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

816
    static class PrioritizedLocale implements Comparable {
817

818
        private Locale _locale;
819
        private float _priority;
820

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

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

841
        public Locale getLocale() {
842
            return _locale;
1✔
843
        }
844

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

855
    }
856

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

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

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

879
    @Override
880
    public boolean isAsyncStarted() {
881
        // TODO Auto-generated method stub
882
        return false;
×
883
    }
884

885
    @Override
886
    public boolean isAsyncSupported() {
887
        // TODO Auto-generated method stub
888
        return false;
×
889
    }
890

891
    @Override
892
    public AsyncContext getAsyncContext() {
893
        // TODO Auto-generated method stub
894
        return null;
×
895
    }
896

897
    @Override
898
    public DispatcherType getDispatcherType() {
899
        // TODO Auto-generated method stub
900
        return null;
×
901
    }
902

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

909
    @Override
910
    public void login(String username, String password) throws ServletException {
911
        // TODO Auto-generated method stub
912

913
    }
×
914

915
    @Override
916
    public void logout() throws ServletException {
917
        // TODO Auto-generated method stub
918

919
    }
×
920

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

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

933
    @Override
934
    public long getContentLengthLong() {
935
        // TODO Auto-generated method stub
936
        return 0;
×
937
    }
938

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

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

951
    @Override
952
    public String getRequestId() {
953
        // TODO Auto-generated method stub
NEW
954
        return null;
×
955
    }
956

957
    @Override
958
    public String getProtocolRequestId() {
959
        // TODO Auto-generated method stub
NEW
960
        return null;
×
961
    }
962

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