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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [gnu/] [java/] [net/] [protocol/] [http/] [Request.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* Request.java --
2
   Copyright (C) 2004, 2005 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.java.net.BASE64;
42
import gnu.java.net.LineInputStream;
43
 
44
import java.io.IOException;
45
import java.io.InputStream;
46
import java.io.OutputStream;
47
import java.net.ProtocolException;
48
import java.security.MessageDigest;
49
import java.security.NoSuchAlgorithmException;
50
import java.text.DateFormat;
51
import java.text.ParseException;
52
import java.util.Calendar;
53
import java.util.Date;
54
import java.util.HashMap;
55
import java.util.Iterator;
56
import java.util.Map;
57
import java.util.Properties;
58
import java.util.zip.GZIPInputStream;
59
import java.util.zip.InflaterInputStream;
60
 
61
/**
62
 * A single HTTP request.
63
 *
64
 * @author Chris Burdess (dog@gnu.org)
65
 */
66
public class Request
67
{
68
 
69
  /**
70
   * The connection context in which this request is invoked.
71
   */
72
  protected final HTTPConnection connection;
73
 
74
  /**
75
   * The HTTP method to invoke.
76
   */
77
  protected final String method;
78
 
79
  /**
80
   * The path identifying the resource.
81
   * This string must conform to the abs_path definition given in RFC2396,
82
   * with an optional "?query" part, and must be URI-escaped by the caller.
83
   */
84
  protected final String path;
85
 
86
  /**
87
   * The headers in this request.
88
   */
89
  protected final Headers requestHeaders;
90
 
91
  /**
92
   * The request body provider.
93
   */
94
  protected RequestBodyWriter requestBodyWriter;
95
 
96
  /**
97
   * Request body negotiation threshold for 100-continue expectations.
98
   */
99
  protected int requestBodyNegotiationThreshold;
100
 
101
  /**
102
   * Map of response header handlers.
103
   */
104
  protected Map responseHeaderHandlers;
105
 
106
  /**
107
   * The authenticator.
108
   */
109
  protected Authenticator authenticator;
110
 
111
  /**
112
   * Whether this request has been dispatched yet.
113
   */
114
  private boolean dispatched;
115
 
116
  /**
117
   * Constructor for a new request.
118
   * @param connection the connection context
119
   * @param method the HTTP method
120
   * @param path the resource path including query part
121
   */
122
  protected Request(HTTPConnection connection, String method,
123
                    String path)
124
  {
125
    this.connection = connection;
126
    this.method = method;
127
    this.path = path;
128
    requestHeaders = new Headers();
129
    responseHeaderHandlers = new HashMap();
130
    requestBodyNegotiationThreshold = 4096;
131
  }
132
 
133
  /**
134
   * Returns the connection associated with this request.
135
   * @see #connection
136
   */
137
  public HTTPConnection getConnection()
138
  {
139
    return connection;
140
  }
141
 
142
  /**
143
   * Returns the HTTP method to invoke.
144
   * @see #method
145
   */
146
  public String getMethod()
147
  {
148
    return method;
149
  }
150
 
151
  /**
152
   * Returns the resource path.
153
   * @see #path
154
   */
155
  public String getPath()
156
  {
157
    return path;
158
  }
159
 
160
  /**
161
   * Returns the full request-URI represented by this request, as specified
162
   * by HTTP/1.1.
163
   */
164
  public String getRequestURI()
165
  {
166
    return connection.getURI() + path;
167
  }
168
 
169
  /**
170
   * Returns the headers in this request.
171
   */
172
  public Headers getHeaders()
173
  {
174
    return requestHeaders;
175
  }
176
 
177
  /**
178
   * Returns the value of the specified header in this request.
179
   * @param name the header name
180
   */
181
  public String getHeader(String name)
182
  {
183
    return requestHeaders.getValue(name);
184
  }
185
 
186
  /**
187
   * Returns the value of the specified header in this request as an integer.
188
   * @param name the header name
189
   */
190
  public int getIntHeader(String name)
191
  {
192
    return requestHeaders.getIntValue(name);
193
  }
194
 
195
  /**
196
   * Returns the value of the specified header in this request as a date.
197
   * @param name the header name
198
   */
199
  public Date getDateHeader(String name)
200
  {
201
    return requestHeaders.getDateValue(name);
202
  }
203
 
204
  /**
205
   * Sets the specified header in this request.
206
   * @param name the header name
207
   * @param value the header value
208
   */
209
  public void setHeader(String name, String value)
210
  {
211
    requestHeaders.put(name, value);
212
  }
213
 
214
  /**
215
   * Convenience method to set the entire request body.
216
   * @param requestBody the request body content
217
   */
218
  public void setRequestBody(byte[] requestBody)
219
  {
220
    setRequestBodyWriter(new ByteArrayRequestBodyWriter(requestBody));
221
  }
222
 
223
  /**
224
   * Sets the request body provider.
225
   * @param requestBodyWriter the handler used to obtain the request body
226
   */
227
  public void setRequestBodyWriter(RequestBodyWriter requestBodyWriter)
228
  {
229
    this.requestBodyWriter = requestBodyWriter;
230
  }
231
 
232
  /**
233
   * Sets a callback handler to be invoked for the specified header name.
234
   * @param name the header name
235
   * @param handler the handler to receive the value for the header
236
   */
237
  public void setResponseHeaderHandler(String name,
238
                                       ResponseHeaderHandler handler)
239
  {
240
    responseHeaderHandlers.put(name, handler);
241
  }
242
 
243
  /**
244
   * Sets an authenticator that can be used to handle authentication
245
   * automatically.
246
   * @param authenticator the authenticator
247
   */
248
  public void setAuthenticator(Authenticator authenticator)
249
  {
250
    this.authenticator = authenticator;
251
  }
252
 
253
  /**
254
   * Sets the request body negotiation threshold.
255
   * If this is set, it determines the maximum size that the request body
256
   * may be before body negotiation occurs(via the
257
   * <code>100-continue</code> expectation). This ensures that a large
258
   * request body is not sent when the server wouldn't have accepted it
259
   * anyway.
260
   * @param threshold the body negotiation threshold, or &lt;=0 to disable
261
   * request body negotation entirely
262
   */
263
  public void setRequestBodyNegotiationThreshold(int threshold)
264
  {
265
    requestBodyNegotiationThreshold = threshold;
266
  }
267
 
268
  /**
269
   * Dispatches this request.
270
   * A request can only be dispatched once; calling this method a second
271
   * time results in a protocol exception.
272
   * @exception IOException if an I/O error occurred
273
   * @return an HTTP response object representing the result of the operation
274
   */
275
  public Response dispatch()
276
    throws IOException
277
  {
278
    if (dispatched)
279
      {
280
        throw new ProtocolException("request already dispatched");
281
      }
282
    final String CRLF = "\r\n";
283
    final String HEADER_SEP = ": ";
284
    final String US_ASCII = "US-ASCII";
285
    final String version = connection.getVersion();
286
    Response response;
287
    int contentLength = -1;
288
    boolean retry = false;
289
    int attempts = 0;
290
    boolean expectingContinue = false;
291
    if (requestBodyWriter != null)
292
      {
293
        contentLength = requestBodyWriter.getContentLength();
294
        if (contentLength > requestBodyNegotiationThreshold)
295
          {
296
            expectingContinue = true;
297
            setHeader("Expect", "100-continue");
298
          }
299
        else
300
          {
301
            setHeader("Content-Length", Integer.toString(contentLength));
302
          }
303
      }
304
 
305
    try
306
      {
307
        // Loop while authentication fails or continue
308
        do
309
          {
310
            retry = false;
311
 
312
            // Get socket output and input streams
313
            OutputStream out = connection.getOutputStream();
314
 
315
            // Request line
316
            String requestUri = path;
317
            if (connection.isUsingProxy() &&
318
                !"*".equals(requestUri) &&
319
                !"CONNECT".equals(method))
320
              {
321
                requestUri = getRequestURI();
322
              }
323
            String line = method + ' ' + requestUri + ' ' + version + CRLF;
324
            out.write(line.getBytes(US_ASCII));
325
            // Request headers
326
            for (Iterator i = requestHeaders.keySet().iterator();
327
                 i.hasNext(); )
328
              {
329
                String name =(String) i.next();
330
                String value =(String) requestHeaders.get(name);
331
                line = name + HEADER_SEP + value + CRLF;
332
                out.write(line.getBytes(US_ASCII));
333
              }
334
            out.write(CRLF.getBytes(US_ASCII));
335
            // Request body
336
            if (requestBodyWriter != null && !expectingContinue)
337
              {
338
                byte[] buffer = new byte[4096];
339
                int len;
340
                int count = 0;
341
 
342
                requestBodyWriter.reset();
343
                do
344
                  {
345
                    len = requestBodyWriter.write(buffer);
346
                    if (len > 0)
347
                      {
348
                        out.write(buffer, 0, len);
349
                      }
350
                    count += len;
351
                  }
352
                while (len > -1 && count < contentLength);
353
              }
354
            out.flush();
355
            // Get response
356
            while(true)
357
            {
358
              response = readResponse(connection.getInputStream());
359
              int sc = response.getCode();
360
              if (sc == 401 && authenticator != null)
361
                {
362
                  if (authenticate(response, attempts++))
363
                    {
364
                      retry = true;
365
                    }
366
                }
367
              else if (sc == 100)
368
                {
369
                  if (expectingContinue)
370
                    {
371
                      requestHeaders.remove("Expect");
372
                      setHeader("Content-Length",
373
                                Integer.toString(contentLength));
374
                      expectingContinue = false;
375
                      retry = true;
376
                    }
377
                  else
378
                    {
379
                      // A conforming server can send an unsoliceted
380
                      // Continue response but *should* not (RFC 2616
381
                      // sec 8.2.3).  Ignore the bogus Continue
382
                      // response and get the real response that
383
                      // should follow
384
                      continue;
385
                    }
386
                }
387
              break;
388
            }
389
          }
390
        while (retry);
391
      }
392
    catch (IOException e)
393
      {
394
        connection.close();
395
        throw e;
396
      }
397
    return response;
398
  }
399
 
400
  Response readResponse(InputStream in)
401
    throws IOException
402
  {
403
    String line;
404
    int len;
405
 
406
    // Read response status line
407
    LineInputStream lis = new LineInputStream(in);
408
 
409
    line = lis.readLine();
410
    if (line == null)
411
      {
412
        throw new ProtocolException("Peer closed connection");
413
      }
414
    if (!line.startsWith("HTTP/"))
415
      {
416
        throw new ProtocolException(line);
417
      }
418
    len = line.length();
419
    int start = 5, end = 6;
420
    while (line.charAt(end) != '.')
421
      {
422
        end++;
423
      }
424
    int majorVersion = Integer.parseInt(line.substring(start, end));
425
    start = end + 1;
426
    end = start + 1;
427
    while (line.charAt(end) != ' ')
428
      {
429
        end++;
430
      }
431
    int minorVersion = Integer.parseInt(line.substring(start, end));
432
    start = end + 1;
433
    end = start + 3;
434
    int code = Integer.parseInt(line.substring(start, end));
435
    String message = line.substring(end + 1, len - 1);
436
    // Read response headers
437
    Headers responseHeaders = new Headers();
438
    responseHeaders.parse(lis);
439
    notifyHeaderHandlers(responseHeaders);
440
    InputStream body = null;
441
 
442
    switch (code)
443
      {
444
      case 100:
445
      case 204:
446
      case 205:
447
      case 304:
448
        break;
449
      default:
450
        body = createResponseBodyStream(responseHeaders, majorVersion,
451
                                        minorVersion, in);
452
      }
453
 
454
    // Construct response
455
    Response ret = new Response(majorVersion, minorVersion, code,
456
                                message, responseHeaders, body);
457
    return ret;
458
  }
459
 
460
  void notifyHeaderHandlers(Headers headers)
461
  {
462
    for (Iterator i = headers.entrySet().iterator(); i.hasNext(); )
463
      {
464
        Map.Entry entry = (Map.Entry) i.next();
465
        String name =(String) entry.getKey();
466
        // Handle Set-Cookie
467
        if ("Set-Cookie".equalsIgnoreCase(name))
468
          {
469
            String value = (String) entry.getValue();
470
            handleSetCookie(value);
471
          }
472
        ResponseHeaderHandler handler =
473
          (ResponseHeaderHandler) responseHeaderHandlers.get(name);
474
        if (handler != null)
475
          {
476
            String value = (String) entry.getValue();
477
            handler.setValue(value);
478
          }
479
      }
480
  }
481
 
482
  private InputStream createResponseBodyStream(Headers responseHeaders,
483
                                               int majorVersion,
484
                                               int minorVersion,
485
                                               InputStream in)
486
    throws IOException
487
  {
488
    long contentLength = -1;
489
    Headers trailer = null;
490
 
491
    // Persistent connections are the default in HTTP/1.1
492
    boolean doClose = "close".equalsIgnoreCase(getHeader("Connection")) ||
493
      "close".equalsIgnoreCase(responseHeaders.getValue("Connection")) ||
494
      (connection.majorVersion == 1 && connection.minorVersion == 0) ||
495
      (majorVersion == 1 && minorVersion == 0);
496
 
497
    String transferCoding = responseHeaders.getValue("Transfer-Encoding");
498
    if ("chunked".equalsIgnoreCase(transferCoding))
499
      {
500
        in = new LimitedLengthInputStream(in, -1, false, connection, doClose);
501
 
502
        in = new ChunkedInputStream(in, responseHeaders);
503
      }
504
    else
505
      {
506
        contentLength = responseHeaders.getLongValue("Content-Length");
507
 
508
        if (contentLength < 0)
509
          doClose = true;  // No Content-Length, must close.
510
 
511
        in = new LimitedLengthInputStream(in, contentLength,
512
                                          contentLength >= 0,
513
                                          connection, doClose);
514
      }
515
    String contentCoding = responseHeaders.getValue("Content-Encoding");
516
    if (contentCoding != null && !"identity".equals(contentCoding))
517
      {
518
        if ("gzip".equals(contentCoding))
519
          {
520
            in = new GZIPInputStream(in);
521
          }
522
        else if ("deflate".equals(contentCoding))
523
          {
524
            in = new InflaterInputStream(in);
525
          }
526
        else
527
          {
528
            throw new ProtocolException("Unsupported Content-Encoding: " +
529
                                        contentCoding);
530
          }
531
        // Remove the Content-Encoding header because the content is
532
        // no longer compressed.
533
        responseHeaders.remove("Content-Encoding");
534
      }
535
    return in;
536
  }
537
 
538
  boolean authenticate(Response response, int attempts)
539
    throws IOException
540
  {
541
    String challenge = response.getHeader("WWW-Authenticate");
542
    if (challenge == null)
543
      {
544
        challenge = response.getHeader("Proxy-Authenticate");
545
      }
546
    int si = challenge.indexOf(' ');
547
    String scheme = (si == -1) ? challenge : challenge.substring(0, si);
548
    if ("Basic".equalsIgnoreCase(scheme))
549
      {
550
        Properties params = parseAuthParams(challenge.substring(si + 1));
551
        String realm = params.getProperty("realm");
552
        Credentials creds = authenticator.getCredentials(realm, attempts);
553
        String userPass = creds.getUsername() + ':' + creds.getPassword();
554
        byte[] b_userPass = userPass.getBytes("US-ASCII");
555
        byte[] b_encoded = BASE64.encode(b_userPass);
556
        String authorization =
557
          scheme + " " + new String(b_encoded, "US-ASCII");
558
        setHeader("Authorization", authorization);
559
        return true;
560
      }
561
    else if ("Digest".equalsIgnoreCase(scheme))
562
      {
563
        Properties params = parseAuthParams(challenge.substring(si + 1));
564
        String realm = params.getProperty("realm");
565
        String nonce = params.getProperty("nonce");
566
        String qop = params.getProperty("qop");
567
        String algorithm = params.getProperty("algorithm");
568
        String digestUri = getRequestURI();
569
        Credentials creds = authenticator.getCredentials(realm, attempts);
570
        String username = creds.getUsername();
571
        String password = creds.getPassword();
572
        connection.incrementNonce(nonce);
573
        try
574
          {
575
            MessageDigest md5 = MessageDigest.getInstance("MD5");
576
            final byte[] COLON = { 0x3a };
577
 
578
            // Calculate H(A1)
579
            md5.reset();
580
            md5.update(username.getBytes("US-ASCII"));
581
            md5.update(COLON);
582
            md5.update(realm.getBytes("US-ASCII"));
583
            md5.update(COLON);
584
            md5.update(password.getBytes("US-ASCII"));
585
            byte[] ha1 = md5.digest();
586
            if ("md5-sess".equals(algorithm))
587
              {
588
                byte[] cnonce = generateNonce();
589
                md5.reset();
590
                md5.update(ha1);
591
                md5.update(COLON);
592
                md5.update(nonce.getBytes("US-ASCII"));
593
                md5.update(COLON);
594
                md5.update(cnonce);
595
                ha1 = md5.digest();
596
              }
597
            String ha1Hex = toHexString(ha1);
598
 
599
            // Calculate H(A2)
600
            md5.reset();
601
            md5.update(method.getBytes("US-ASCII"));
602
            md5.update(COLON);
603
            md5.update(digestUri.getBytes("US-ASCII"));
604
            if ("auth-int".equals(qop))
605
              {
606
                byte[] hEntity = null; // TODO hash of entity body
607
                md5.update(COLON);
608
                md5.update(hEntity);
609
              }
610
            byte[] ha2 = md5.digest();
611
            String ha2Hex = toHexString(ha2);
612
 
613
            // Calculate response
614
            md5.reset();
615
            md5.update(ha1Hex.getBytes("US-ASCII"));
616
            md5.update(COLON);
617
            md5.update(nonce.getBytes("US-ASCII"));
618
            if ("auth".equals(qop) || "auth-int".equals(qop))
619
              {
620
                String nc = getNonceCount(nonce);
621
                byte[] cnonce = generateNonce();
622
                md5.update(COLON);
623
                md5.update(nc.getBytes("US-ASCII"));
624
                md5.update(COLON);
625
                md5.update(cnonce);
626
                md5.update(COLON);
627
                md5.update(qop.getBytes("US-ASCII"));
628
              }
629
            md5.update(COLON);
630
            md5.update(ha2Hex.getBytes("US-ASCII"));
631
            String digestResponse = toHexString(md5.digest());
632
 
633
            String authorization = scheme +
634
              " username=\"" + username + "\"" +
635
              " realm=\"" + realm + "\"" +
636
              " nonce=\"" + nonce + "\"" +
637
              " uri=\"" + digestUri + "\"" +
638
              " response=\"" + digestResponse + "\"";
639
            setHeader("Authorization", authorization);
640
            return true;
641
          }
642
        catch (NoSuchAlgorithmException e)
643
          {
644
            return false;
645
          }
646
      }
647
    // Scheme not recognised
648
    return false;
649
  }
650
 
651
  Properties parseAuthParams(String text)
652
  {
653
    int len = text.length();
654
    String key = null;
655
    StringBuilder buf = new StringBuilder();
656
    Properties ret = new Properties();
657
    boolean inQuote = false;
658
    for (int i = 0; i < len; i++)
659
      {
660
        char c = text.charAt(i);
661
        if (c == '"')
662
          {
663
            inQuote = !inQuote;
664
          }
665
        else if (c == '=' && key == null)
666
          {
667
            key = buf.toString().trim();
668
            buf.setLength(0);
669
          }
670
        else if (c == ' ' && !inQuote)
671
          {
672
            String value = unquote(buf.toString().trim());
673
            ret.put(key, value);
674
            key = null;
675
            buf.setLength(0);
676
          }
677
        else if (c != ',' || (i <(len - 1) && text.charAt(i + 1) != ' '))
678
          {
679
            buf.append(c);
680
          }
681
      }
682
    if (key != null)
683
      {
684
        String value = unquote(buf.toString().trim());
685
        ret.put(key, value);
686
      }
687
    return ret;
688
  }
689
 
690
  String unquote(String text)
691
  {
692
    int len = text.length();
693
    if (len > 0 && text.charAt(0) == '"' && text.charAt(len - 1) == '"')
694
      {
695
        return text.substring(1, len - 1);
696
      }
697
    return text;
698
  }
699
 
700
  /**
701
   * Returns the number of times the specified nonce value has been seen.
702
   * This always returns an 8-byte 0-padded hexadecimal string.
703
   */
704
  String getNonceCount(String nonce)
705
  {
706
    int nc = connection.getNonceCount(nonce);
707
    String hex = Integer.toHexString(nc);
708
    StringBuilder buf = new StringBuilder();
709
    for (int i = 8 - hex.length(); i > 0; i--)
710
      {
711
        buf.append('0');
712
      }
713
    buf.append(hex);
714
    return buf.toString();
715
  }
716
 
717
  /**
718
   * Client nonce value.
719
   */
720
  byte[] nonce;
721
 
722
  /**
723
   * Generates a new client nonce value.
724
   */
725
  byte[] generateNonce()
726
    throws IOException, NoSuchAlgorithmException
727
  {
728
    if (nonce == null)
729
      {
730
        long time = System.currentTimeMillis();
731
        MessageDigest md5 = MessageDigest.getInstance("MD5");
732
        md5.update(Long.toString(time).getBytes("US-ASCII"));
733
        nonce = md5.digest();
734
      }
735
    return nonce;
736
  }
737
 
738
  String toHexString(byte[] bytes)
739
  {
740
    char[] ret = new char[bytes.length * 2];
741
    for (int i = 0, j = 0; i < bytes.length; i++)
742
      {
743
        int c =(int) bytes[i];
744
        if (c < 0)
745
          {
746
            c += 0x100;
747
          }
748
        ret[j++] = Character.forDigit(c / 0x10, 0x10);
749
        ret[j++] = Character.forDigit(c % 0x10, 0x10);
750
      }
751
    return new String(ret);
752
  }
753
 
754
  /**
755
   * Parse the specified cookie list and notify the cookie manager.
756
   */
757
  void handleSetCookie(String text)
758
  {
759
    CookieManager cookieManager = connection.getCookieManager();
760
    if (cookieManager == null)
761
      {
762
        return;
763
      }
764
    String name = null;
765
    String value = null;
766
    String comment = null;
767
    String domain = connection.getHostName();
768
    String path = this.path;
769
    int lsi = path.lastIndexOf('/');
770
    if (lsi != -1)
771
      {
772
        path = path.substring(0, lsi);
773
      }
774
    boolean secure = false;
775
    Date expires = null;
776
 
777
    int len = text.length();
778
    String attr = null;
779
    StringBuilder buf = new StringBuilder();
780
    boolean inQuote = false;
781
    for (int i = 0; i <= len; i++)
782
      {
783
        char c =(i == len) ? '\u0000' : text.charAt(i);
784
        if (c == '"')
785
          {
786
            inQuote = !inQuote;
787
          }
788
        else if (!inQuote)
789
          {
790
            if (c == '=' && attr == null)
791
              {
792
                attr = buf.toString().trim();
793
                buf.setLength(0);
794
              }
795
            else if (c == ';' || i == len || c == ',')
796
              {
797
                String val = unquote(buf.toString().trim());
798
                if (name == null)
799
                  {
800
                    name = attr;
801
                    value = val;
802
                  }
803
                else if ("Comment".equalsIgnoreCase(attr))
804
                  {
805
                    comment = val;
806
                  }
807
                else if ("Domain".equalsIgnoreCase(attr))
808
                  {
809
                    domain = val;
810
                  }
811
                else if ("Path".equalsIgnoreCase(attr))
812
                  {
813
                    path = val;
814
                  }
815
                else if ("Secure".equalsIgnoreCase(val))
816
                  {
817
                    secure = true;
818
                  }
819
                else if ("Max-Age".equalsIgnoreCase(attr))
820
                  {
821
                    int delta = Integer.parseInt(val);
822
                    Calendar cal = Calendar.getInstance();
823
                    cal.setTimeInMillis(System.currentTimeMillis());
824
                    cal.add(Calendar.SECOND, delta);
825
                    expires = cal.getTime();
826
                  }
827
                else if ("Expires".equalsIgnoreCase(attr))
828
                  {
829
                    DateFormat dateFormat = new HTTPDateFormat();
830
                    try
831
                      {
832
                        expires = dateFormat.parse(val);
833
                      }
834
                    catch (ParseException e)
835
                      {
836
                        // if this isn't a valid date, it may be that
837
                        // the value was returned unquoted; in that case, we
838
                        // want to continue buffering the value
839
                        buf.append(c);
840
                        continue;
841
                      }
842
                  }
843
                attr = null;
844
                buf.setLength(0);
845
                // case EOL
846
                if (i == len || c == ',')
847
                  {
848
                    Cookie cookie = new Cookie(name, value, comment, domain,
849
                                               path, secure, expires);
850
                    cookieManager.setCookie(cookie);
851
                  }
852
                if (c == ',')
853
                  {
854
                    // Reset cookie fields
855
                    name = null;
856
                    value = null;
857
                    comment = null;
858
                    domain = connection.getHostName();
859
                    path = this.path;
860
                    if (lsi != -1)
861
                      {
862
                        path = path.substring(0, lsi);
863
                      }
864
                    secure = false;
865
                    expires = null;
866
                  }
867
              }
868
            else
869
              {
870
                buf.append(c);
871
              }
872
          }
873
        else
874
          {
875
            buf.append(c);
876
          }
877
      }
878
  }
879
 
880
}
881
 

powered by: WebSVN 2.1.0

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