|
Java example source code file (ExchangeImpl.java)
The ExchangeImpl.java Java example source code/* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.net.httpserver; import java.io.*; import java.net.*; import javax.net.ssl.*; import java.util.*; import java.util.logging.Logger; import java.text.*; import com.sun.net.httpserver.*; class ExchangeImpl { Headers reqHdrs, rspHdrs; Request req; String method; boolean writefinished; URI uri; HttpConnection connection; long reqContentLen; long rspContentLen; /* raw streams which access the socket directly */ InputStream ris; OutputStream ros; Thread thread; /* close the underlying connection when this exchange finished */ boolean close; boolean closed; boolean http10 = false; /* for formatting the Date: header */ private static final String pattern = "EEE, dd MMM yyyy HH:mm:ss zzz"; private static final TimeZone gmtTZ = TimeZone.getTimeZone("GMT"); private static final ThreadLocal<DateFormat> dateFormat = new ThreadLocal<DateFormat>() { @Override protected DateFormat initialValue() { DateFormat df = new SimpleDateFormat(pattern, Locale.US); df.setTimeZone(gmtTZ); return df; } }; private static final String HEAD = "HEAD"; /* streams which take care of the HTTP protocol framing * and are passed up to higher layers */ InputStream uis; OutputStream uos; LeftOverInputStream uis_orig; // uis may have be a user supplied wrapper PlaceholderOutputStream uos_orig; boolean sentHeaders; /* true after response headers sent */ Map<String,Object> attributes; int rcode = -1; HttpPrincipal principal; ServerImpl server; ExchangeImpl ( String m, URI u, Request req, long len, HttpConnection connection ) throws IOException { this.req = req; this.reqHdrs = req.headers(); this.rspHdrs = new Headers(); this.method = m; this.uri = u; this.connection = connection; this.reqContentLen = len; /* ros only used for headers, body written directly to stream */ this.ros = req.outputStream(); this.ris = req.inputStream(); server = getServerImpl(); server.startExchange(); } public Headers getRequestHeaders () { return new UnmodifiableHeaders (reqHdrs); } public Headers getResponseHeaders () { return rspHdrs; } public URI getRequestURI () { return uri; } public String getRequestMethod (){ return method; } public HttpContextImpl getHttpContext (){ return connection.getHttpContext(); } private boolean isHeadRequest() { return HEAD.equals(getRequestMethod()); } public void close () { if (closed) { return; } closed = true; /* close the underlying connection if, * a) the streams not set up yet, no response can be sent, or * b) if the wrapper output stream is not set up, or * c) if the close of the input/outpu stream fails */ try { if (uis_orig == null || uos == null) { connection.close(); return; } if (!uos_orig.isWrapped()) { connection.close(); return; } if (!uis_orig.isClosed()) { uis_orig.close(); } uos.close(); } catch (IOException e) { connection.close(); } } public InputStream getRequestBody () { if (uis != null) { return uis; } if (reqContentLen == -1L) { uis_orig = new ChunkedInputStream (this, ris); uis = uis_orig; } else { uis_orig = new FixedLengthInputStream (this, ris, reqContentLen); uis = uis_orig; } return uis; } LeftOverInputStream getOriginalInputStream () { return uis_orig; } public int getResponseCode () { return rcode; } public OutputStream getResponseBody () { /* TODO. Change spec to remove restriction below. Filters * cannot work with this restriction * * if (!sentHeaders) { * throw new IllegalStateException ("headers not sent"); * } */ if (uos == null) { uos_orig = new PlaceholderOutputStream (null); uos = uos_orig; } return uos; } /* returns the place holder stream, which is the stream * returned from the 1st call to getResponseBody() * The "real" ouputstream is then placed inside this */ PlaceholderOutputStream getPlaceholderResponseBody () { getResponseBody(); return uos_orig; } public void sendResponseHeaders (int rCode, long contentLen) throws IOException { if (sentHeaders) { throw new IOException ("headers already sent"); } this.rcode = rCode; String statusLine = "HTTP/1.1 "+rCode+Code.msg(rCode)+"\r\n"; OutputStream tmpout = new BufferedOutputStream (ros); PlaceholderOutputStream o = getPlaceholderResponseBody(); tmpout.write (bytes(statusLine, 0), 0, statusLine.length()); boolean noContentToSend = false; // assume there is content rspHdrs.set ("Date", dateFormat.get().format (new Date())); /* check for response type that is not allowed to send a body */ if ((rCode>=100 && rCode <200) /* informational */ ||(rCode == 204) /* no content */ ||(rCode == 304)) /* not modified */ { if (contentLen != -1) { Logger logger = server.getLogger(); String msg = "sendResponseHeaders: rCode = "+ rCode + ": forcing contentLen = -1"; logger.warning (msg); } contentLen = -1; } if (isHeadRequest()) { /* HEAD requests should not set a content length by passing it * through this API, but should instead manually set the required * headers.*/ if (contentLen >= 0) { final Logger logger = server.getLogger(); String msg = "sendResponseHeaders: being invoked with a content length for a HEAD request"; logger.warning (msg); } noContentToSend = true; contentLen = 0; } else { /* not a HEAD request */ if (contentLen == 0) { if (http10) { o.setWrappedStream (new UndefLengthOutputStream (this, ros)); close = true; } else { rspHdrs.set ("Transfer-encoding", "chunked"); o.setWrappedStream (new ChunkedOutputStream (this, ros)); } } else { if (contentLen == -1) { noContentToSend = true; contentLen = 0; } rspHdrs.set("Content-length", Long.toString(contentLen)); o.setWrappedStream (new FixedLengthOutputStream (this, ros, contentLen)); } } write (rspHdrs, tmpout); this.rspContentLen = contentLen; tmpout.flush() ; tmpout = null; sentHeaders = true; if (noContentToSend) { WriteFinishedEvent e = new WriteFinishedEvent (this); server.addEvent (e); closed = true; } server.logReply (rCode, req.requestLine(), null); } void write (Headers map, OutputStream os) throws IOException { Set<Map.Entry Other Java examples (source code examples)Here is a short list of links related to this Java ExchangeImpl.java source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.