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

hazendaz / httpunit / 313

26 Apr 2025 12:51AM UTC coverage: 80.503% (-0.03%) from 80.53%
313

push

github

hazendaz
Merge branch 'master' into javax

3231 of 4121 branches covered (78.4%)

Branch coverage included in aggregate %.

0 of 1 new or added line in 1 file covered. (0.0%)

3 existing lines in 2 files now uncovered.

8285 of 10184 relevant lines covered (81.35%)

0.81 hits per line

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

73.96
/src/main/java/com/meterware/servletunit/ServletUnitHttpResponse.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

24
import java.io.ByteArrayOutputStream;
25
import java.io.IOException;
26
import java.io.OutputStreamWriter;
27
import java.io.PrintWriter;
28
import java.io.UnsupportedEncodingException;
29
import java.text.SimpleDateFormat;
30
import java.util.ArrayList;
31
import java.util.Collection;
32
import java.util.Collections;
33
import java.util.Date;
34
import java.util.Enumeration;
35
import java.util.Hashtable;
36
import java.util.Iterator;
37
import java.util.Locale;
38
import java.util.Map;
39
import java.util.TimeZone;
40
import java.util.Vector;
41

42
import javax.servlet.ServletOutputStream;
43
import javax.servlet.WriteListener;
44
import javax.servlet.http.Cookie;
45
import javax.servlet.http.HttpServletResponse;
46

47
class ServletUnitHttpResponse implements HttpServletResponse {
1✔
48

49
    // rfc1123-date is "Sun, 06 Nov 1994 08:49:37 GMT"
50
    private static final String RFC1123_DATE_SPEC = "EEE, dd MMM yyyy HH:mm:ss z";
51
    private boolean _committed;
52
    private Locale _locale = Locale.getDefault();
1✔
53

54
    private static final Hashtable ENCODING_MAP = new Hashtable();
1✔
55

56
    /**
57
     * @deprecated Use encodeURL(String url)
58
     */
59
    @Deprecated
60
    @Override
61
    public String encodeUrl(String url) {
62
        return encodeURL(url);
×
63
    }
64

65
    /**
66
     * Adds the specified cookie to the response. It can be called multiple times to set more than one cookie.
67
     */
68
    @Override
69
    public void addCookie(Cookie cookie) {
70
        _cookies.addElement(cookie);
1✔
71
    }
1✔
72

73
    /**
74
     * Checks whether the response message header has a field with the specified name.
75
     */
76
    @Override
77
    public boolean containsHeader(String name) {
78
        return _headers.containsKey(name.toUpperCase());
1✔
79
    }
80

81
    /**
82
     * @deprecated Use encodeRedirectURL(String url)
83
     **/
84
    @Deprecated
85
    @Override
86
    public String encodeRedirectUrl(String url) {
87
        return encodeRedirectURL(url);
×
88
    }
89

90
    /**
91
     * Encodes the specified URL by including the session ID in it, or, if encoding is not needed, returns the URL
92
     * unchanged. The implementation of this method should include the logic to determine whether the session ID needs
93
     * to be encoded in the URL. For example, if the browser supports cookies, or session tracking is turned off, URL
94
     * encoding is unnecessary.
95
     **/
96
    @Override
97
    public String encodeURL(String url) {
98
        return url;
×
99
    }
100

101
    /**
102
     * Encodes the specified URL for use in the <code>sendRedirect</code> method or, if encoding is not needed, returns
103
     * the URL unchanged. The implementation of this method should include the logic to determine whether the session ID
104
     * needs to be encoded in the URL. Because the rules for making this determination differ from those used to decide
105
     * whether to encode a normal link, this method is seperate from the <code>encodeUrl</code> method.
106
     **/
107
    @Override
108
    public String encodeRedirectURL(String url) {
109
        return url;
×
110
    }
111

112
    /**
113
     * Sends a temporary redirect response to the client using the specified redirect location URL. The URL must be
114
     * absolute (for example, <code><em>https://hostname/path/file.html</em></code>). Relative URLs are not permitted
115
     * here.
116
     */
117
    @Override
118
    public void sendRedirect(String location) throws IOException {
119
        setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
1✔
120
        setHeader("Location", location);
1✔
121
    }
1✔
122

123
    /**
124
     * Sends an error response to the client using the specified status code and descriptive message. If setStatus has
125
     * previously been called, it is reset to the error status code. The message is sent as the body of an HTML page,
126
     * which is returned to the user to describe the problem. The page is sent with a default HTML header; the message
127
     * is enclosed in simple body tags (&lt;body&gt;&lt;/body&gt;).
128
     **/
129
    @Override
130
    public void sendError(int sc) throws IOException {
131
        sendError(sc, "");
×
132
    }
×
133

134
    /**
135
     * Sends an error response to the client using the specified status code and descriptive message. If setStatus has
136
     * previously been called, it is reset to the error status code. The message is sent as the body of an HTML page,
137
     * which is returned to the user to describe the problem. The page is sent with a default HTML header; the message
138
     * is enclosed in simple body tags (&lt;body&gt;&lt;/body&gt;).
139
     **/
140
    @Override
141
    public void sendError(int sc, String msg) throws IOException {
142
        setStatus(sc);
×
143
        _statusMessage = msg;
×
144

145
        _writer = null;
×
146
        _servletStream = null;
×
147

148
        setContentType("text/html");
×
149
        getWriter().println("<html><head><title>" + msg + "</title></head><body>" + msg + "</body></html>");
×
150
    }
×
151

152
    /**
153
     * Sets the status code for this response. This method is used to set the return status code when there is no error
154
     * (for example, for the status codes SC_OK or SC_MOVED_TEMPORARILY). If there is an error, the
155
     * <code>sendError</code> method should be used instead.
156
     **/
157
    @Override
158
    public void setStatus(int sc) {
159
        _status = sc;
1✔
160
    }
1✔
161

162
    /**
163
     * @deprecated As of version 2.1, due to ambiguous meaning of the message parameter. To set a status code use
164
     *             setStatus(int), to send an error with a description use sendError(int, String). Sets the status code
165
     *             and message for this response.
166
     **/
167
    @Deprecated
168
    @Override
169
    public void setStatus(int sc, String msg) {
170
        setStatus(sc);
×
171
    }
×
172

173
    /**
174
     * Adds a field to the response header with the given name and value. If the field had already been set, the new
175
     * value overwrites the previous one. The <code>containsHeader</code> method can be used to test for the presence of
176
     * a header before setting its value.
177
     **/
178
    @Override
179
    public void setHeader(String name, String value) {
180
        ArrayList values = new ArrayList();
1✔
181
        values.add(value);
1✔
182
        synchronized (_headers) {
1✔
183
            _headers.put(name.toUpperCase(), values);
1✔
184
        }
1✔
185
    }
1✔
186

187
    /**
188
     * Adds a field to the response header with the given name and integer value. If the field had already been set, the
189
     * new value overwrites the previous one. The <code>containsHeader</code> method can be used to test for the
190
     * presence of a header before setting its value.
191
     **/
192
    @Override
193
    public void setIntHeader(String name, int value) {
194
        setHeader(name, asHeaderValue(value));
1✔
195
    }
1✔
196

197
    /**
198
     * Adds a field to the response header with the given name and integer value. If the field had already been set, the
199
     * new value overwrites the previous one. The <code>containsHeader</code> method can be used to test for the
200
     * presence of a header before setting its value.
201
     **/
202
    public void setLongHeader(String name, long value) {
203
        setHeader(name, asHeaderLongValue(value));
×
204
    }
×
205

206
    private String asHeaderValue(int value) {
207
        return Integer.toString(value);
1✔
208
    }
209

210
    private String asHeaderLongValue(long value) {
211
        return Long.toString(value);
×
212
    }
213

214
    /**
215
     * Adds a field to the response header with the given name and date-valued field. The date is specified in terms of
216
     * milliseconds since the epoch. If the date field had already been set, the new value overwrites the previous one.
217
     * The <code>containsHeader</code> method can be used to test for the presence of a header before setting its value.
218
     **/
219
    @Override
220
    public void setDateHeader(String name, long date) {
221
        setHeader(name, asDateHeaderValue(date));
1✔
222
    }
1✔
223

224
    private String asDateHeaderValue(long date) {
225
        Date value = new Date(date);
1✔
226
        SimpleDateFormat formatter = new SimpleDateFormat(RFC1123_DATE_SPEC, Locale.US);
1✔
227
        formatter.setTimeZone(TimeZone.getTimeZone("Greenwich Mean Time"));
1✔
228
        return formatter.format(value);
1✔
229
    }
230

231
    /**
232
     * Returns the name of the character set encoding used for the MIME body sent by this response.
233
     **/
234
    @Override
235
    public String getCharacterEncoding() {
236
        return _encoding == null ? HttpUnitUtils.DEFAULT_CHARACTER_SET : _encoding;
1✔
237
    }
238

239
    /**
240
     * Sets the content type of the response the server sends to the client. The content type may include the type of
241
     * character encoding used, for example, <code>text/html; charset=ISO-8859-4</code>.
242
     * <p>
243
     * You can only use this method once, and you should call it before you obtain a <code>PrintWriter</code> or
244
     * {@link ServletOutputStream} object to return a response.
245
     **/
246
    @Override
247
    public void setContentType(String type) {
248
        String[] typeAndEncoding = HttpUnitUtils.parseContentTypeHeader(type);
1✔
249

250
        _contentType = typeAndEncoding[0];
1✔
251
        if (typeAndEncoding[1] != null) {
1✔
252
            _encoding = typeAndEncoding[1];
1✔
253
        }
254
    }
1✔
255

256
    /**
257
     * Returns a {@link ServletOutputStream} suitable for writing binary data in the response. The servlet engine does
258
     * not encode the binary data.
259
     *
260
     * @exception IllegalStateException
261
     *                if you have already called the <code>getWriter</code> method
262
     **/
263
    @Override
264
    public ServletOutputStream getOutputStream() throws IOException {
265
        if (_writer != null) {
1✔
266
            throw new IllegalStateException("Tried to create output stream; writer already exists");
1✔
267
        }
268
        if (_servletStream == null) {
1✔
269
            _outputStream = new ByteArrayOutputStream();
1✔
270
            _servletStream = new ServletUnitOutputStream(_outputStream);
1✔
271
        }
272
        return _servletStream;
1✔
273
    }
274

275
    /**
276
     * Returns a <code>PrintWriter</code> object that you can use to send character text to the client. The character
277
     * encoding used is the one specified in the <code>charset=</code> property of the {@link #setContentType} method,
278
     * which you must call <i>before</i> you call this method.
279
     * <p>
280
     * If necessary, the MIME type of the response is modified to reflect the character encoding used.
281
     * <p>
282
     * You cannot use this method if you have already called {@link #getOutputStream} for this
283
     * <code>ServletResponse</code> object.
284
     *
285
     * @exception UnsupportedEncodingException
286
     *                if the character encoding specified in <code>setContentType</code> cannot be used
287
     * @exception IllegalStateException
288
     *                if the <code>getOutputStream</code> method has already been called for this response object; in
289
     *                that case, you can't use this method
290
     **/
291
    @Override
292
    public PrintWriter getWriter() throws UnsupportedEncodingException {
293
        if (_servletStream != null) {
1✔
294
            throw new IllegalStateException("Tried to create writer; output stream already exists");
1✔
295
        }
296
        if (_writer == null) {
1✔
297
            _outputStream = new ByteArrayOutputStream();
1✔
298
            _writer = new PrintWriter(new OutputStreamWriter(_outputStream, getCharacterEncoding()));
1✔
299
        }
300
        return _writer;
1✔
301
    }
302

303
    /**
304
     * Sets the length of the content the server returns to the client. In HTTP servlets, this method sets the HTTP
305
     * Content-Length header.
306
     **/
307
    @Override
308
    public void setContentLength(int len) {
309
        setIntHeader("Content-Length", len);
1✔
310
    }
1✔
311

312
    // ------------------------------- the following methods are new in JSDK 2.2 ----------------------
313

314
    /**
315
     * Adds a response header with the given name and value. This method allows response headers to have multiple
316
     * values.
317
     **/
318
    @Override
319
    public void addHeader(String name, String value) {
320
        synchronized (_headers) {
1✔
321
            String key = name.toUpperCase();
1✔
322
            ArrayList values = (ArrayList) _headers.get(key);
1✔
323
            if (values == null) {
1✔
324
                values = new ArrayList();
1✔
325
                _headers.put(key, values);
1✔
326
            }
327
            values.add(value);
1✔
328
        }
1✔
329
    }
1✔
330

331
    /**
332
     * Adds a response header with the given name and value. This method allows response headers to have multiple
333
     * values.
334
     **/
335
    @Override
336
    public void addIntHeader(String name, int value) {
337
        addHeader(name, asHeaderValue(value));
1✔
338
    }
1✔
339

340
    /**
341
     * Adds a response header with the given name and value. This method allows response headers to have multiple
342
     * values.
343
     **/
344
    @Override
345
    public void addDateHeader(String name, long value) {
346
        addHeader(name, asDateHeaderValue(value));
1✔
347
    }
1✔
348

349
    /**
350
     * Sets the preferred buffer size for the body of the response. The servlet container will use a buffer at least as
351
     * large as the size requested. The actual buffer size used can be found using getBufferSize.
352
     **/
353
    @Override
354
    public void setBufferSize(int size) {
355
        if (getContents().length != 0) {
1✔
356
            throw new IllegalStateException("May not set buffer size after data is written");
1✔
357
        }
358
    }
1✔
359

360
    /**
361
     * Returns the actual buffer size used for the response. If no buffering is used, this method returns 0.
362
     **/
363
    @Override
364
    public int getBufferSize() {
365
        return 0;
×
366
    }
367

368
    /**
369
     * Returns a boolean indicating if the response has been committed. A committed response has already had its status
370
     * code and headers written.
371
     **/
372
    @Override
373
    public boolean isCommitted() {
374
        return _committed;
1✔
375
    }
376

377
    /**
378
     * Forces any content in the buffer to be written to the client. A call to this method automatically commits the
379
     * response, meaning the status code and headers will be written.
380
     **/
381
    @Override
382
    public void flushBuffer() throws IOException {
383
        _committed = true;
1✔
384
    }
1✔
385

386
    /**
387
     * Clears any data that exists in the buffer as well as the status code and headers. If the response has been
388
     * committed, this method throws an IllegalStateException.
389
     **/
390
    @Override
391
    public void reset() {
392
        resetBuffer();
1✔
393
        _headers.clear();
1✔
394
        _headersComplete = false;
1✔
395
        _status = SC_OK;
1✔
396
    }
1✔
397

398
    /**
399
     * Sets the locale of the response, setting the headers (including the Content-Type's charset) as appropriate. This
400
     * method should be called before a call to getWriter(). By default, the response locale is the default locale for
401
     * the server.
402
     **/
403
    @Override
404
    public void setLocale(Locale locale) {
405
        _locale = locale;
1✔
406
        if (_encoding == null) {
1!
407
            for (Iterator it = ENCODING_MAP.entrySet().iterator(); it.hasNext();) {
1!
408
                Map.Entry entry = (Map.Entry) it.next();
1✔
409
                String locales = (String) entry.getValue();
1✔
410
                if (locales.indexOf(locale.getLanguage()) >= 0 || locales.indexOf(locale.toString()) >= 0) {
1!
411
                    _encoding = (String) entry.getKey();
1✔
412
                    return;
1✔
413
                }
414
            }
1✔
415
        }
416
    }
×
417

418
    /**
419
     * Returns the locale assigned to the response.
420
     **/
421
    @Override
422
    public Locale getLocale() {
423
        return _locale;
1✔
424
    }
425

426
    // ----------------------------- methods added to ServletResponse in JSDK 2.3 --------------------------------------
427

428
    /**
429
     * Clears the content of the underlying buffer in the response without clearing headers or status code. If the
430
     * response has been committed, this method throws an IllegalStateException.
431
     *
432
     * @since 1.3
433
     */
434
    @Override
435
    public void resetBuffer() {
436
        if (_committed) {
1✔
437
            throw new IllegalStateException("May not resetBuffer after response is committed");
1✔
438
        }
439
        _outputStream = null;
1✔
440
        _servletStream = null;
1✔
441
        _writer = null;
1✔
442
    }
1✔
443

444
    // ---------------------------------------------- package methods --------------------------------------------------
445

446
    /**
447
     * Returns the contents of this response.
448
     **/
449
    byte[] getContents() {
450
        if (_outputStream == null) {
1✔
451
            return new byte[0];
1✔
452
        }
453
        if (_writer != null) {
1✔
454
            _writer.flush();
1✔
455
        }
456
        return _outputStream.toByteArray();
1✔
457
    }
458

459
    /**
460
     * Returns the status of this response.
461
     **/
462
    @Override
463
    public int getStatus() {
464
        return _status;
1✔
465
    }
466

467
    /**
468
     * Returns the message associated with this response's status.
469
     **/
470
    String getMessage() {
471
        return _statusMessage;
×
472
    }
473

474
    public String[] getHeaderFieldNames() {
475
        if (!_headersComplete) {
×
476
            completeHeaders();
×
477
        }
478
        Vector names = new Vector();
×
479
        for (Enumeration e = _headers.keys(); e.hasMoreElements();) {
×
480
            names.addElement(e.nextElement());
×
481
        }
482
        String[] result = new String[names.size()];
×
483
        names.copyInto(result);
×
484
        return result;
×
485
    }
486

487
    /**
488
     * Returns the headers defined for this response.
489
     *
490
     * @param name
491
     *            - the name of the field to get
492
     **/
493
    String getHeaderFieldDirect(String name) {
494
        ArrayList values;
495
        synchronized (_headers) {
1✔
496
            values = (ArrayList) _headers.get(name.toUpperCase());
1✔
497
        }
1✔
498

499
        return values == null ? null : (String) values.get(0);
1✔
500
    }
501

502
    /**
503
     * Returns the headers defined for this response.
504
     *
505
     * @param name
506
     **/
507
    String getHeaderField(String name) {
508
        if (!_headersComplete) {
1✔
509
            completeHeaders();
1✔
510
        }
511
        return getHeaderFieldDirect(name);
1✔
512
    }
513

514
    /**
515
     * Return an array of all the header values associated with the specified header name, or an zero-length array if
516
     * there are no such header values.
517
     *
518
     * @param name
519
     *            Header name to look up
520
     */
521
    public String[] getHeaderFields(String name) {
522
        if (!_headersComplete) {
1✔
523
            completeHeaders();
1✔
524
        }
525
        ArrayList values;
526
        synchronized (_headers) {
1✔
527
            values = (ArrayList) _headers.get(name.toUpperCase());
1✔
528
        }
1✔
529
        if (values == null) {
1✔
530
            return new String[0];
1✔
531
        }
532
        String results[] = new String[values.size()];
1✔
533
        return (String[]) values.toArray(results);
1✔
534

535
    }
536

537
    // --------------------------------------- methods added to ServletRequest in Servlet API 2.4
538
    // ----------------------------
539

540
    @Override
541
    public void setCharacterEncoding(String string) {
542
        _encoding = string;
×
543
    }
×
544

545
    /**
546
     * Returns the content type defined for this response.
547
     **/
548
    @Override
549
    public String getContentType() {
550
        return _contentType;
×
551
    }
552

553
    // ------------------------------------------- private members ------------------------------------
554

555
    private String _contentType = "text/plain";
1✔
556

557
    private String _encoding;
558

559
    private PrintWriter _writer;
560

561
    private ServletOutputStream _servletStream;
562

563
    private ByteArrayOutputStream _outputStream;
564

565
    private int _status = SC_OK;
1✔
566

567
    private String _statusMessage = "OK";
1✔
568

569
    private final Hashtable _headers = new Hashtable();
1✔
570

571
    private boolean _headersComplete;
572

573
    private Vector _cookies = new Vector();
1✔
574

575
    private void completeHeaders() {
576
        if (_headersComplete) {
1!
577
            return;
×
578
        }
579
        addCookieHeader();
1✔
580
        // BR 3301056 ServletUnit handling Content-Type incorrectly
581
        if (getHeaderFieldDirect("Content-Type") == null) {
1✔
582
            setHeader("Content-Type", _contentType + "; charset=" + getCharacterEncoding());
1✔
583
        }
584
        _headersComplete = true;
1✔
585
    }
1✔
586

587
    private void addCookieHeader() {
588
        if (_cookies.isEmpty()) {
1✔
589
            return;
1✔
590
        }
591

592
        StringBuilder sb = new StringBuilder();
1✔
593
        for (Enumeration e = _cookies.elements(); e.hasMoreElements();) {
1✔
594
            Cookie cookie = (Cookie) e.nextElement();
1✔
595
            sb.append(cookie.getName()).append('=').append(cookie.getValue());
1✔
596
            if (cookie.getPath() != null) {
1!
597
                sb.append(";path=").append(cookie.getPath());
1✔
598
            }
599
            if (cookie.getDomain() != null) {
1!
600
                sb.append(";domain=").append(cookie.getDomain());
×
601
            }
602
            if (e.hasMoreElements()) {
1!
603
                sb.append(',');
×
604
            }
605
        }
1✔
606
        setHeader("Set-Cookie", sb.toString());
1✔
607
    }
1✔
608

609
    static {
610
        ENCODING_MAP.put("iso-8859-1", "ca da de en es fi fr is it nl no pt sv ");
1✔
611
        ENCODING_MAP.put("iso-8859-2", "cs hr hu pl ro sh sk sl sq ");
1✔
612
        ENCODING_MAP.put("iso-8859-4", "et lt lv ");
1✔
613
        ENCODING_MAP.put("iso-8859-5", "be bg mk ru sr uk ");
1✔
614
        ENCODING_MAP.put("iso-8859-6", "ar ");
1✔
615
        ENCODING_MAP.put("iso-8859-7", "el ");
1✔
616
        ENCODING_MAP.put("iso-8859-8", "iw he ");
1✔
617
        ENCODING_MAP.put("iso-8859-9", "tr ");
1✔
618

619
        ENCODING_MAP.put("Shift_JIS", "ja ");
1✔
620
        ENCODING_MAP.put("EUC-KR", "ko ");
1✔
621
        ENCODING_MAP.put("TIS-620", "th ");
1✔
622
        ENCODING_MAP.put("GB2312", "zh ");
1✔
623
        ENCODING_MAP.put("Big5", "zh_TW zh_HK ");
1✔
624
    }
1✔
625

626
    @Override
627
    public String getHeader(String name) {
628
        return (String) _headers.get(name.toUpperCase());
×
629
    }
630

631
    @Override
632
    public Collection<String> getHeaders(String name) {
633
        ArrayList values;
634
        synchronized (_headers) {
×
635
            values = (ArrayList) _headers.get(name.toUpperCase());
×
636
        }
×
637
        if (values == null) {
×
638
            return Collections.EMPTY_LIST;
×
639
        }
640
        return values;
×
641
    }
642

643
    @Override
644
    public Collection<String> getHeaderNames() {
645
        if (!_headersComplete) {
×
646
            completeHeaders();
×
647
        }
648
        Vector names = new Vector();
×
649
        for (Enumeration e = _headers.keys(); e.hasMoreElements();) {
×
650
            names.addElement(e.nextElement());
×
651
        }
652
        return names;
×
653
    }
654

655
    @Override
656
    public void setContentLengthLong(long len) {
657
        setLongHeader("Content-Length", len);
×
658
    }
×
659

660
}
661

662
class ServletUnitOutputStream extends ServletOutputStream {
663

664
    ServletUnitOutputStream(ByteArrayOutputStream stream) {
1✔
665
        _stream = stream;
1✔
666
    }
1✔
667

668
    @Override
669
    public void write(int aByte) throws IOException {
670
        _stream.write(aByte);
1✔
671
    }
1✔
672

673
    private ByteArrayOutputStream _stream;
674

675
    @Override
676
    public boolean isReady() {
UNCOV
677
        return false;
×
678
    }
679

680
    @Override
681
    public void setWriteListener(WriteListener writeListener) {
682
        // Do nothing
683
    }
×
684
}
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