1/*
2 * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26/*
27 * NOTE: This class lives in the package sun.net.www.protocol.https.
28 * There is a copy in com.sun.net.ssl.internal.www.protocol.https for JSSE
29 * 1.0.2 compatibility. It is 100% identical except the package and extends
30 * lines. Any changes should be made to be class in sun.net.* and then copied
31 * to com.sun.net.*.
32 */
33
34// For both copies of the file, uncomment one line and comment the other
35package sun.net.www.protocol.https;
36// package com.sun.net.ssl.internal.www.protocol.https;
37
38import java.net.URL;
39import java.net.Proxy;
40import java.net.ProtocolException;
41import java.io.*;
42import javax.net.ssl.*;
43import java.security.Permission;
44import java.security.Principal;
45import java.util.Map;
46import java.util.List;
47import sun.net.www.http.HttpClient;
48
49/**
50 * A class to represent an HTTP connection to a remote object.
51 *
52 * Ideally, this class should subclass and inherit the http handler
53 * implementation, but it can't do so because that class have the
54 * wrong Java Type.  Thus it uses the delegate (aka, the
55 * Adapter/Wrapper design pattern) to reuse code from the http
56 * handler.
57 *
58 * Since it would use a delegate to access
59 * sun.net.www.protocol.http.HttpURLConnection functionalities, it
60 * needs to implement all public methods in it's super class and all
61 * the way to Object.
62 *
63 */
64
65// For both copies of the file, uncomment one line and comment the
66// other. The differences between the two copies are introduced for
67// plugin, and it is marked as such.
68public class HttpsURLConnectionImpl
69        extends javax.net.ssl.HttpsURLConnection {
70// public class HttpsURLConnectionOldImpl
71//      extends com.sun.net.ssl.HttpsURLConnection {
72
73    // NOTE: made protected for plugin so that subclass can set it.
74    protected DelegateHttpsURLConnection delegate;
75
76// For both copies of the file, uncomment one line and comment the other
77    HttpsURLConnectionImpl(URL u, Handler handler) throws IOException {
78//    HttpsURLConnectionOldImpl(URL u, Handler handler) throws IOException {
79        this(u, null, handler);
80    }
81
82// For both copies of the file, uncomment one line and comment the other
83    HttpsURLConnectionImpl(URL u, Proxy p, Handler handler) throws IOException {
84//    HttpsURLConnectionOldImpl(URL u, Proxy p, Handler handler) throws IOException {
85        super(u);
86        delegate = new DelegateHttpsURLConnection(url, p, handler, this);
87    }
88
89    // NOTE: introduced for plugin
90    // subclass needs to overwrite this to set delegate to
91    // the appropriate delegatee
92    protected HttpsURLConnectionImpl(URL u) throws IOException {
93        super(u);
94    }
95
96    /**
97     * Create a new HttpClient object, bypassing the cache of
98     * HTTP client objects/connections.
99     *
100     * @param url       the URL being accessed
101     */
102    protected void setNewClient(URL url) throws IOException {
103        delegate.setNewClient(url, false);
104    }
105
106    /**
107     * Obtain a HttpClient object. Use the cached copy if specified.
108     *
109     * @param url       the URL being accessed
110     * @param useCache  whether the cached connection should be used
111     *                  if present
112     */
113    protected void setNewClient(URL url, boolean useCache)
114            throws IOException {
115        delegate.setNewClient(url, useCache);
116    }
117
118    /**
119     * Create a new HttpClient object, set up so that it uses
120     * per-instance proxying to the given HTTP proxy.  This
121     * bypasses the cache of HTTP client objects/connections.
122     *
123     * @param url       the URL being accessed
124     * @param proxyHost the proxy host to use
125     * @param proxyPort the proxy port to use
126     */
127    protected void setProxiedClient(URL url, String proxyHost, int proxyPort)
128            throws IOException {
129        delegate.setProxiedClient(url, proxyHost, proxyPort);
130    }
131
132    /**
133     * Obtain a HttpClient object, set up so that it uses per-instance
134     * proxying to the given HTTP proxy. Use the cached copy of HTTP
135     * client objects/connections if specified.
136     *
137     * @param url       the URL being accessed
138     * @param proxyHost the proxy host to use
139     * @param proxyPort the proxy port to use
140     * @param useCache  whether the cached connection should be used
141     *                  if present
142     */
143    protected void setProxiedClient(URL url, String proxyHost, int proxyPort,
144            boolean useCache) throws IOException {
145        delegate.setProxiedClient(url, proxyHost, proxyPort, useCache);
146    }
147
148    /**
149     * Implements the HTTP protocol handler's "connect" method,
150     * establishing an SSL connection to the server as necessary.
151     */
152    public void connect() throws IOException {
153        delegate.connect();
154    }
155
156    /**
157     * Used by subclass to access "connected" variable.  Since we are
158     * delegating the actual implementation to "delegate", we need to
159     * delegate the access of "connected" as well.
160     */
161    protected boolean isConnected() {
162        return delegate.isConnected();
163    }
164
165    /**
166     * Used by subclass to access "connected" variable.  Since we are
167     * delegating the actual implementation to "delegate", we need to
168     * delegate the access of "connected" as well.
169     */
170    protected void setConnected(boolean conn) {
171        delegate.setConnected(conn);
172    }
173
174    /**
175     * Returns the cipher suite in use on this connection.
176     */
177    public String getCipherSuite() {
178        return delegate.getCipherSuite();
179    }
180
181    /**
182     * Returns the certificate chain the client sent to the
183     * server, or null if the client did not authenticate.
184     */
185    public java.security.cert.Certificate []
186        getLocalCertificates() {
187        return delegate.getLocalCertificates();
188    }
189
190    /**
191     * Returns the server's certificate chain, or throws
192     * SSLPeerUnverified Exception if
193     * the server did not authenticate.
194     */
195    public java.security.cert.Certificate []
196        getServerCertificates() throws SSLPeerUnverifiedException {
197        return delegate.getServerCertificates();
198    }
199
200    /**
201     * Returns the server's X.509 certificate chain, or null if
202     * the server did not authenticate.
203     *
204     * NOTE: This method is not necessary for the version of this class
205     * implementing javax.net.ssl.HttpsURLConnection, but provided for
206     * compatibility with the com.sun.net.ssl.HttpsURLConnection version.
207     */
208    public javax.security.cert.X509Certificate[] getServerCertificateChain() {
209        try {
210            return delegate.getServerCertificateChain();
211        } catch (SSLPeerUnverifiedException e) {
212            // this method does not throw an exception as declared in
213            // com.sun.net.ssl.HttpsURLConnection.
214            // Return null for compatibility.
215            return null;
216        }
217    }
218
219    /**
220     * Returns the principal with which the server authenticated itself,
221     * or throw a SSLPeerUnverifiedException if the server did not authenticate.
222     */
223    public Principal getPeerPrincipal()
224            throws SSLPeerUnverifiedException
225    {
226        return delegate.getPeerPrincipal();
227    }
228
229    /**
230     * Returns the principal the client sent to the
231     * server, or null if the client did not authenticate.
232     */
233    public Principal getLocalPrincipal()
234    {
235        return delegate.getLocalPrincipal();
236    }
237
238    /*
239     * Allowable input/output sequences:
240     * [interpreted as POST/PUT]
241     * - get output, [write output,] get input, [read input]
242     * - get output, [write output]
243     * [interpreted as GET]
244     * - get input, [read input]
245     * Disallowed:
246     * - get input, [read input,] get output, [write output]
247     */
248
249    public synchronized OutputStream getOutputStream() throws IOException {
250        return delegate.getOutputStream();
251    }
252
253    public synchronized InputStream getInputStream() throws IOException {
254        return delegate.getInputStream();
255    }
256
257    public InputStream getErrorStream() {
258        return delegate.getErrorStream();
259    }
260
261    /**
262     * Disconnect from the server.
263     */
264    public void disconnect() {
265        delegate.disconnect();
266    }
267
268    public boolean usingProxy() {
269        return delegate.usingProxy();
270    }
271
272    /**
273     * Returns an unmodifiable Map of the header fields.
274     * The Map keys are Strings that represent the
275     * response-header field names. Each Map value is an
276     * unmodifiable List of Strings that represents
277     * the corresponding field values.
278     *
279     * @return a Map of header fields
280     * @since 1.4
281     */
282    public Map<String,List<String>> getHeaderFields() {
283        return delegate.getHeaderFields();
284    }
285
286    /**
287     * Gets a header field by name. Returns null if not known.
288     * @param name the name of the header field
289     */
290    public String getHeaderField(String name) {
291        return delegate.getHeaderField(name);
292    }
293
294    /**
295     * Gets a header field by index. Returns null if not known.
296     * @param n the index of the header field
297     */
298    public String getHeaderField(int n) {
299        return delegate.getHeaderField(n);
300    }
301
302    /**
303     * Gets a header field by index. Returns null if not known.
304     * @param n the index of the header field
305     */
306    public String getHeaderFieldKey(int n) {
307        return delegate.getHeaderFieldKey(n);
308    }
309
310    /**
311     * Sets request property. If a property with the key already
312     * exists, overwrite its value with the new value.
313     * @param value the value to be set
314     */
315    public void setRequestProperty(String key, String value) {
316        delegate.setRequestProperty(key, value);
317    }
318
319    /**
320     * Adds a general request property specified by a
321     * key-value pair.  This method will not overwrite
322     * existing values associated with the same key.
323     *
324     * @param   key     the keyword by which the request is known
325     *                  (e.g., "<code>accept</code>").
326     * @param   value  the value associated with it.
327     * @see #getRequestProperties(java.lang.String)
328     * @since 1.4
329     */
330    public void addRequestProperty(String key, String value) {
331        delegate.addRequestProperty(key, value);
332    }
333
334    /**
335     * Overwrite super class method
336     */
337    public int getResponseCode() throws IOException {
338        return delegate.getResponseCode();
339    }
340
341    public String getRequestProperty(String key) {
342        return delegate.getRequestProperty(key);
343    }
344
345    /**
346     * Returns an unmodifiable Map of general request
347     * properties for this connection. The Map keys
348     * are Strings that represent the request-header
349     * field names. Each Map value is a unmodifiable List
350     * of Strings that represents the corresponding
351     * field values.
352     *
353     * @return  a Map of the general request properties for this connection.
354     * @throws IllegalStateException if already connected
355     * @since 1.4
356     */
357    public Map<String,List<String>> getRequestProperties() {
358        return delegate.getRequestProperties();
359    }
360
361    /*
362     * We support JDK 1.2.x so we can't count on these from JDK 1.3.
363     * We override and supply our own version.
364     */
365    public void setInstanceFollowRedirects(boolean shouldFollow) {
366        delegate.setInstanceFollowRedirects(shouldFollow);
367    }
368
369    public boolean getInstanceFollowRedirects() {
370        return delegate.getInstanceFollowRedirects();
371    }
372
373    public void setRequestMethod(String method) throws ProtocolException {
374        delegate.setRequestMethod(method);
375    }
376
377    public String getRequestMethod() {
378        return delegate.getRequestMethod();
379    }
380
381    public String getResponseMessage() throws IOException {
382        return delegate.getResponseMessage();
383    }
384
385    public long getHeaderFieldDate(String name, long Default) {
386        return delegate.getHeaderFieldDate(name, Default);
387    }
388
389    public Permission getPermission() throws IOException {
390        return delegate.getPermission();
391    }
392
393    public URL getURL() {
394        return delegate.getURL();
395    }
396
397    public int getContentLength() {
398        return delegate.getContentLength();
399    }
400
401    public long getContentLengthLong() {
402        return delegate.getContentLengthLong();
403    }
404
405    public String getContentType() {
406        return delegate.getContentType();
407    }
408
409    public String getContentEncoding() {
410        return delegate.getContentEncoding();
411    }
412
413    public long getExpiration() {
414        return delegate.getExpiration();
415    }
416
417    public long getDate() {
418        return delegate.getDate();
419    }
420
421    public long getLastModified() {
422        return delegate.getLastModified();
423    }
424
425    public int getHeaderFieldInt(String name, int Default) {
426        return delegate.getHeaderFieldInt(name, Default);
427    }
428
429    public long getHeaderFieldLong(String name, long Default) {
430        return delegate.getHeaderFieldLong(name, Default);
431    }
432
433    public Object getContent() throws IOException {
434        return delegate.getContent();
435    }
436
437    public Object getContent(Class[] classes) throws IOException {
438        return delegate.getContent(classes);
439    }
440
441    public String toString() {
442        return delegate.toString();
443    }
444
445    public void setDoInput(boolean doinput) {
446        delegate.setDoInput(doinput);
447    }
448
449    public boolean getDoInput() {
450        return delegate.getDoInput();
451    }
452
453    public void setDoOutput(boolean dooutput) {
454        delegate.setDoOutput(dooutput);
455    }
456
457    public boolean getDoOutput() {
458        return delegate.getDoOutput();
459    }
460
461    public void setAllowUserInteraction(boolean allowuserinteraction) {
462        delegate.setAllowUserInteraction(allowuserinteraction);
463    }
464
465    public boolean getAllowUserInteraction() {
466        return delegate.getAllowUserInteraction();
467    }
468
469    public void setUseCaches(boolean usecaches) {
470        delegate.setUseCaches(usecaches);
471    }
472
473    public boolean getUseCaches() {
474        return delegate.getUseCaches();
475    }
476
477    public void setIfModifiedSince(long ifmodifiedsince) {
478        delegate.setIfModifiedSince(ifmodifiedsince);
479    }
480
481    public long getIfModifiedSince() {
482        return delegate.getIfModifiedSince();
483    }
484
485    public boolean getDefaultUseCaches() {
486        return delegate.getDefaultUseCaches();
487    }
488
489    public void setDefaultUseCaches(boolean defaultusecaches) {
490        delegate.setDefaultUseCaches(defaultusecaches);
491    }
492
493    /*
494     * finalize (dispose) the delegated object.  Otherwise
495     * sun.net.www.protocol.http.HttpURLConnection's finalize()
496     * would have to be made public.
497     */
498    protected void finalize() throws Throwable {
499        delegate.dispose();
500    }
501
502    public boolean equals(Object obj) {
503        return delegate.equals(obj);
504    }
505
506    public int hashCode() {
507        return delegate.hashCode();
508    }
509
510    public void setConnectTimeout(int timeout) {
511        delegate.setConnectTimeout(timeout);
512    }
513
514    public int getConnectTimeout() {
515        return delegate.getConnectTimeout();
516    }
517
518    public void setReadTimeout(int timeout) {
519        delegate.setReadTimeout(timeout);
520    }
521
522    public int getReadTimeout() {
523        return delegate.getReadTimeout();
524    }
525
526    public void setFixedLengthStreamingMode (int contentLength) {
527        delegate.setFixedLengthStreamingMode(contentLength);
528    }
529
530    public void setFixedLengthStreamingMode(long contentLength) {
531        delegate.setFixedLengthStreamingMode(contentLength);
532    }
533
534    public void setChunkedStreamingMode (int chunklen) {
535        delegate.setChunkedStreamingMode(chunklen);
536    }
537}
538