Added library functions for setting and parsing cookies.
[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
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 }
7779099a 113}