Bugfixed cookie parsing.
[jsvc.git] / src / dolda / jsvc / util / Http.java
CommitLineData
7779099a
FT
1package dolda.jsvc.util;
2
3import java.util.*;
4import java.text.*;
141e5e3c 5import java.io.*;
7779099a
FT
6
7public class Http {
8 public final static DateFormat datefmt;
141e5e3c 9 public final static String tspecials = "()<>@,;:\\\"/[]?={} ";
7779099a
FT
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
141e5e3c
FT
15 public static class EncodingException extends ClientError {
16 public EncodingException(String msg) {
17 super("Invalid header encoding", msg);
18 }
19 }
20
7779099a
FT
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 }
141e5e3c
FT
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
5e8bab52 62 public static String tokenunquote(PushbackReader in) throws IOException {
141e5e3c
FT
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") {
5e8bab52
FT
73 if(c == '"') {
74 st = "quoted";
75 c = in.read();
76 } else if((c < 0) || Character.isWhitespace((char)c) || (tspecials.indexOf((char)c) >= 0)) {
77 if(c >= 0)
78 in.unread(c);
141e5e3c
FT
79 if(buf.length() == 0)
80 return(null);
81 return(buf.toString());
82 } else if((c < 32) || (c >= 127)) {
83 throw(new EncodingException("Invalid characters in header"));
141e5e3c
FT
84 } else {
85 buf.append((char)c);
86 c = in.read();
87 }
88 } else if(st == "quoted") {
89 if(c < 0) {
90 throw(new EncodingException("Unterminated quoted-string"));
91 } else if((c < 32) && !Character.isWhitespace((char)c)) {
92 throw(new EncodingException("Invalid characters in header"));
93 } else if(c == '"') {
94 return(buf.toString());
95 } else if(c == '\\') {
96 st = "q1";
97 c = in.read();
98 } else {
99 buf.append((char)c);
100 c = in.read();
101 }
102 } else if(st == "q1") {
103 if(c < 0) {
104 throw(new EncodingException("Unterminated quoted-string"));
105 } else if(c > 127) {
106 throw(new EncodingException("Invalid characters in header"));
107 } else {
108 buf.append((char)c);
109 c = in.read();
110 st = "quoted";
111 }
112 }
113 }
114 }
7779099a 115}