OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [java/] [net/] [protocol/] [http/] [HTTPURLConnection.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* HTTPURLConnection.java --
2
   Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package gnu.java.net.protocol.http;
40
 
41
import gnu.classpath.SystemProperties;
42
 
43
import java.io.ByteArrayOutputStream;
44
import java.io.FileNotFoundException;
45
import java.io.IOException;
46
import java.io.InputStream;
47
import java.io.OutputStream;
48
import java.net.ProtocolException;
49
import java.net.URL;
50
import java.security.cert.Certificate;
51
import java.util.Collections;
52
import java.util.Date;
53
import java.util.List;
54
import java.util.Map;
55
 
56
import javax.net.ssl.HandshakeCompletedEvent;
57
import javax.net.ssl.HandshakeCompletedListener;
58
import javax.net.ssl.HttpsURLConnection;
59
import javax.net.ssl.SSLPeerUnverifiedException;
60
import javax.net.ssl.SSLSocketFactory;
61
 
62
/**
63
 * A URLConnection that uses the HTTPConnection class.
64
 *
65
 * @author Chris Burdess (dog@gnu.org)
66
 */
67
public class HTTPURLConnection
68
 extends HttpsURLConnection
69
  implements HandshakeCompletedListener
70
{
71
  /*
72
   * The underlying connection.
73
   */
74
  private HTTPConnection connection;
75
 
76
  // These are package private for use in anonymous inner classes.
77
  String proxyHostname;
78
  int proxyPort = -1;
79
  String agent;
80
  boolean keepAlive;
81
 
82
  private Request request;
83
  private Headers requestHeaders;
84
  private ByteArrayOutputStream requestSink;
85
  private boolean requestMethodSetExplicitly;
86
 
87
  private Response response;
88
  private InputStream responseSink;
89
  private InputStream errorSink;
90
 
91
  private HandshakeCompletedEvent handshakeEvent;
92
 
93
  /**
94
   * Constructor.
95
   * @param url the URL
96
   */
97
  public HTTPURLConnection(URL url)
98
    throws IOException
99
  {
100
    super(url);
101
    requestHeaders = new Headers();
102
    String proxy = SystemProperties.getProperty("http.proxyHost");
103
    if (proxy != null && proxy.length() > 0)
104
      {
105
        String port = SystemProperties.getProperty("http.proxyPort");
106
        if (port != null && port.length() > 0)
107
          {
108
            try
109
              {
110
                proxyPort = Integer.parseInt(port);
111
                proxyHostname = proxy;
112
              }
113
            catch (NumberFormatException _)
114
              {
115
                // Ignore.
116
              }
117
          }
118
      }
119
    agent = SystemProperties.getProperty("http.agent");
120
    String ka = SystemProperties.getProperty("http.keepAlive");
121
    keepAlive = !(ka != null && "false".equals(ka));
122
  }
123
 
124
  public void connect()
125
    throws IOException
126
  {
127
    if (connected)
128
      {
129
        return;
130
      }
131
    String protocol = url.getProtocol();
132
    boolean secure = "https".equals(protocol);
133
    String host = url.getHost();
134
    int port = url.getPort();
135
    if (port < 0)
136
      {
137
        port = secure ? HTTPConnection.HTTPS_PORT :
138
          HTTPConnection.HTTP_PORT;
139
      }
140
    String file = url.getFile();
141
    String username = url.getUserInfo();
142
    String password = null;
143
    if (username != null)
144
      {
145
        int ci = username.indexOf(':');
146
        if (ci != -1)
147
          {
148
            password = username.substring(ci + 1);
149
            username = username.substring(0, ci);
150
          }
151
      }
152
    final Credentials creds = (username == null) ? null :
153
      new Credentials (username, password);
154
 
155
    if ("POST".equals(method))
156
      {
157
        String contentType = requestHeaders.getValue("Content-Type");
158
        if (null == contentType)
159
          requestHeaders.addValue("Content-Type",
160
                                  "application/x-www-form-urlencoded");
161
      }
162
 
163
    boolean retry;
164
    do
165
      {
166
        retry = false;
167
        if (connection == null)
168
          {
169
            connection = getConnection(host, port, secure);
170
            if (secure)
171
              {
172
                SSLSocketFactory factory = getSSLSocketFactory();
173
                // FIXME: use the verifier
174
                // HostnameVerifier verifier = getHostnameVerifier();
175
                if (factory != null)
176
                  {
177
                    connection.setSSLSocketFactory(factory);
178
                  }
179
                connection.addHandshakeCompletedListener(this);
180
                // TODO verifier
181
              }
182
          }
183
        if (proxyHostname != null)
184
          {
185
            if (proxyPort < 0)
186
              {
187
                proxyPort = secure ? HTTPConnection.HTTPS_PORT :
188
                  HTTPConnection.HTTP_PORT;
189
              }
190
            connection.setProxy(proxyHostname, proxyPort);
191
          }
192
        try
193
          {
194
            request = connection.newRequest(method, file);
195
            if (!keepAlive)
196
              {
197
                request.setHeader("Connection", "close");
198
              }
199
            if (agent != null)
200
              {
201
                request.setHeader("User-Agent", agent);
202
              }
203
            request.getHeaders().putAll(requestHeaders);
204
            if (requestSink != null)
205
              {
206
                byte[] content = requestSink.toByteArray();
207
                RequestBodyWriter writer = new ByteArrayRequestBodyWriter(content);
208
                request.setRequestBodyWriter(writer);
209
              }
210
            if (creds != null)
211
              {
212
                request.setAuthenticator(new Authenticator() {
213
                    public Credentials getCredentials(String realm, int attempts)
214
                    {
215
                      return (attempts < 2) ? creds : null;
216
                    }
217
                  });
218
              }
219
            response = request.dispatch();
220
          }
221
        catch (IOException ioe)
222
          {
223
            if (connection.useCount > 0)
224
              {
225
                // Connection re-use failed: Try a new connection.
226
                try
227
                  {
228
                    connection.close();
229
                  }
230
                catch (IOException _)
231
                  {
232
                    // Ignore.
233
                  }
234
                connection = null;
235
                retry = true;
236
                continue;
237
              }
238
            else
239
              {
240
                // First time the connection was used: Hard failure.
241
                throw ioe;
242
              }
243
          }
244
 
245
        if (response.isRedirect() && getInstanceFollowRedirects())
246
          {
247
            // Read the response body, if there is one.  If the
248
            // redirect points us back at the same server, we will use
249
            // the cached connection, so we must make sure there is no
250
            // pending data in it.
251
            InputStream body = response.getBody();
252
            if (body != null)
253
              {
254
                byte[] ignore = new byte[1024];
255
                while (true)
256
                  {
257
                    int n = body.read(ignore, 0, ignore.length);
258
                    if (n == -1)
259
                      break;
260
                  }
261
              }
262
 
263
            // Follow redirect
264
            String location = response.getHeader("Location");
265
            if (location != null)
266
              {
267
                String connectionUri = connection.getURI();
268
                int start = connectionUri.length();
269
                if (location.startsWith(connectionUri) &&
270
                    location.charAt(start) == '/')
271
                  {
272
                    file = location.substring(start);
273
                    retry = true;
274
                  }
275
                else if (location.startsWith("http:"))
276
                  {
277
                    connection.close();
278
                    connection = null;
279
                    secure = false;
280
                    start = 7;
281
                    int end = location.indexOf('/', start);
282
                    if (end == -1)
283
                      end = location.length();
284
                    host = location.substring(start, end);
285
                    int ci = host.lastIndexOf(':');
286
                    if (ci != -1)
287
                      {
288
                        port = Integer.parseInt(host.substring (ci + 1));
289
                        host = host.substring(0, ci);
290
                      }
291
                    else
292
                      {
293
                        port = HTTPConnection.HTTP_PORT;
294
                      }
295
                    file = location.substring(end);
296
                    retry = true;
297
                  }
298
                else if (location.startsWith("https:"))
299
                  {
300
                    connection.close();
301
                    connection = null;
302
                    secure = true;
303
                    start = 8;
304
                    int end = location.indexOf('/', start);
305
                    if (end == -1)
306
                      end = location.length();
307
                    host = location.substring(start, end);
308
                    int ci = host.lastIndexOf(':');
309
                    if (ci != -1)
310
                      {
311
                        port = Integer.parseInt(host.substring (ci + 1));
312
                        host = host.substring(0, ci);
313
                      }
314
                    else
315
                      {
316
                        port = HTTPConnection.HTTPS_PORT;
317
                      }
318
                    file = location.substring(end);
319
                    retry = true;
320
                  }
321
                else if (location.length() > 0)
322
                  {
323
                    // Malformed absolute URI, treat as file part of URI
324
                    if (location.charAt(0) == '/')
325
                      {
326
                        // Absolute path
327
                        file = location;
328
                      }
329
                    else
330
                      {
331
                        // Relative path
332
                        int lsi = file.lastIndexOf('/');
333
                        file = (lsi == -1) ? "/" : file.substring(0, lsi + 1);
334
                    file += location;
335
                      }
336
                    retry = true;
337
                  }
338
              }
339
          }
340
        else
341
          {
342
            responseSink = response.getBody();
343
 
344
            if (response.isError())
345
              errorSink = responseSink;
346
          }
347
      }
348
    while (retry);
349
    connected = true;
350
  }
351
 
352
  /**
353
   * Returns a connection, from the pool if necessary.
354
   */
355
  HTTPConnection getConnection(String host, int port, boolean secure)
356
    throws IOException
357
  {
358
    HTTPConnection connection;
359
    if (keepAlive)
360
      {
361
        connection = HTTPConnection.Pool.instance.get(host, port, secure,
362
                                                      getConnectTimeout(),
363
                                                      getReadTimeout());
364
      }
365
    else
366
      {
367
        connection = new HTTPConnection(host, port, secure,
368
                                        getConnectTimeout(), getReadTimeout());
369
      }
370
    return connection;
371
  }
372
 
373
  public void disconnect()
374
  {
375
    if (connection != null)
376
      {
377
        try
378
          {
379
            connection.close();
380
          }
381
        catch (IOException e)
382
          {
383
          }
384
      }
385
  }
386
 
387
  public boolean usingProxy()
388
  {
389
    return (proxyHostname != null);
390
  }
391
 
392
  /**
393
   * Overrides the corresponding method in HttpURLConnection to permit
394
   * arbitrary methods, as long as they're valid ASCII alphabetic
395
   * characters. This is to permit WebDAV and other HTTP extensions to
396
   * function.
397
   * @param method the method
398
   */
399
  public void setRequestMethod(String method)
400
    throws ProtocolException
401
  {
402
    if (connected)
403
      {
404
        throw new ProtocolException("Already connected");
405
      }
406
    // Validate
407
    method = method.toUpperCase();
408
    int len = method.length();
409
    if (len == 0)
410
      {
411
        throw new ProtocolException("Empty method name");
412
      }
413
    for (int i = 0; i < len; i++)
414
      {
415
        char c = method.charAt(i);
416
        if (c < 0x41 || c > 0x5a)
417
          {
418
            throw new ProtocolException("Illegal character '" + c +
419
                                        "' at index " + i);
420
          }
421
      }
422
    // OK
423
    this.method = method;
424
    requestMethodSetExplicitly = true;
425
  }
426
 
427
  public String getRequestProperty(String key)
428
  {
429
    return requestHeaders.getValue(key);
430
  }
431
 
432
  public Map<String, List<String>> getRequestProperties()
433
  {
434
    if (connected)
435
      throw new IllegalStateException("Already connected");
436
 
437
    Map<String, List<String>> m = requestHeaders.getAsMap();
438
    return Collections.unmodifiableMap(m);
439
  }
440
 
441
  public void setRequestProperty(String key, String value)
442
  {
443
    super.setRequestProperty(key, value);
444
 
445
    requestHeaders.put(key, value);
446
  }
447
 
448
  public void addRequestProperty(String key, String value)
449
  {
450
    super.addRequestProperty(key, value);
451
    requestHeaders.addValue(key, value);
452
  }
453
 
454
  public OutputStream getOutputStream()
455
    throws IOException
456
  {
457
    if (connected)
458
      {
459
        throw new ProtocolException("Already connected");
460
      }
461
    if (!doOutput)
462
      {
463
        throw new ProtocolException("doOutput is false");
464
      }
465
    else if (!requestMethodSetExplicitly)
466
      {
467
        /*
468
         * Silently change the method to POST if no method was set
469
         * explicitly. This is due to broken applications depending on this
470
         * behaviour (Apache XMLRPC for one).
471
         */
472
        method = "POST";
473
      }
474
    if (requestSink == null)
475
      {
476
        requestSink = new ByteArrayOutputStream();
477
      }
478
    return requestSink;
479
  }
480
 
481
  // -- Response --
482
 
483
  public InputStream getInputStream()
484
    throws IOException
485
  {
486
    if (!connected)
487
      {
488
        connect();
489
      }
490
    if (!doInput)
491
      {
492
        throw new ProtocolException("doInput is false");
493
      }
494
 
495
    if (response.isError())
496
      {
497
        int code = response.getCode();
498
        if (code == 404 || code == 410)
499
          throw new FileNotFoundException(url.toString());
500
 
501
        throw new IOException("Server returned HTTP response code " + code
502
                              + " for URL " + url.toString());
503
      }
504
 
505
    return responseSink;
506
  }
507
 
508
  public InputStream getErrorStream()
509
  {
510
    return errorSink;
511
  }
512
 
513
  public Map<String,List<String>> getHeaderFields()
514
  {
515
    if (!connected)
516
      {
517
        try
518
          {
519
            connect();
520
          }
521
        catch (IOException e)
522
          {
523
            return null;
524
          }
525
      }
526
    Map<String,List<String>> m = response.getHeaders().getAsMap();
527
    m.put(null, Collections.singletonList(getStatusLine(response)));
528
    return Collections.unmodifiableMap(m);
529
  }
530
 
531
  String getStatusLine(Response response)
532
  {
533
    return "HTTP/" + response.getMajorVersion() +
534
      "." + response.getMinorVersion() +
535
      " " + response.getCode() +
536
      " " + response.getMessage();
537
  }
538
 
539
  public String getHeaderField(int index)
540
  {
541
    if (!connected)
542
      {
543
        try
544
          {
545
            connect();
546
          }
547
        catch (IOException e)
548
          {
549
            return null;
550
          }
551
      }
552
    if (index == 0)
553
      {
554
        return getStatusLine(response);
555
      }
556
    return response.getHeaders().getHeaderValue(index - 1);
557
  }
558
 
559
  public String getHeaderFieldKey(int index)
560
  {
561
    if (!connected)
562
      {
563
        try
564
          {
565
            connect();
566
          }
567
        catch (IOException e)
568
          {
569
            return null;
570
          }
571
      }
572
    // index of zero is the status line.
573
    return response.getHeaders().getHeaderName(index - 1);
574
  }
575
 
576
  public String getHeaderField(String name)
577
  {
578
    if (!connected)
579
      {
580
        try
581
          {
582
            connect();
583
          }
584
        catch (IOException e)
585
          {
586
            return null;
587
          }
588
      }
589
    return response.getHeader(name);
590
  }
591
 
592
  public long getHeaderFieldDate(String name, long def)
593
  {
594
    if (!connected)
595
      {
596
        try
597
          {
598
            connect();
599
          }
600
        catch (IOException e)
601
          {
602
            return def;
603
          }
604
      }
605
    Date date = response.getDateHeader(name);
606
    return (date == null) ? def : date.getTime();
607
  }
608
 
609
  public String getContentType()
610
  {
611
    return getHeaderField("Content-Type");
612
  }
613
 
614
  public int getResponseCode()
615
    throws IOException
616
  {
617
    if (!connected)
618
      {
619
        connect();
620
      }
621
    return response.getCode();
622
  }
623
 
624
  public String getResponseMessage()
625
    throws IOException
626
  {
627
    if (!connected)
628
      {
629
        connect();
630
      }
631
    return response.getMessage();
632
  }
633
 
634
  // -- HTTPS specific --
635
 
636
  public String getCipherSuite()
637
  {
638
    if (!connected)
639
      {
640
        throw new IllegalStateException("not connected");
641
      }
642
    return handshakeEvent.getCipherSuite();
643
  }
644
 
645
  public Certificate[] getLocalCertificates()
646
  {
647
    if (!connected)
648
      {
649
        throw new IllegalStateException("not connected");
650
      }
651
    return handshakeEvent.getLocalCertificates();
652
  }
653
 
654
  public Certificate[] getServerCertificates()
655
    throws SSLPeerUnverifiedException
656
  {
657
    if (!connected)
658
      {
659
        throw new IllegalStateException("not connected");
660
      }
661
    return handshakeEvent.getPeerCertificates();
662
  }
663
 
664
  // HandshakeCompletedListener
665
 
666
  public void handshakeCompleted(HandshakeCompletedEvent event)
667
  {
668
    handshakeEvent = event;
669
  }
670
 
671
  /**
672
   * Set the read timeout, in milliseconds, or zero if the timeout
673
   * is to be considered infinite.
674
   *
675
   * Overloaded.
676
   *
677
   */
678
  public void setReadTimeout(int timeout)
679
    throws IllegalArgumentException
680
  {
681
    super.setReadTimeout(timeout);
682
    if (connection == null)
683
      return;
684
    try
685
      {
686
        connection.getSocket().setSoTimeout(timeout);
687
      }
688
    catch (IOException se)
689
      {
690
        // Ignore socket exceptions.
691
      }
692
  }
693
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.