001: /*
002: * @(#)URLConnection.java 1.36 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package sun.net.www;
029:
030: import java.net.URL;
031: import java.net.ContentHandler;
032: import java.util.*;
033: import java.io.InputStream;
034: import java.io.OutputStream;
035: import java.io.BufferedInputStream;
036: import java.net.UnknownServiceException;
037:
038: /**
039: * A class to represent an active connection to an object
040: * represented by a URL.
041: * @author James Gosling
042: */
043:
044: abstract public class URLConnection extends java.net.URLConnection {
045:
046: /** The URL that it is connected to */
047:
048: private String contentType;
049: private int contentLength = -1;
050:
051: protected MessageHeader properties;
052:
053: /** Create a URLConnection object. These should not be created directly:
054: instead they should be created by protocol handers in response to
055: URL.openConnection.
056: @param u The URL that this connects to.
057: */
058: public URLConnection(URL u) {
059: super (u);
060: properties = new MessageHeader();
061: }
062:
063: /** Call this routine to get the property list for this object.
064: * Properties (like content-type) that have explicit getXX() methods
065: * associated with them should be accessed using those methods. */
066: public MessageHeader getProperties() {
067: return properties;
068: }
069:
070: /** Call this routine to set the property list for this object. */
071: public void setProperties(MessageHeader properties) {
072: this .properties = properties;
073: }
074:
075: public void setRequestProperty(String key, String value) {
076: if (connected)
077: throw new IllegalAccessError("Already connected");
078: if (key == null)
079: throw new NullPointerException("key cannot be null");
080: properties.set(key, value);
081: }
082:
083: public String getHeaderField(String name) {
084: try {
085: getInputStream();
086: } catch (Exception e) {
087: return null;
088: }
089: return properties == null ? null : properties.findValue(name);
090: }
091:
092: /**
093: * Return the key for the nth header field. Returns null if
094: * there are fewer than n fields. This can be used to iterate
095: * through all the headers in the message.
096: */
097: public String getHeaderFieldKey(int n) {
098: try {
099: getInputStream();
100: } catch (Exception e) {
101: return null;
102: }
103: MessageHeader props = properties;
104: return props == null ? null : props.getKey(n);
105: }
106:
107: /**
108: * Return the value for the nth header field. Returns null if
109: * there are fewer than n fields. This can be used in conjunction
110: * with getHeaderFieldKey to iterate through all the headers in the message.
111: */
112: public String getHeaderField(int n) {
113: try {
114: getInputStream();
115: } catch (Exception e) {
116: return null;
117: }
118: MessageHeader props = properties;
119: return props == null ? null : props.getValue(n);
120: }
121:
122: /** Call this routine to get the content-type associated with this
123: * object.
124: */
125: public String getContentType() {
126: if (contentType == null)
127: contentType = getHeaderField("content-type");
128: if (contentType == null) {
129: String ct = null;
130: try {
131: ct = guessContentTypeFromStream(getInputStream());
132: } catch (java.io.IOException e) {
133: }
134: String ce = properties.findValue("content-encoding");
135: if (ct == null) {
136: ct = properties.findValue("content-type");
137:
138: if (ct == null)
139: if (url.getFile().endsWith("/"))
140: ct = "text/html";
141: else
142: ct = guessContentTypeFromName(url.getFile());
143: }
144:
145: /*
146: * If the Mime header had a Content-encoding field and its value
147: * was not one of the values that essentially indicate no
148: * encoding, we force the content type to be unknown. This will
149: * cause a save dialog to be presented to the user. It is not
150: * ideal but is better than what we were previously doing, namely
151: * bringing up an image tool for compressed tar files.
152: */
153:
154: if (ct == null
155: || ce != null
156: && !(ce.equalsIgnoreCase("7bit")
157: || ce.equalsIgnoreCase("8bit") || ce
158: .equalsIgnoreCase("binary")))
159: ct = "content/unknown";
160: contentType = ct;
161: }
162: return contentType;
163: }
164:
165: /**
166: * Set the content type of this URL to a specific value.
167: * @param type The content type to use. One of the
168: * content_* static variables in this
169: * class should be used.
170: * eg. setType(URL.content_html);
171: */
172: public void setContentType(String type) {
173: contentType = type;
174: }
175:
176: /** Call this routine to get the content-length associated with this
177: * object.
178: */
179: public int getContentLength() {
180: try {
181: getInputStream();
182: } catch (Exception e) {
183: return -1;
184: }
185: int l = contentLength;
186: if (l < 0) {
187: try {
188: l = Integer.parseInt(properties
189: .findValue("content-length"));
190: contentLength = l;
191: } catch (Exception e) {
192: }
193: }
194: return l;
195: }
196:
197: /** Call this routine to set the content-length associated with this
198: * object.
199: */
200: protected void setContentLength(int length) {
201: contentLength = length;
202: }
203:
204: /**
205: * Returns true if the data associated with this URL can be cached.
206: */
207: public boolean canCache() {
208: return url.getFile().indexOf('?') < 0;
209: }
210:
211: /**
212: * Call this to close the connection and flush any remaining data.
213: * Overriders must remember to call super.close()
214: */
215: public void close() {
216: url = null;
217: }
218: }
|