src/jdk.httpserver/share/classes/sun/net/httpserver/ExchangeImpl.java
author michaelm
Fri, 19 Oct 2018 14:23:43 +0100
changeset 52196 420445d16008
parent 52023 d0c04d180a3b
child 53720 3e451bff6f7f
permissions -rw-r--r--
8211437: java.net.http.HttpClient hangs on 204 reply without Content-length 0 Reviewed-by: chegar, dfuchs
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
7668
d4a77089c587 6962318: Update copyright year
ohair
parents: 7271
diff changeset
     2
 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 5460
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 5460
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 5460
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 5460
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 5460
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.net.httpserver;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.io.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.net.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import javax.net.ssl.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.util.*;
41592
855537e5ad9c 8157965: update httpserver logging to use java.lang.System.Logger
dfuchs
parents: 25859
diff changeset
    32
import java.lang.System.Logger;
855537e5ad9c 8157965: update httpserver logging to use java.lang.System.Logger
dfuchs
parents: 25859
diff changeset
    33
import java.lang.System.Logger.Level;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.text.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import com.sun.net.httpserver.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
class ExchangeImpl {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
    Headers reqHdrs, rspHdrs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
    Request req;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
    String method;
7271
17d3fc18872d 6725892: Http server stability issues
michaelm
parents: 6003
diff changeset
    42
    boolean writefinished;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
    URI uri;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
    HttpConnection connection;
1511
65ddd8f149f3 6756771: com.sun.net.httpserver.HttpServer should handle POSTs larger than 2Gig
chegar
parents: 2
diff changeset
    45
    long reqContentLen;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
    long rspContentLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
    /* raw streams which access the socket directly */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
    InputStream ris;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
    OutputStream ros;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
    Thread thread;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
    /* close the underlying connection when this exchange finished */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
    boolean close;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
    boolean closed;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
    boolean http10 = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
    /* for formatting the Date: header */
6003
6aed6c9c974d 6967684: httpserver using a non thread-safe SimpleDateFormat
chegar
parents: 5506
diff changeset
    57
    private static final String pattern = "EEE, dd MMM yyyy HH:mm:ss zzz";
6aed6c9c974d 6967684: httpserver using a non thread-safe SimpleDateFormat
chegar
parents: 5506
diff changeset
    58
    private static final TimeZone gmtTZ = TimeZone.getTimeZone("GMT");
6aed6c9c974d 6967684: httpserver using a non thread-safe SimpleDateFormat
chegar
parents: 5506
diff changeset
    59
    private static final ThreadLocal<DateFormat> dateFormat =
6aed6c9c974d 6967684: httpserver using a non thread-safe SimpleDateFormat
chegar
parents: 5506
diff changeset
    60
         new ThreadLocal<DateFormat>() {
6aed6c9c974d 6967684: httpserver using a non thread-safe SimpleDateFormat
chegar
parents: 5506
diff changeset
    61
             @Override protected DateFormat initialValue() {
6aed6c9c974d 6967684: httpserver using a non thread-safe SimpleDateFormat
chegar
parents: 5506
diff changeset
    62
                 DateFormat df = new SimpleDateFormat(pattern, Locale.US);
6aed6c9c974d 6967684: httpserver using a non thread-safe SimpleDateFormat
chegar
parents: 5506
diff changeset
    63
                 df.setTimeZone(gmtTZ);
6aed6c9c974d 6967684: httpserver using a non thread-safe SimpleDateFormat
chegar
parents: 5506
diff changeset
    64
                 return df;
6aed6c9c974d 6967684: httpserver using a non thread-safe SimpleDateFormat
chegar
parents: 5506
diff changeset
    65
         }
6aed6c9c974d 6967684: httpserver using a non thread-safe SimpleDateFormat
chegar
parents: 5506
diff changeset
    66
     };
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
5460
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
    68
    private static final String HEAD = "HEAD";
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
    69
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
    /* streams which take care of the HTTP protocol framing
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
     * and are passed up to higher layers
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
    InputStream uis;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    OutputStream uos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
    LeftOverInputStream uis_orig; // uis may have be a user supplied wrapper
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    PlaceholderOutputStream uos_orig;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    boolean sentHeaders; /* true after response headers sent */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
    Map<String,Object> attributes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
    int rcode = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    HttpPrincipal principal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    ServerImpl server;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    ExchangeImpl (
1511
65ddd8f149f3 6756771: com.sun.net.httpserver.HttpServer should handle POSTs larger than 2Gig
chegar
parents: 2
diff changeset
    85
        String m, URI u, Request req, long len, HttpConnection connection
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
    ) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
        this.req = req;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
        this.reqHdrs = req.headers();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
        this.rspHdrs = new Headers();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
        this.method = m;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
        this.uri = u;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
        this.connection = connection;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
        this.reqContentLen = len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
        /* ros only used for headers, body written directly to stream */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
        this.ros = req.outputStream();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
        this.ris = req.inputStream();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
        server = getServerImpl();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
        server.startExchange();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
    public Headers getRequestHeaders () {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
        return new UnmodifiableHeaders (reqHdrs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    public Headers getResponseHeaders () {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
        return rspHdrs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
    public URI getRequestURI () {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
        return uri;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
    public String getRequestMethod (){
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
        return method;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    public HttpContextImpl getHttpContext (){
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
        return connection.getHttpContext();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
5460
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
   121
    private boolean isHeadRequest() {
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
   122
        return HEAD.equals(getRequestMethod());
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
   123
    }
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
   124
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
    public void close () {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
        if (closed) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
        closed = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
        /* close the underlying connection if,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
         * a) the streams not set up yet, no response can be sent, or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
         * b) if the wrapper output stream is not set up, or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
         * c) if the close of the input/outpu stream fails
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
            if (uis_orig == null || uos == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
                connection.close();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
            if (!uos_orig.isWrapped()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
                connection.close();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
            if (!uis_orig.isClosed()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
                uis_orig.close();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
            uos.close();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
        } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
            connection.close();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
    public InputStream getRequestBody () {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
        if (uis != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
            return uis;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
        }
1511
65ddd8f149f3 6756771: com.sun.net.httpserver.HttpServer should handle POSTs larger than 2Gig
chegar
parents: 2
diff changeset
   158
        if (reqContentLen == -1L) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
            uis_orig = new ChunkedInputStream (this, ris);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
            uis = uis_orig;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
            uis_orig = new FixedLengthInputStream (this, ris, reqContentLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
            uis = uis_orig;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
        return uis;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
    LeftOverInputStream getOriginalInputStream () {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
        return uis_orig;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
    public int getResponseCode () {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
        return rcode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
    public OutputStream getResponseBody () {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        /* TODO. Change spec to remove restriction below. Filters
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
         * cannot work with this restriction
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
         * if (!sentHeaders) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
         *    throw new IllegalStateException ("headers not sent");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
         * }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
        if (uos == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
            uos_orig = new PlaceholderOutputStream (null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
            uos = uos_orig;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
        return uos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
    /* returns the place holder stream, which is the stream
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
     * returned from the 1st call to getResponseBody()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
     * The "real" ouputstream is then placed inside this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
    PlaceholderOutputStream getPlaceholderResponseBody () {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
        getResponseBody();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
        return uos_orig;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
    public void sendResponseHeaders (int rCode, long contentLen)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
    throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
        if (sentHeaders) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
            throw new IOException ("headers already sent");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
        this.rcode = rCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
        String statusLine = "HTTP/1.1 "+rCode+Code.msg(rCode)+"\r\n";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
        OutputStream tmpout = new BufferedOutputStream (ros);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
        PlaceholderOutputStream o = getPlaceholderResponseBody();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
        tmpout.write (bytes(statusLine, 0), 0, statusLine.length());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
        boolean noContentToSend = false; // assume there is content
52023
d0c04d180a3b 8211420: com.sun.net.httpserver.HttpServer returns Content-length header for 204 response code
michaelm
parents: 50681
diff changeset
   213
        boolean noContentLengthHeader = false; // must not send Content-length is set
6003
6aed6c9c974d 6967684: httpserver using a non thread-safe SimpleDateFormat
chegar
parents: 5506
diff changeset
   214
        rspHdrs.set ("Date", dateFormat.get().format (new Date()));
4047
f5dcf30f9206 6886436: Lightwight HTTP Container (com.sun.* package) is unstable
michaelm
parents: 1639
diff changeset
   215
f5dcf30f9206 6886436: Lightwight HTTP Container (com.sun.* package) is unstable
michaelm
parents: 1639
diff changeset
   216
        /* check for response type that is not allowed to send a body */
f5dcf30f9206 6886436: Lightwight HTTP Container (com.sun.* package) is unstable
michaelm
parents: 1639
diff changeset
   217
f5dcf30f9206 6886436: Lightwight HTTP Container (com.sun.* package) is unstable
michaelm
parents: 1639
diff changeset
   218
        if ((rCode>=100 && rCode <200) /* informational */
f5dcf30f9206 6886436: Lightwight HTTP Container (com.sun.* package) is unstable
michaelm
parents: 1639
diff changeset
   219
            ||(rCode == 204)           /* no content */
f5dcf30f9206 6886436: Lightwight HTTP Container (com.sun.* package) is unstable
michaelm
parents: 1639
diff changeset
   220
            ||(rCode == 304))          /* not modified */
f5dcf30f9206 6886436: Lightwight HTTP Container (com.sun.* package) is unstable
michaelm
parents: 1639
diff changeset
   221
        {
f5dcf30f9206 6886436: Lightwight HTTP Container (com.sun.* package) is unstable
michaelm
parents: 1639
diff changeset
   222
            if (contentLen != -1) {
f5dcf30f9206 6886436: Lightwight HTTP Container (com.sun.* package) is unstable
michaelm
parents: 1639
diff changeset
   223
                Logger logger = server.getLogger();
f5dcf30f9206 6886436: Lightwight HTTP Container (com.sun.* package) is unstable
michaelm
parents: 1639
diff changeset
   224
                String msg = "sendResponseHeaders: rCode = "+ rCode
f5dcf30f9206 6886436: Lightwight HTTP Container (com.sun.* package) is unstable
michaelm
parents: 1639
diff changeset
   225
                    + ": forcing contentLen = -1";
41592
855537e5ad9c 8157965: update httpserver logging to use java.lang.System.Logger
dfuchs
parents: 25859
diff changeset
   226
                logger.log (Level.WARNING, msg);
4047
f5dcf30f9206 6886436: Lightwight HTTP Container (com.sun.* package) is unstable
michaelm
parents: 1639
diff changeset
   227
            }
f5dcf30f9206 6886436: Lightwight HTTP Container (com.sun.* package) is unstable
michaelm
parents: 1639
diff changeset
   228
            contentLen = -1;
52023
d0c04d180a3b 8211420: com.sun.net.httpserver.HttpServer returns Content-length header for 204 response code
michaelm
parents: 50681
diff changeset
   229
            noContentLengthHeader = (rCode != 304);
4047
f5dcf30f9206 6886436: Lightwight HTTP Container (com.sun.* package) is unstable
michaelm
parents: 1639
diff changeset
   230
        }
5460
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
   231
50681
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents: 47216
diff changeset
   232
        if (isHeadRequest() || rCode == 304) {
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents: 47216
diff changeset
   233
            /* HEAD requests or 304 responses should not set a content length by passing it
5460
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
   234
             * through this API, but should instead manually set the required
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
   235
             * headers.*/
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
   236
            if (contentLen >= 0) {
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
   237
                final Logger logger = server.getLogger();
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
   238
                String msg =
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
   239
                    "sendResponseHeaders: being invoked with a content length for a HEAD request";
41592
855537e5ad9c 8157965: update httpserver logging to use java.lang.System.Logger
dfuchs
parents: 25859
diff changeset
   240
                logger.log (Level.WARNING, msg);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
            }
5460
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
   242
            noContentToSend = true;
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
   243
            contentLen = 0;
50681
4254bed3c09d 8204679: HTTP Client refresh
chegar
parents: 47216
diff changeset
   244
        } else { /* not a HEAD request or 304 response */
5460
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
   245
            if (contentLen == 0) {
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
   246
                if (http10) {
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
   247
                    o.setWrappedStream (new UndefLengthOutputStream (this, ros));
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
   248
                    close = true;
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
   249
                } else {
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
   250
                    rspHdrs.set ("Transfer-encoding", "chunked");
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
   251
                    o.setWrappedStream (new ChunkedOutputStream (this, ros));
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
   252
                }
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
   253
            } else {
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
   254
                if (contentLen == -1) {
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
   255
                    noContentToSend = true;
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
   256
                    contentLen = 0;
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
   257
                }
52196
420445d16008 8211437: java.net.http.HttpClient hangs on 204 reply without Content-length 0
michaelm
parents: 52023
diff changeset
   258
                if (!noContentLengthHeader) {
52023
d0c04d180a3b 8211420: com.sun.net.httpserver.HttpServer returns Content-length header for 204 response code
michaelm
parents: 50681
diff changeset
   259
                    rspHdrs.set("Content-length", Long.toString(contentLen));
d0c04d180a3b 8211420: com.sun.net.httpserver.HttpServer returns Content-length header for 204 response code
michaelm
parents: 50681
diff changeset
   260
                }
5460
0682ab146d05 6886723: light weight http server doesn't return correct status code for HEAD requests
chegar
parents: 4047
diff changeset
   261
                o.setWrappedStream (new FixedLengthOutputStream (this, ros, contentLen));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
        write (rspHdrs, tmpout);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
        this.rspContentLen = contentLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
        tmpout.flush() ;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
        tmpout = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
        sentHeaders = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
        if (noContentToSend) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
            WriteFinishedEvent e = new WriteFinishedEvent (this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
            server.addEvent (e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
            closed = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
        server.logReply (rCode, req.requestLine(), null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
    void write (Headers map, OutputStream os) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
        Set<Map.Entry<String,List<String>>> entries = map.entrySet();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
        for (Map.Entry<String,List<String>> entry : entries) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
            String key = entry.getKey();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
            byte[] buf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
            List<String> values = entry.getValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
            for (String val : values) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
                int i = key.length();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
                buf = bytes (key, 2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
                buf[i++] = ':';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
                buf[i++] = ' ';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
                os.write (buf, 0, i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
                buf = bytes (val, 2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
                i = val.length();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
                buf[i++] = '\r';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
                buf[i++] = '\n';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
                os.write (buf, 0, i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
        os.write ('\r');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
        os.write ('\n');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
    private byte[] rspbuf = new byte [128]; // used by bytes()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
     * convert string to byte[], using rspbuf
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
     * Make sure that at least "extra" bytes are free at end
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
     * of rspbuf. Reallocate rspbuf if not big enough.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
     * caller must check return value to see if rspbuf moved
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
    private byte[] bytes (String s, int extra) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
        int slen = s.length();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
        if (slen+extra > rspbuf.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
            int diff = slen + extra - rspbuf.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
            rspbuf = new byte [2* (rspbuf.length + diff)];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
        char c[] = s.toCharArray();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
        for (int i=0; i<c.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
            rspbuf[i] = (byte)c[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
        return rspbuf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
    public InetSocketAddress getRemoteAddress (){
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
        Socket s = connection.getChannel().socket();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
        InetAddress ia = s.getInetAddress();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
        int port = s.getPort();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
        return new InetSocketAddress (ia, port);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
    public InetSocketAddress getLocalAddress (){
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
        Socket s = connection.getChannel().socket();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
        InetAddress ia = s.getLocalAddress();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
        int port = s.getLocalPort();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
        return new InetSocketAddress (ia, port);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
    public String getProtocol (){
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
        String reqline = req.requestLine();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
        int index = reqline.lastIndexOf (' ');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
        return reqline.substring (index+1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
    public SSLSession getSSLSession () {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
        SSLEngine e = connection.getSSLEngine();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
        if (e == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
        return e.getSession();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
    public Object getAttribute (String name) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
        if (name == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
            throw new NullPointerException ("null name parameter");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
        if (attributes == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
            attributes = getHttpContext().getAttributes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
        return attributes.get (name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
    public void setAttribute (String name, Object value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
        if (name == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
            throw new NullPointerException ("null name parameter");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
        if (attributes == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
            attributes = getHttpContext().getAttributes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
        attributes.put (name, value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
    public void setStreams (InputStream i, OutputStream o) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
        assert uis != null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
        if (i != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
            uis = i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
        if (o != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
            uos = o;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
     * PP
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
    HttpConnection getConnection () {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
        return connection;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
    ServerImpl getServerImpl () {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
        return getHttpContext().getServerImpl();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
    public HttpPrincipal getPrincipal () {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
        return principal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
    void setPrincipal (HttpPrincipal principal) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
        this.principal = principal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
    static ExchangeImpl get (HttpExchange t) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
        if (t instanceof HttpExchangeImpl) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
            return ((HttpExchangeImpl)t).getExchangeImpl();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
            assert t instanceof HttpsExchangeImpl;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
            return ((HttpsExchangeImpl)t).getExchangeImpl();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
 * An OutputStream which wraps another stream
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
 * which is supplied either at creation time, or sometime later.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
 * If a caller/user tries to write to this stream before
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
 * the wrapped stream has been provided, then an IOException will
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
 * be thrown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
class PlaceholderOutputStream extends java.io.OutputStream {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
    OutputStream wrapped;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
    PlaceholderOutputStream (OutputStream os) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
        wrapped = os;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
    void setWrappedStream (OutputStream os) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
        wrapped = os;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
    boolean isWrapped () {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
        return wrapped != null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
    private void checkWrap () throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
        if (wrapped == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
            throw new IOException ("response headers not sent yet");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
    public void write(int b) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
        checkWrap();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
        wrapped.write (b);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
    public void write(byte b[]) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
        checkWrap();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
        wrapped.write (b);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
    public void write(byte b[], int off, int len) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
        checkWrap();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
        wrapped.write (b, off, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
    public void flush() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
        checkWrap();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
        wrapped.flush();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
    public void close() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
        checkWrap();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
        wrapped.close();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
}