b83e6d2fa75cb81c14e514f8879b91accae825cc
[jsvc.git] / src / dolda / jsvc / util / Http.java
1 package dolda.jsvc.util;
2
3 import java.util.*;
4 import java.text.*;
5 import java.io.*;
6
7 public class Http {
8     public final static DateFormat datefmt;
9     public final static String tspecials = "()<>@,;:\\\"/[]?={} ";
10     static {
11         datefmt = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH);
12         datefmt.setCalendar(Calendar.getInstance(TimeZone.getTimeZone("UTC")));
13     }
14     
15     public static class EncodingException extends ClientError {
16         public EncodingException(String msg) {
17             super("Invalid header encoding", msg);
18         }
19     }
20     
21     public static String fmtdate(Date d) {
22         return(datefmt.format(d));
23     }
24     
25     public static Date parsedate(String str) throws ParseException {
26         return(datefmt.parse(str));
27     }
28     
29     public static boolean istoken(String str) {
30         for(int i = 0; i < str.length(); i++) {
31             char c = str.charAt(i);
32             if(c < 32)
33                 return(false);
34             if(c >= 127)
35                 return(false);
36             if(tspecials.indexOf(c) >= 0)
37                 return(false);
38         }
39         return(true);
40     }
41     
42     public static String tokenquote(String str) {
43         if(istoken(str))
44             return(str);
45         StringBuilder buf = new StringBuilder();
46         buf.append("\"");
47         for(int i = 0; i < str.length(); i++) {
48             char c = str.charAt(i);
49             if(((c < 32) && (c != 9)) || (c >= 127))
50                 throw(new RuntimeException("Invalid character in HTTP quoted-string: `" + c + "'"));
51             if((c == '"') || (c == '\\')) {
52                 buf.append('\\');
53                 buf.append(c);
54             } else {
55                 buf.append(c);
56             }
57         }
58         buf.append("\"");
59         return(buf.toString());
60     }
61     
62     public static String tokenunquote(Reader in) throws IOException {
63         StringBuilder buf = new StringBuilder();
64         String st = "eatws";
65         int c = in.read();
66         while(true) {
67             if(st == "eatws") {
68                 if(Character.isWhitespace((char)c))
69                     c = in.read();
70                 else
71                     st = "token";
72             } else if(st == "token") {
73                 if((c < 0) || Character.isWhitespace((char)c) || (tspecials.indexOf((char)c) >= 0)) {
74                     if(buf.length() == 0)
75                         return(null);
76                     return(buf.toString());
77                 } else if((c < 32) || (c >= 127)) {
78                     throw(new EncodingException("Invalid characters in header"));
79                 } else if(c == '"') {
80                     st = "quoted";
81                     c = in.read();
82                 } else {
83                     buf.append((char)c);
84                     c = in.read();
85                 }
86             } else if(st == "quoted") {
87                 if(c < 0) {
88                     throw(new EncodingException("Unterminated quoted-string"));
89                 } else if((c < 32) && !Character.isWhitespace((char)c)) {
90                     throw(new EncodingException("Invalid characters in header"));
91                 } else if(c == '"') {
92                     return(buf.toString());
93                 } else if(c == '\\') {
94                     st = "q1";
95                     c = in.read();
96                 } else {
97                     buf.append((char)c);
98                     c = in.read();
99                 }
100             } else if(st == "q1") {
101                 if(c < 0) {
102                     throw(new EncodingException("Unterminated quoted-string"));
103                 } else if(c > 127) {
104                     throw(new EncodingException("Invalid characters in header"));
105                 } else {
106                     buf.append((char)c);
107                     c = in.read();
108                     st = "quoted";
109                 }
110             }
111         }
112     }
113 }